Androidで選択、チェック、アクティブ化された状態の違いは何ですか?


114

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


4
ビューの状態(例えば、リストビューアイテム)developer.android.com/guide/topics/resources/...
ルイ

stackoverflow.com/questions/13634259/…は、これをよりよく理解するのに役立つ同様の質問です。詳細については、こちらをご覧ください。
Acsor 2014

回答:


182

CheckedとActivatedの違いは実際には非常に興味深いものです。Googleのドキュメントでさえ謝罪です(以下に強調が追加されています)。

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

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

  1. HoneycombでActivatedが導入されたので、それまでは使用できません
  2. アクティブ化は、すべてのビューのプロパティになりました。メソッドsetActivated()とisActivated()があります
  3. アクティブ化すると、それが設定されているビューの子に伝達されます
  4. Checkedは、Checkableインターフェースを実装するビューを中心に展開します。メソッド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:セレクターに応答するカスタムチェック可能なビュー

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/


4
この答えは貴重です。Checkableレイアウトの実装方法などを検討する前に、このドキュメントを読んでほしいと思います。ありがとうございました。
Blake Mumford、2014年

12
すばらしい答えですが、「選択された」項目は扱いません。私はあなたが引用したSelection is a transient property, representing the view (hierarchy) the user is currently interacting with. Activation is a longer-term state that the user can move views in and out of. For example, in a list view with single or multiple selection enabled, the views in the current selection set are activated. (Um, yeah, we are deeply sorry about the terminology here.)
ものの直前

呼び出し:私のカスタムの背景色は唯一の背後に選択/あなたは上記の投稿ポストハニカム方法使用している場合、項目をチェックしない、アイテムを集中表示されsetItemChecked()、その後、プロパティとセレクタを使用してandroid:state_activated="true"
woojoo666

1
どうもありがとうございました。3日間無駄に考えて、「チェック、選択、アクティブ化の違いは何ですか」と自問することにしました。メニューのように単純なものを扱うのは、複雑でオーバーエンジニアリングである必要があります。グーグルの天才によって、ほとんどがこの会社が他を遅くするために意図的に設定した障害のように思われます。
Gubatron、2015年

20

ドキュメントによると:

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

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

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

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


5
android:state_selectedについて詳しく説明してください。trueに設定されている場合、どのような状況ですか?
アンダーソン

@Andersonそれは使用しているViewGroupに依存します-ListView、RecyclerView(おそらくそのLayoutManagers)、GridViewは異なる実装を持っている可能性があります:ListViewはsetFocusedを呼び出し、GridViewはsetSelectedを呼び出します。これは、異なるプラットフォームバージョンでアプリをチェックする場合にすぎません。
ataulm 2015年

1
@Anderson:リストがあり、ユーザーが矢印キーを持っている場合、1つが「選択」され、矢印キーが上下に移動すると、選択が上下に移動します。彼らが「アクティブ化」キーを押すと、それはコントロールを「アクティブ化」し、その選択を漠然とマウスオーバーに似ていると考え、チェック/アクティブ化を漠然とクリックに似ていると考えます。
Mooing Duck

私は疑問に思っていました、リストビューで1つの項目を強調表示するためにアクティブ化を使用するつもりですが、他のリストアイテムのアクティブ化をfalseに設定しますか?これらのいずれかを実行しない場合、見つける必要はありません他のアクティブ化された子アイテムで、アクティブ化をfalseに設定しますか?
Lion789 2016年

0

この問題の他の解決策は次のとおりです。https//github.com/jiahaoliuliu/CustomizedListRow/blob/master/src/com/jiahaoliuliu/android/customizedlistview/MainActivity.java

メソッド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;
    }
    }
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.