android - getitemid - viewholderとは




アダプタからListView項目を設定する (2)

私は2種類のアイテムを表示するListViewを持っています。 これらの種類の1つにCheckedTextViewが含まれています。 私はカスタムアダプタを使用してアダプタとしてArrayAdapter内のチェック/非チェック状態に関する情報を含むデータ構造体を使用しています。

アイテムの中には、(私のデータ構造内で)選択されたものとしてマークされているものがありますので、ListViewを作成したときにチェックボックスをマークしたいと思います。 CheckedTextViewのsetChecked()メソッドでアダプタのgetView()メソッドを実行しようとしましたが、動作しません。 私は、それが動作するように私は、アクティビティのonCreate()setItemChecked()を呼び出すすべての項目をループする必要がありますので、setItemChecked()でListViewレベルで行う必要があり、選択した人は アイテムのリストは非常に長くて、そのうち少数しか選択されていないので、無駄です。

getView()でsetChecked()を呼び出すのがなぜ機能しないのですか? これを行う良い方法がありますか(私はAndroid初心者です)。

下に私のチェック項目のレイアウトとアダプタがあります。

レイアウト:

<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:textAppearance="@style/listViewItemText"
    android:checkMark="?android:attr/listChoiceIndicatorMultiple"
    android:paddingLeft="6dp"
    android:paddingRight="6dp"
/>

アダプタ:

package com.melog.re.droid.search;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.TextView;

import com.melog.re.droid.core.R;
import com.melog.re.droid.search.MultiCriterionValue.MultiCriterionSingleValue;
import com.melog.re.droid.search.MultiListAdapter.MultiChoiceItem;

public class MultiListAdapter extends ArrayAdapter<MultiChoiceItem> {
    private static final int VIEW_TYPES_COUNT = 2;

    public static final int VIEW_TYPE_GROUP = 0;
    public static final int VIEW_TYPE_ITEM = 1;

    private LayoutInflater mInflater;

    public MultiListAdapter(Context context, int textViewResourceId, List<MultiChoiceItem> objects) {
        super(context, textViewResourceId, objects);
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getItemViewType(int position) {
        MultiChoiceItem item = getItem(position);
        return (item.children.size() == 0) ? VIEW_TYPE_ITEM : VIEW_TYPE_GROUP;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO: optymalizacja ViewHolder
        MultiChoiceItem item = getItem(position);
        int viewType = getItemViewType(position);
        switch (viewType) {
        case VIEW_TYPE_GROUP:
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.multi_choice_group_item, parent, false);
            }
            TextView groupLabel = (TextView) convertView.findViewById(android.R.id.text1);
            groupLabel.setText(item.toString());
            break;
        case VIEW_TYPE_ITEM:
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.multi_choice_child_item, parent, false);
            }
            CheckedTextView itemLabel = (CheckedTextView) convertView.findViewById(android.R.id.text1);
            itemLabel.setText(item.toString());
            itemLabel.setChecked(item.selected);
            break;
        }

        return convertView;
    }

    public static class MultiChoiceItem implements Parcelable {
        public static final int CONTENTS_DESCR = 1;

        public String label;
        public String value;
        public boolean selected = false;
        public ArrayList<MultiChoiceItem> children = new ArrayList<MultiChoiceItem>();

        public MultiChoiceItem(String l, String v, boolean sel) {
            label = l;
            value = v;
            selected = sel;
        }
        public MultiChoiceItem(MultiCriterionSingleValue v) {
            label = v.toString();
            value = v.value;
        }
        public MultiChoiceItem(Parcel in) {
            label = in.readString();
            value = in.readString();
            selected = (in.readInt() == 1);
        }
        @Override
        public String toString() {
            return label;
        }
        @Override
        public int describeContents() {
            return CONTENTS_DESCR;
        }
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(label);
            dest.writeString(value);
            dest.writeInt(selected ? 1 : 0);
        }

        public static final Parcelable.Creator<MultiChoiceItem> CREATOR = new Parcelable.Creator<MultiChoiceItem>() {
            public MultiChoiceItem createFromParcel(Parcel in) {
                return new MultiChoiceItem(in);
            }

            public MultiChoiceItem[] newArray(int size) {
                return new MultiChoiceItem[size];
            }
        };
}
}

そして、アクティビティのonCreate()

...     
mAdapter = new MultiListAdapter(this, R.id.head, mItems);
setListAdapter(mAdapter);

final ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setItemsCanFocus(false);
...

編集:

より良いソリューションを見つけるまで、私はアクティビティのチェックを実装しました:

...
int len = mListView.getCount();
for (int i = 0; i < len; i++) {
    if (((MultiChoiceItem) mListView.getItemAtPosition(i)).selected) {
        mListView.setItemChecked(i, true);
    }
}
...

私はパフォーマンスが唯一の潜在的な問題だと思ったが、私は別のものを見つけた。 リストには、テキストフィルタが有効になっています(mListView.setTextFilterEnabled(true))。 失敗シナリオは次のとおりです。

  1. 私は新しいリストを開きます
  2. 私は2番目のアイテム
  3. 私はいくつかの項目をフィルタリングするために入力を開始する
  4. フィルタリングが行われると、2番目の項目はチェックされていなくてもまだチェックされています

私はsetItemChecked()は、リスト上の固定位置をチェックしている間は、その位置に保持されているItemをマークする必要があると仮定します。リスト上の位置が変化しても状態を保持します。

パフォーマンスの問題は(ある点まで)無視することができますが、この新しい問題は本当に私をブロックしているので、私は本当にそれに助けていただければ幸いです。


ListView.CHOICE_MODE_MULTIPLEまたはCHOICE_MODE_SINGLEを使用すると、 CHOICE_MODE_SINGLEが呼び出された後でアイテムのチェック状態がListViewによってオーバーライドされます。 次の構文を使用する必要があります。

@Override
public View getView(int position, View convertView, ViewGroup parent) {
   ((ListView)parent).setItemChecked(position, true);
}

もう一つの可能​​性は、 ListView.CHOICE_MODE_NONEを使用し、自分でチェック状態を管理することです。


手順を確認する項目xmlの最初の部分に変更を加えてチェックボックスに1行追加する

`android:onClick="chatWithFriend"` 

だからcheackboxをクリックしたら、アクティビティ名に1つのメソッドを作成します

  public void chatWithFriend(View view){}
here you will get the view of check box,

戻り値の変換ビューの前にgetViewに行を追加します。

holder.checkbox.setTag(position);

今すぐチェックボックスの位置を取得します

これがあなたに役立つことを願っています。





checkedtextview