在Android中选择,检查和激活状态之间有什么区别?

Lou*_*uis 105 android selected checked android-view

我想知道这些州有什么不同.我没有找到任何网页澄清这一点.

小智 175

Checked和Activated之间的区别实际上非常有趣.即使是Google文档也是抱歉的(下面重点介绍):

...例如,在启用了单个或多个选择的列表视图中,将激活当前选择集中的视图.(嗯,是的,我们对这里的术语深感抱歉.)激活的状态向下传播到它所设置的视图的子节点.

所以这是区别:

  1. 在Honeycomb中引入了Activated,因此您无法在此之前使用它
  2. 已激活现在是每个视图的属性.它有方法setActivated()和isActivated()
  3. 已激活传播到设置它的View的子项
  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));
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    注意mCheckStates变量.它会跟踪列表中的哪些位置被检查/激活.例如,可以通过getCheckedItemPositions()访问它们.另请注意,对ListView.setItemChecked()的调用会调用上面的内容.换句话说,它同样可以称为setItemActivated().

  6. 在Honeycomb之前,我们必须实现变通方法以反映列表项中的state_checked.这是因为ListView仅在布局中最顶层的View上调用setChecked()(并且布局不实现可检查)......并且它不会在没有帮助的情况下传播.这些变通方法具有以下形式:扩展根布局以实现Checkable.在其构造函数中,递归地查找实现Checkable的所有子项.当调用setChecked()etc ...时,将调用传递给那些视图.如果这些视图为state_checked实现具有不同drawable的状态列表drawable(例如CheckBox),则检查状态将反映在UI中.

  7. 要在Honeycomb之后为列表项做一个很好的背景,你需要做的就是有一个状态列表可绘制,状态为state_activated的drawable(当然使用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"/>
    
    Run Code Online (Sandbox Code Playgroud)

  8. 要在HoneyComb之前为列表项做一个很好的背景,你可以为state_checked执行类似上面的操作,并且还需要扩展最顶层的视图来实现Checkable接口.然后,您需要通过实现onCreateDrawableState()并在状态更改时调用refreshDrawableState()来告诉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"/>
    
    Run Code Online (Sandbox Code Playgroud)

...并且在RelativeLayout中实现Checkable和state_checked的代码可以是:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

感谢以下内容:

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/

  • 很好的答案,但不解决"选定"的项目.我在你引用的句子之前的句子中找到了答案:`Selection是一个瞬态属性,表示用户当前正在与之交互的视图(层次结构).激活是一种较长期的状态,用户可以将视图移入和移出.例如,在启用了单个或多个选择的列表视图中,将激活当前选择集中的视图.(嗯,是的,我们对这里的术语深感抱歉.)`[来源](http://developer.android.com/reference/android/view/View.html#setActivated(boolean)) (12认同)
  • 这个答案是无价的.我希望在尝试研究如何实现Checkable布局等之前先阅读它.非常感谢你. (4认同)

AMe*_*rle 19

根据文件:

  • android:state_selected 布尔值." true"如果在使用方向控件导航时对象是当前用户选择时(例如在使用d-pad导航列表时),则应使用此项目; " false"如果未选择对象时应使用此项.当焦点(android:state_focused)不足时(例如,当列表视图具有焦点并且使用d-pad选择其中的项目时),将使用所选状态.

  • android:state_checked 布尔值." true"如果在检查对象时应该使用此项目; " false"如果在取消选中对象时应该使用它.

  • android:state_activated 布尔值." true"如果在将对象激活为持久选择时(例如,在持久导航视图中"突出显示"先前选择的列表项),则应使用此项目; " false"如果在未激活对象时应该使用它.在API级别11中引入.

我认为文档很清楚,那么问题是什么?

  • 你能详细说明android:state_selected.设置为true时的情况是什么? (4认同)