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;
}
}
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
}
}
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.
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();
}
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