3

画像、TextViewのペア、チェックボックスを備えたListViewsのカスタムrow_itemがあります。私が理解したところによると、checkBoxはフォーカス可能な要素であるため、listViewからフォーカスを奪うため、すべてのrow_itemをクリック不可として設定し、子孫のフォーカス可能性をブロックしない限り、OnListItemClickedは起動されません。

次に、チェックボックスの変更を管理するために、アダプターのgetViewメソッドでチェックボックスの「OnCheckedChangeListener」を設定しました。

これはこれを行うための悪い方法ですか?(getViewが呼び出されるたびに新しいリスナーを作成しているため)同じことを行う他の方法はありますか?

私が何を意味するのか理解しやすいように、いくつかのコードを添付します。

getViewメソッド:(arrayAdapter内)

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

    /** recycling views */
    View row = convertView;
    PregoHolder holder = null;

    if(row == null)
    {
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new PregoHolder();
        holder.imgIcon = (ImageView)row.findViewById(R.id.thumbnail);
        holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
        holder.txtNews = (TextView)row.findViewById(R.id.txtNews);
        holder.chBox = (CheckBox) row.findViewById(R.id.checkBox);

        row.setTag(holder);
    }
    else
    {
        holder = (PregoHolder)row.getTag();
    }

    Prego Prego = data[position];
    holder.txtTitle.setText(Prego.title);
    holder.imgIcon.setImageResource(Prego.icon);
    holder.txtNews.setText(Prego.news);
    holder.chBox.setChecked(Prego.checked);

    /** wiring up Listeners... 
     * (works fine but we are creating new listener each time)
     * (Done like this because of the custom list view focusable issue)
     */

    holder.chBox.setOnCheckedChangeListener(new OnCheckedChangeListener(){

        @Override
        public void onCheckedChanged(CompoundButton arg0, boolean checked) {
            /** Getting the view position in the ListView */
            ListView parent = (ListView)(arg0.getParent()).getParent();
            int pos = parent.getPositionForView(arg0);

            if (checked){
                checkedPregons[pos] = true;
                pregonsChecked++;
            }
            else if (!checked){
                checkedPregons[pos] = false;
                pregonsChecked--;
            }

            Toast.makeText(context, pregonsChecked+" is/are checked", Toast.LENGTH_SHORT).show();
        }
    });

    row.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {
            //mMode = ((Activity)context).startActionMode(new PregonsActionModes());
            ListView parent = (ListView)v.getParent();
            int pos = parent.getPositionForView(v);
            Toast.makeText(context, "getView should show prego "+pos,Toast.LENGTH_SHORT).show();

        }
    });

    return row;
}

前もって感謝します。

4

1 に答える 1

3

もっと良い方法があると思いますが、これは私が眠りにつくようなものではありません。あなたのメソッドは、新旧の多くのAndroid開発者によって乱暴に実装されており、それを実行するための単純な自然な方法です。ListViewさらに、一度に画面に表示できる行数だけがあることを覚えておいてください(そしてgetViewスクロールすると常に呼び出しています)ので、いつでも8〜12個の作成されたオブジェクトについて話していることになります(明らかに完全に推測)、あなたのボトルネックはここにはありません。実際、変更する必要のあるオブジェクトがどこにあるかによっては、私はそれについて考えさえしません。

しかし、で使用OnCheckedChangeListenerすることListViewは私が強く警告したいものです。私が言ったようにgetView、それがスクロールされて作られているので、すべての行に対して呼び出されます。このチェックされた変更されたリスナーは、作成されたとおりに起動され、行ごとに1回getViewだけ呼び出されるという保証はまったくありませんが、実際にはそうではないことを保証します。したがって、これらのコードブロックは、ボックスティックが手動で処理された場合にのみ意図されていたとしても、おそらくwazooを起動している可能性があります。のような比較的集中的なコマンドを入力すると、この現象からロックアップが表示されます。CheckBoxnotifyDataSetChanged()ListView

解決策は、onClickListener代わりにチェックボックスを使用してisChecked()内部をチェックすることです。

于 2012-12-29T17:32:44.790 に答える