在适配器中删除getview()的视图保持

时间:2014-09-14 16:24:45

标签: android gridview android-arrayadapter

//////////////////////  
MyAdapter mMyAdapter;  
GridView mGridView;  
mGridView.setAdapter(mMyAdapter);  
mMyAdapter.setData(anyDataList);  
isListView = true;  

/////////// When click on button [named: SwitchView] ///////////  
if (isListView) {  
    isListView = false;  
    mGridView.setNumColumns(1);    
    mMyAdapter.setIsListView(true);  
    mMyAdapter.notifyDataSetChanged();  
} else {  
    isListView = true;  
    mGridView.setNumColumns(1);  
    mMyAdapter.setIsListView(false); 
    mMyAdapter.notifyDataSetChanged();   
}  

/////////// Adapter Class Defination ///////////  
class MyAdapter extends ArrayAdapter<MyClass> {  
    List<MyClass> mData;  
    boolean mIsListView;  

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View rowView = convertView;
    // reuse views
    if (rowView == null) {
        LayoutInflater inflater = context.getLayoutInflater();
        if (mIsListView) {
            rowView = inflater.inflate(R.layout.list_view, parent, false);
        } else {
        rowView = inflater.inflate(R.layout.grid_view, parent, false);
        }
        // configure view holder
        ViewHolder viewHolder = new ViewHolder();
        viewHolder.text = (TextView) rowView.findViewById(R.id.TextView01);
        rowView.setTag(viewHolder);
    }
        // fill data
    ViewHolder holder = (ViewHolder) rowView.getTag();
    holder.text.setText(mData.getName());
        return rowView;
    }

    public void setData(List<MyClass> data) {
        mData = data;
    }

    public void setIsListView(boolean isListView) {
        mIsListView = isListView;
    }
}

///////////我的要求是什么///////////
当我点击按钮SwitchView时,适配器应该膨胀list_view或grid_view布局。

///////////问题///////////
就我而言,适配器中的数据是相同的,但它的视图正在发生变化。但是当我点击按钮SwitchView时,我得到了一些不可理解的结果。 GridView显示两种类型的布局(list_view和grid_view)。在某些列表位置,它显示布局“list_view”,在其他位置,它显示布局“grid_view”。

///////////原因///////////
此问题即将发生,因为getView()保存旧视图。

///////////解决方案///////////
代替使用mMyAdapter.notifyDataSetChanged(),应该实例化新的mMyAdapter。但我想知道是否有其他解决方案。我不想实例化新的适配器。

2 个答案:

答案 0 :(得分:1)

无需创建新适配器。只需要利用适配器的视图类型。在MyAdapter类中,覆盖视图类型计数。例如:

@Override
public int getViewTypeCount() {
    return 2;
}

接下来覆盖getItemViewType方法以返回它是网格还是列表。例如:

@Override
public int getItemViewType(int position) {
    return mIsListView ? 1 : 0;
}

最后,在getView方法中,检查位置项类型,以确定要扩张的布局。然后,您可以继续填充视图。例如:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    View rowView = convertView;
    ViewHolder viewHolder;
    // reuse views
    if (rowView == null) {
        LayoutInflater inflater = context.getLayoutInflater();
        if (getItemViewType(position) == 1) {
            rowView = inflater.inflate(R.layout.list_view, parent, false);
        } else {
            rowView = inflater.inflate(R.layout.grid_view, parent, false);
        }

        // configure view holder
        viewHolder = new ViewHolder();
        viewHolder.text = (TextView) rowView.findViewById(R.id.TextView01);
        rowView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) rowView.getTag();
    } 

    holder.text.setText(mData.getName());
    return rowView;
}

注意,此示例演示了仅使用视图类型来确定要膨胀的视图。如果您的数据必须以不同方式填充每种视图类型,那么您还需要使用视图类型来确定它。

答案 1 :(得分:0)

您可以避免使用视图持有者,但它会影响列表的性能。我相信切换布局不仅仅是数据集改变它对于inflater的整个布局更改任务所以要么实例化新的适配器,要么避免使用视图持有者,似乎没有别的办法。