0

クリックした行のリソースビューを変更するカスタムArrayAdapterを作成ListViewしました(クリックしたときに一種の拡張行をシミュレートするため)。でOnItemClickListenerクリックを見てクリック位置をアダプターにセットします。次に、データが変更されたことをアダプターに伝えます。その後、アダプターが更新され、クリックの位置で、単純な 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 を、インフレータで作成されるビューと比較します。ビューが通常のビューか「拡張」ビューかをすべて検出できませんでした。その結果、OSはビューをリサイクルしているため、ますます「拡張された」ビューを行として作成しています。

さまざまなビューを検出するために機能する方法を知っている人はいますか? それとも、この場合、ビューをリサイクルしないほうがよいでしょうか?

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_VIEW、 とSPECIAL_VIEWは 2 種類の行 (通常の行と拡張された行) です。

// 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 に答える