0

ArrayAdapter我为我做了一个自定义,ListView它会改变被点击的行的资源视图(当你点击它时模拟一种扩展行)。使用 aOnItemClickListener我观察点击并将点击位置设置为适配器。然后我告诉适配器数据发生了变化。然后适配器更新,并在单击的位置使用一个不同的资源视图,使用一个简单的 if 语句。最后一次单击发生的视图返回到其初始“未展开”状态。如果我只是让适配器从头开始膨胀每个视图,这很好用。这是我MyAdapter为此使用的类的代码:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View row;
    LayoutInflater inf = ((Activity) mContext).getLayoutInflater();

    if(clickposition == position){
        row = inf.inflate(R.layout.expandedoverviewrow, parent, false); 
    }
    else{
        row = inf.inflate(R.layout.overviewrow, parent, false);
    }

    TextView txtPayedby = (TextView)row.findViewById(payedbyId);
    TextView txtAmount = (TextView)row.findViewById(amountId);
    TextView txtDate = (TextView)row.findViewById(dateId);
    TextView txtDescript = (TextView)row.findViewById(descriptId);
    TextView txtPersons = (TextView)row.findViewById(personId);

    txtPayedby.setText(payedbyList.get(position));
    txtAmount.setText(amountList.get(position));
    txtDate.setText(dateList.get(position));
    txtDescript.setText(descriptList.get(position));
    txtPersons.setText(personList.get(position));

    return(row);
}

public void clicked(int position){
    clickposition = position;
}

但是,如果我想回收视图,那就大错特错了。随机行获得“扩展”视图,因为它正在回收视图。如果我使用上面的代码,这是预期的。我尝试稍微更改代码以区分convertView是正常视图还是“扩展”视图。我通过将代码的第一部分更改为:

View row = convertView; 
    if{row == null || ......){
        LayoutInflater inf = ((Activity) mContext).getLayoutInflater();
        row = inf.inflate(R.layout.overviewrow, parent, false);
    }
    if(clickedposition == position){
        LayoutInflater inf = ((Activity) mContext).getLayoutInflater();
        row = inf.inflate(R.layout.expandedoverviewrow, parent, false);
    }

在第一个 if 语句中的多个点处,我想检查视图是否是“扩展”视图。我尝试了各种东西,将getId与Resource Id进行比较,将内容描述与字符串进行比较。将 convertView 与使用充气器创建的视图进行比较。所有人都未能检测到视图是正常视图还是“扩展”视图。导致该操作系统正在回收视图,从而使越来越多的“扩展”视图成为行。

有谁知道一种可以检测不同视图的方法?还是在这种情况下不回收视图更好?

4

1 回答 1

1

...或者在这种情况下最好不要回收视图?

始终以使用ListView' 的回收机制为目标,下面是我的做法(您实现该getView方法的逻辑有点奇怪)。首先我会使用适配器的getItemViewTypeandgetViewTypeCount方法。它们看起来像这样:

@Override
public int getItemViewType(int position) {
    if (clickposition != -1 && position == clickposition) {
        return SPECIAL_VIEW;
    }
    return NORMAL_VIEW;
}

@Override
public int getViewTypeCount() {
    return 2; // we have two types of views
}

其中NORMAL_VIEWSPECIAL_VIEW是两种类型的行(普通行和扩展行):

// fields in your adapter class
public static final int NORMAL_VIEW = 0;
public static final int SPECIAL_VIEW = 1;

使用上面的所有代码,该getView方法将如下所示:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    int whichOne = getItemViewType(position);
    if (convertView == null) {
        switch (whichOne) {
        case NORMAL_VIEW:
            convertView = mInflater.inflate(R.layout.overviewrow, parent, false);
            break;
        case SPECIAL_VIEW:
            convertView = mInflater.inflate(R.layout.expandedoverviewrow, parent, false);
            break;
            }
    } else {
        // there is no else, the getItemViewType will make sure that you have a valid view                    
    }
    // then you would set the data based on the value of whichOne 
    //...

当您单击一个项目时,更新clickposition并调用notifyDataSetChanged适配器,以便它可以调整行。

于 2012-06-13T12:28:01.377 回答