121

それらの状態の違いを知りたいのですが。これを明確にするウェブページは見つかりませんでした。

4

3 に答える 3

186

Checked と Activated の違いは、実際には非常に興味深いものです。Googleのドキュメントでさえ申し訳ありません(以下に強調を追加):

... たとえば、単一または複数の選択が有効になっているリスト ビューでは、現在の選択セットのビューがアクティブになります。(ええと、ここでの用語について深くお詫び申し上げます。)アクティブ化された状態は、それが設定されているビューの子に伝播されます。

だからここに違いがあります:

  1. Activated は Honeycomb で導入されたため、それ以前は使用できません
  2. Activated はすべての View のプロパティになりました。メソッド setActivated() および isActivated() があります
  3. アクティブ化は、それが設定されているビューの子に伝播します
  4. Checked は、Checkable インターフェイスを実装する View を中心に展開します。メソッド setChecked()、isChecked()、toggle()
  5. ListView (Honeycomb の後) は、以下のように Android のバージョンに応じて setChecked() または setActivated() を呼び出します (Android ソース コードから取得)。

    if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {
        if (child instanceof Checkable) {
            ((Checkable) child).setChecked(mCheckStates.get(position));
        } else if (getContext().getApplicationInfo().targetSdkVersion
                >= android.os.Build.VERSION_CODES.HONEYCOMB) {
            child.setActivated(mCheckStates.get(position));
        }
    }
    

    mCheckStates 変数に注意してください。リスト内のどの位置がチェック/アクティブ化されているかを追跡します。これらは、getCheckedItemPositions() などを介してアクセスできます。ListView.setItemChecked() を呼び出すと、上記が呼び出されることにも注意してください。つまり、setItemActivated() と同じように呼び出すことができます。

  6. Honeycomb の前に、リスト項目に state_checked を反映するための回避策を実装する必要がありました。これは、ListView がレイアウトの最上位のビューでのみ setChecked() を呼び出すためです (レイアウトはチェック可能を実装していません) ... 助けなしでは伝播しません。これらの回避策の形式は次のとおりです。 ルート レイアウトを拡張して Checkable を実装します。そのコンストラクターで、Checkable を実装するすべての子を再帰的に見つけます。setChecked() などが呼び出されると、それらのビューに呼び出しを渡します。それらのビューが state_checked の別のドローアブルを持つ状態リスト ドローアブル (CheckBox など) を実装する場合、チェックされた状態が UI に反映されます。

  7. Honeycomb の後にリスト アイテムの背景をきれいにするには、次のように state_activated 状態のドローアブルを含むステート リスト ドローアブルを用意するだけです (もちろん、setItemChecked() を使用します)。

    <item android:state_pressed="true"
        android:drawable="@drawable/list_item_bg_pressed"/>
    <item android:state_activated="true"
        android:drawable="@drawable/list_item_bg_activated"/>
    <item android:drawable="@drawable/list_item_bg_normal"/>
    

  8. HoneyComb の前にリスト アイテムのバックグラウンドをうまく処理するには、state_checked に対して上記のようなことを行います。また、一番上のビューを拡張して Checkable インターフェイスを実装する必要もあります。その中で、 onCreateDrawableState() を実装し、状態が変化するたびに refreshDrawableState() を呼び出すことによって、実装している状態が true か false かを Android に伝える必要があります。

    <item android:state_pressed="true"
        android:drawable="@drawable/list_item_bg_pressed"/>
    <item android:state_checked="true"
        android:drawable="@drawable/list_item_bg_checked"/>
    <item android:drawable="@drawable/list_item_bg_normal"/>
    

...そして、RelativeLayout で state_checked と組み合わせて Checkable を実装するコードは次のようになります。

public class RelativeLayoutCheckable extends RelativeLayout implements Checkable {

    public RelativeLayoutCheckable(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RelativeLayoutCheckable(Context context) {
        super(context);
    }

    private boolean mChecked = false;

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }
    @Override
    public boolean isChecked() {
        return mChecked;
    }

    @Override
    public void setChecked(boolean checked) {
        mChecked = checked;
        refreshDrawableState();
    }

    private static final int[] mCheckedStateSet = {
        android.R.attr.state_checked,
    };

    @Override
    protected int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (isChecked()) {
            mergeDrawableStates(drawableState, mCheckedStateSet);
        }
        return drawableState;
    }    

    @Override
    public void toggle() {
        setChecked(!mChecked);
    }
}

次のおかげで:

http://sriramramani.wordpress.com/2012/11/17/custom-states/

Stackoverflow:カスタム ボタン状態を追加する方法

Stackoverflow: Selector に応答するカスタム チェック可能ビュー

http://www.charlesharley.com/2012/programming/custom-drawable-states-in-android/

http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList

http://blog.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/

于 2013-01-10T15:59:38.710 に答える
20

ドキュメントによると:

  • android:state_selected ブール値。" true" 方向コントロールでナビゲートするとき (方向パッドでリストをナビゲートするときなど)、オブジェクトが現在のユーザー選択である場合に、このアイテムを使用する必要がある場合。" false" オブジェクトが選択されていないときにこのアイテムを使用する必要がある場合。選択された状態は、フォーカス (android:state_focused) が十分でない場合 (リスト ビューにフォーカスがあり、その中の項目が方向パッドで選択されている場合など) に使用されます。

  • android:state_checked ブール値。" true" オブジェクトのチェック時にこのアイテムを使用する必要がある場合。falseオブジェクトがチェックされていないときに使用する必要がある場合は" "。

  • android:state_activated ブール値。オブジェクトが永続的な選択としてアクティブ化されているtrue場合にこのアイテムを使用する必要がある場合 (永続的なナビゲーション ビューで以前に選択したリスト項目を「強調表示」する場合など)。falseオブジェクトがアクティブ化されていないときに使用する必要がある場合は" "。API レベル 11で導入されました。

ドキュメントはかなり明確だと思いますが、何が問題なのですか?

于 2012-07-16T13:23:32.427 に答える
0

この問題の他の解決策は次のとおりです

メソッド setOnItemClickListener をオーバーライドし、コード内のさまざまなケースを確認しました。しかし、間違いなく、マービンのソリューションははるかに優れています.

listView.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position,
        long id) {
    CheckedTextView checkedTextView =
            (CheckedTextView)view.findViewById(R.id.checkedTextView);
    // Save the actual selected row data
    boolean checked = checkedTextView.isChecked();
    int choiceMode = listView.getChoiceMode();
    switch (choiceMode) {
    // Not choosing anything
    case (ListView.CHOICE_MODE_NONE):
        // Clear all selected data
        clearSelection();
        //printCheckedElements();
        break;
    // Single choice
    case (ListView.CHOICE_MODE_SINGLE):
        // Clear all the selected data
        // Revert the actual row data
        clearSelection();
        toggle(checked, checkedTextView, position);
        //printCheckedElements();
        break;
    // Multiple choice
    case (ListView.CHOICE_MODE_MULTIPLE):
    case (ListView.CHOICE_MODE_MULTIPLE_MODAL):
        // Revert the actual selected row data
        toggle(checked, checkedTextView, position);
        //printCheckedElements();
        break;
    }
    }
});
于 2013-08-21T15:14:19.980 に答える