Android 中选中、选中和激活的状态有什么区别? [英] What is the difference between the states selected, checked and activated in Android?

查看:27
本文介绍了Android 中选中、选中和激活的状态有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道这些状态有何不同.我没有找到任何网页来澄清这一点.

解决方案

Checked 和 Activated 的区别其实挺有意思的.甚至 Google 文档也很抱歉(强调在下面添加):

<块引用>

... 例如,在具有单选或多选的列表视图中启用,当前选择集中的视图被激活.(嗯,是的,我们对这里的术语深表歉意.) 已激活状态向下传播到设置它的视图的子级.

区别就在这里:

  1. 在 Honeycomb 中引入了 Activated,因此在此之前您无法使用它
  2. Activated 现在是每个视图的属性.它有方法 setActivated() 和 isActivated()
  3. Activated 传播到设置它的 View 的子级
  4. Checked 围绕实现 Checkable 接口的 View 展开.方法 setChecked()、isChecked()、toggle()
  5. ListView(在 Honeycomb 之后)调用 setChecked() 或 setActivated() 取决于 Android 版本如下(取自 Android 源代码):

    if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {如果(可检查的子实例){((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 仅在布局中的最顶层 View 上调用 setChecked() (并且布局不实现可检查)......并且它不会在没有帮助的情况下传播.这些变通方法采用以下形式: 扩展根布局以实现 Checkable.在其构造函数中,递归查找所有实现 Checkable 的子级.当 setChecked() 等...被调用时,将调用传递给这些视图.如果这些视图使用 state_checked 的不同可绘制对象实现状态列表可绘制对象(例如 CheckBox),则选中的状态会反映在 UI 中.

  7. 要在 Honeycomb 之后为列表项做一个漂亮的背景,您需要做的就是拥有一个可绘制的状态列表,其中包含一个可绘制的状态 state_activated 像这样(当然还使用 setItemChecked()):

  8. 要在 HoneyComb 之前为列表项做一个漂亮的背景,您可以对 state_checked 执行类似上面的操作,并且您还需要扩展最顶层的视图以实现 Checkable 接口.然后,您需要通过实现 onCreateDrawableState() 并在状态发生变化时调用 refreshDrawableState() 来告诉 Android 您正在实现的状态是真还是假.

    <item android:drawable="@drawable/list_item_bg_normal"/>

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

public class RelativeLayoutCheckable extends RelativeLayout 实现 Checkable {公共RelativeLayoutCheckable(上下文上下文,AttributeSet attrs){超级(上下文,属性);}公共相对布局可检查(上下文上下文){超级(上下文);}私人布尔 mChecked = false;@覆盖受保护的无效 onFinishInflate() {super.onFinishInflate();}@覆盖公共布尔 isChecked() {返回 mChecked;}@覆盖公共无效设置检查(布尔值检查){mChecked = 已检查;refreshDrawableState();}private static final int[] mCheckedStateSet = {android.R.attr.state_checked,};@覆盖protected int[] onCreateDrawableState(int extraSpace) {最终 int[] drawableState = super.onCreateDrawableState(extraSpace + 1);如果(isChecked()){mergeDrawableStates(drawableState, mCheckedStateSet);}返回 drawableState;}@覆盖公共无效切换(){setChecked(!mChecked);}}

感谢以下内容:

http://sriramramani.wordpress.com/2012/11/17/自定义状态/

Stackoverflow:如何添加自定义按钮状态

Stackoverflow:响应选择器的自定义可检查视图

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

http://developer.android.com/guide/主题/资源/drawable-resource.html#StateList

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

I'd like to know what differs those states. I didn't find any webpage clarifying this.

解决方案

The difference between Checked and Activated is actually quite interesting. Even the Google documentation is apologetic (emphasis below added):

... 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.) The activated state is propagated down to children of the view it is set on.

So here is the difference:

  1. Activated was introduced in Honeycomb so you can't use it before that
  2. Activated is now a property of every View. It has methods setActivated() and isActivated()
  3. Activated propagates to children of the View on which it is set
  4. Checked revolves around a View implementing the Checkable interface. Methods setChecked(), isChecked(), toggle()
  5. ListView (after Honeycomb) calls setChecked() OR setActivated() depending on Android version as below (taken from Android source code):

    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));
        }
    }
    

    Note the mCheckStates variable. It keeps track of which positions in your list are checked / activated. These are accessible via, for example, getCheckedItemPositions(). Note also that a call to ListView.setItemChecked() invokes the above. In other words, it could equally be called setItemActivated().

  6. Prior to Honeycomb we had to implement workarounds to reflect state_checked in our list items. This is because ListView calls setChecked() ONLY on the topmost View in the layout (and layouts do not implement checkable) ... and it does NOT propagate without help. These workarounds were of the following form: Extend the root layout to implement Checkable. In its constructor, recursively find all the children that implement Checkable. When setChecked() etc... are called, pass the call on to those Views. If those views implement state list drawables (eg a CheckBox) with a different drawable for state_checked then the checked state is reflected in the UI.

  7. To do a nice background to a list item after Honeycomb all you need do is have a state list drawable with a drawable for the state state_activated like this (and use setItemChecked() of course):

    <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. To do a nice background to a list item prior to HoneyComb you would do something like the above for state_checked and you ALSO need to extend your topmost view to implement the Checkable interface. Within that you then need to tell Android whether the state you are implementing is true or false by implementing onCreateDrawableState() and calling refreshDrawableState() whenever the state changes.

    <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"/>
    

... and the code to implement Checkable combined with state_checked in a RelativeLayout could be:

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);
    }
}

Thanks to the following:

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

Stackoverflow: How to add a custom button state

Stackoverflow: Custom Checkable View which responds to 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/

这篇关于Android 中选中、选中和激活的状态有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆