在BaseAdapter.getView()中保留已创建视图的位置似乎是一个问题。
在我的情况下,我创建了一个数据对象(-array),其中包含listview的所有数据。列表项有三种类型:分隔符,带复选框的项和带有可单击图像的项以打开对话框。该数据将由定制的数组适配器执行,始终具有单独的布局。为此,我使用了不同的视图。创造不是问题,但如果回收者启动它的工作,所有的意图/位置都会改变。但就此而言,我的数据基于。
我知道回收商是如何运作的,但程序员应该如何(在地狱中)保持与自己数据的关系呢?
在stackoverflow.com中,有些人问了同样的问题,答案是“覆盖getItemViewType-Methode”。没问题,但如果位置总是变化,那不是真的有帮助,对吗?
让某人有解决方案吗?
此致 皮埃尔
以下是我的概念代码:
// *** Activity: onCreate()
...
ArrayList<DataObj> data = getData();
final ListView list = (ListView)findViewById( R.id.listView1 );
list.setAdapter( new PackedListAdapter( this, data ) );
...
// *** Activity: getData()
private ArrayList<DataObj> getData() {
ArrayList<DataObj> dataArr = new ArrayList<DataObj>();
DataObj dataset;
int i;
dataset = new DataObj();
dataset.setType( DataObj.TYPE_CATEGORY );
dataset.setItemText( "Category CheckItems" );
dataArr.add( dataset );
for ( i = 0; i < 5; i++ ) {
dataset = new DataObj();
dataset.setType( DataObj.TYPE_ITEM_CHECK );
dataset.setItemText( "ItemCheck #" + i );
dataArr.add( dataset );
}
dataset = new DataObj();
dataset.setType( DataObj.TYPE_CATEGORY );
dataset.setItemText( "Category DialogItems" );
dataArr.add( dataset );
for ( i = 0; i < 5; i++ ) {
dataset = new DataObj();
dataset.setType( DataObj.TYPE_ITEM_DLG );
dataset.setItemText( "ItemDlg #" + i );
dataArr.add( dataset );
}
return dataArr;
}
// *** Data-Object:
public class DataObj {
private int type = 1;
// further variables here (e.g. String text1 ) ...
public final static int TYPE_CATEGORY = 1;
public final static int TYPE_ITEM_CHECK = 2;
public final static int TYPE_ITEM_DLG = 3;
public void setType( int type ) { this.type = type; }
public int getType() { return type; }
// further setter/getter-methodes for variables here ...
}
// *** BaseAdapter:
public class PackedListAdapter extends BaseAdapter {
private static ArrayList<DataObj> mData;
private LayoutInflater mInflater;
PackedListAdapter( Context context, ArrayList<DataObj> data ) {
mData = data;
mInflater = LayoutInflater.from( context );
}
public int getCount() {
return mData.size();
}
public Object getItem( int position ) {
return mData.get( position );
}
public long getItemId( int position ) { return position; }
public int getItemViewType( int position ) {
return mData.get( position ).getType();
}
public boolean hasStableIds() { return false; }
public int getViewTypeCount() { return 3; }
public View getView( int position, View convertView, ViewGroup parent ) {
int type = this.getItemViewType( position );
if ( convertView == null ) {
switch ( type ) {
case DataObj.TYPE_CATEGORY:
{
convertView = mInflater.inflate( R.layout.listcat, null );
ViewHolderCat holder = new ViewHolderCat();
// setting up data from mData(position) here
convertView.setTag( holder );
break;
}
case DataObj.TYPE_ITEM_CHECK:
{
convertView = mInflater.inflate( R.layout.listrow, null );
ViewHolderItem holder = new ViewHolderItem();
// setting up data from mData(position) here
convertView.setTag( holder );
break;
}
case DataObj.TYPE_ITEM_DLG:
{
convertView = mInflater.inflate( R.layout.listdlg, null );
ViewHolderDlg holder = new ViewHolderDlg();
// setting up data from mData(position) here
convertView.setTag( holder );
break;
}
}
} else {
switch ( type ) {
case DataObj.TYPE_CATEGORY:
{
ViewHolderCat holder = (ViewHolderCat)convertView.getTag();
// setting up data from mData(position) here
break;
}
case DataObj.TYPE_ITEM_CHECK:
{
ViewHolderItem holder = (ViewHolderItem)convertView.getTag();
// setting up data from mData(position) here
break;
}
case DataObj.TYPE_ITEM_DLG:
{
ViewHolderDlg holder = (ViewHolderDlg)convertView.getTag();
// setting up data from mData(position) here
break;
}
}
}
return convertView;
}
public static class ViewHolderCat {
public TextView txtCat;
}
public static class ViewHolderItem {
public TextView txtItem;
public TextView txtDescr;
public ImageView imgCheckButton;
}
public static class ViewHolderDlg {
public TextView txtItem;
public TextView txtDescr;
public ImageView imgDlgButton;
}
}
答案 0 :(得分:2)
除hasStableIds和getItemViewType外,您还应覆盖getViewTypeCount。这看起来像是:
@Override
public boolean hasStableIds() {
/* the view types for rows will change over time */
return false;
}
@Override
public int getViewTypeCount() {
return 3;
}
@Override
public int getItemViewType(int position) {
/* calculate the view type for this row */
return ... ;
}
我相信这让框架知道它不应该根据项目ID进行缓存。
答案 1 :(得分:1)
该解决方案似乎是一个包含更多适配器的BaseAdapter ......
http://jsharkey.org/blog/2008/08/18/separating-lists-with-headers-in-android-09/
答案 2 :(得分:0)
我试图创建一个与我的数据集最近相关的我的视图的本地缓存,但在看完之后我决定放弃:
http://www.youtube.com/watch?v=wDBM6wVEO70&feature=player_detailpage#t=816s
如果ListView开发人员建议不要这样做,我觉得我应该听取他们的建议而不是试图破解它。