2

この Expandable List チェックボックスのサンプル コードをベースラインとして使用して、チェックボックスの状態を保存して維持しようとしています。ただし、ランダムなチェックボックスがチェックされたり、チェックがOnCheckedChangeListener外されたりします(新しい値で私のトリガーになります)。

public Object getChild(int groupPosition, int childPosition) {
    return colors.get( groupPosition ).get( childPosition );
}

public long getChildId(int groupPosition, int childPosition) {
    return (long)( groupPosition*1024+childPosition );  // Max 1024 children per group
}

public View getChildView(final int groupPosition, final int childPosition, 
        boolean isLastChild, View convertView, ViewGroup parent) {

    View v = null;
    if( convertView != null ) {
        v = convertView;
    } else {
        v = inflater.inflate(R.layout.child_row, parent, false); 
    }

    Color c = (Color)getChild( groupPosition, childPosition );

    TextView color = (TextView)v.findViewById( R.id.childname );
    if( color != null ) {
        color.setText( c.getColor() );
    }

    TextView rgb = (TextView)v.findViewById( R.id.rgb );
    if( rgb != null ) {
        rgb.setText( c.getRgb() );
    }

    CheckBox cb = (CheckBox)v.findViewById( R.id.check1 );
    cb.setChecked( c.getState() );
    cb.setOnCheckedChangeListener(new OnCheckedChangeListener()
    {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
        {
            colors.get(groupPosition).get(childPosition).setState(isChecked);
            context.setColorBool(groupPosition, childPosition, isChecked);
            Log.d("ElistCBox2", "listitem position: " +groupPosition+"/"+childPosition+" "+isChecked);
        }
    });

    return v;
}

どのコードが原因であるかはわかりません。そのため、ここに何を含めるかについての提案は大歓迎です。私のコードは、値を保存しようとしている点だけが元のコードと異なります。

4

2 に答える 2

0

私の推測では、アダプターがビューを作成しているときに、チェックボックスビューが初期化されるときにチェックリスナーが呼び出されていると思います。Android の多くのウィジェットはこのように機能します...ビューが初期化されると、リスナーが呼び出されます。

なぜこのように動作するのかはわかりませんが、クライアント コードが一貫した方法で初期化できるようにするためかもしれません。たとえば、チェックボックスがユーザーによってチェックされているかどうか、またはチェックされているように初期化されているかどうかに関係なく、同じコードを実行します。

これに対抗するには、リスナー クラスの impl にフラグを設定して、最初のクリックを無視できるようにするなどの方法を試すことができます。

cb.setOnCheckedChangeListener(new OnCheckedChangeListener()
    {
        private void first = true;

        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
        {
            if (first) {
              first = false;
              return;
            }

            colors.get(groupPosition).get(childPosition).setState(isChecked);
            context.setColorBool(groupPosition, childPosition, isChecked);
            Log.d("ElistCBox2", "listitem position: " +groupPosition+"/"+childPosition+" "+isChecked);
        }
    });

convertViewまた、アダプターの実装で正しく再利用していることを確認してgetView()ください。例えば、

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if (view == null) {
        view = inflater.inflate(R.layout.applications_item, null);
    }
于 2012-06-27T19:41:21.833 に答える
0

これは非常に古い質問ですが、私は同じ問題に苦しんでいたので、探している人のための私の答えは次のとおりです。

最も簡単な方法は、onCheckedChangeListener の代わりに CheckBox.onClickListener を使用することです。

これは、ロジックを再配置するという点では少し面倒ですが、(たとえば、隣接するグループを展開することによって) ボックスがランダムにチェックされていない場合、イベントは発生しません。

正直なところ、これはバグと見なされるべきだと思いますが、動作は Android ソースから説明できると確信しています。

于 2013-08-14T12:22:19.287 に答える