Android list items are changing when scrolling

北慕城南 提交于 2019-12-22 01:23:04

问题


I have a list that should have each item the same layout except for the first and last item which should have separate layouts. The first item shows its unique layout correctly, but the last one changes when I scroll it in and out of view between the correct one and the layout of the first item. Here is my adapter:

public class ListAdapterApp extends ArrayAdapter<App> {

    Context context;
    int layoutResourceId;
    List<App> appList;

    public ListAdapterApp(Context context, int layoutResourceId, List<App> appList) {
        super(context, layoutResourceId, appList);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.appList = appList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        AppHolder holder = null;

        if(row == null)
        {


            holder = new AppHolder();
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            if(position == 0){
                holder.rowLayoutID = R.layout.list_column_appheaderitem;
            } else if(position == appList.size() - 1){
                holder.rowLayoutID = R.layout.list_column_appfooteritem;
            } else {
                holder.rowLayoutID = layoutResourceId;
            }
            row = inflater.inflate(holder.rowLayoutID, parent, false);//holder.packBackground = (LinearLayout)row.findViewById(R.id.packBackground);

            row.setTag(holder);
        }
        else
        {
            holder = (AppHolder)row.getTag();
        }

        App app = appList.get(position);

        return row;
    }

    static class AppHolder
    {
        public int rowLayoutID;
    }
}

回答1:


The problem is ListView is recycling a non-footer row view when it calls getView() for the last item. You need to implement getItemViewType() and getViewTypeCount() in your adapter, to give ListView a hint about what views can be recycled for those items.

private static final int VIEW_TYPE_HEADER = 0;
private static final int VIEW_TYPE_FOOTER = 1;
private static final int VIEW_TYPE_DEFAULT = 2;
private static final int VIEW_TYPE_COUNT = 3;

@Override
public int getViewTypeCount() {
    // The total number of row types your adapter supports.
    // This should NEVER change at runtime.
    return VIEW_TYPE_COUNT;
}

@Override
public int getItemViewType(int position) {
    // return a value from zero to (viewTypeCount - 1)
    if (position == 0) {
        return VIEW_TYPE_HEADER;
    } else if (position == getCount() - 1) {
        return VIEW_TYPE_FOOTER;
    }
    return VIEW_TYPE_DEFAULT;
}

Inside of getView() you can call getItemViewType() and use a switch statement to build your rows:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    switch(getItemViewType(position)) {
    case VIEW_TYPE_HEADER:
        return getHeaderView(position, convertView, parent); // TODO implement this
    case VIEW_TYPE_FOOTER:
        return getFooterView(position, convertView, parent); // TODO implement this
    case VIEW_TYPE_DEFAULT:
        return getDefaultView(position, convertView, parent); // TODO implement this
    }
}



回答2:


I am facing the same problem and then i resolve this issue like don't check if (row==null) and then implement else remove the if else block and just put the whole code in your Getview() Method and then run it your problem is solved.




回答3:


you should put your if-else position checks out side the body of if(row == null) like:

        if(row == null)
        {
            holder = new AppHolder();
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();

            row = inflater.inflate(holder.rowLayoutID, parent, false);

            row.setTag(holder);
        }
        else
        {
            holder = (AppHolder)row.getTag();
        }

          if(position == 0){
                holder.rowLayoutID = R.layout.list_column_appheaderitem;
            } else if(position == appList.size() - 1){
                holder.rowLayoutID = R.layout.list_column_appfooteritem;
            } else {
                holder.rowLayoutID = layoutResourceId;
            }

Also make instance of AppHolder in your constructor like:

Context context;
    int layoutResourceId;
    List<App> appList;

AppHolder holder;

    public ListAdapterApp(Context context, int layoutResourceId, List<App> appList) {
        super(context, layoutResourceId, appList);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.appList = appList;

        holder = new AppHolder();
    }



回答4:


I had the similar problem and I solved it like this . I was facing the problem with RadioGroup and Radio BUttons, but the rest of the problem was similar to your's.



来源:https://stackoverflow.com/questions/26622536/android-list-items-are-changing-when-scrolling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!