What is the difference between the states selected, checked and activated in Android?

我想知道这些状态有什么不同。我没有发现任何网页澄清这一点。

51629 次浏览

According to the doc:

  • Android: state _ select Boolean. “ true”如果当对象是当前用户导航时选择的对象时应该使用此项 使用方向控件(例如在列表中导航时) “ false”,如果对象是 未选中。焦点时使用选中状态 (android: state _ focus)是不够的(例如当列表视图具有 焦点和其中的一个项目是用 d-pad 选择的。

  • Android: state _ check 布尔型.如果检查对象时应使用此项,则为“ true”; 如果应在 对象未选中

  • Android: state _ actived Boolean. “ true”,如果对象作为持久选择被激活时应该使用此项(如 以“突出显示”先前选定的列表项 导航视图) ; “ false”,如果它应该使用时,对象不是 激活。引入 空气污染指数十一级

我觉得医生说得很清楚了,有什么问题吗?

Checked 和 Activated 之间的区别实际上非常有趣,甚至 Google 的文档也是带有歉意的(下面添加了强调) :

... For example, in a list view with single or multiple selection 启用后,当前选择集中的视图将被激活。 < em > (Um, 是的,我们对这里的术语深感抱歉 state is propagated down to children of the view it is set on.

所以区别在于:

  1. 激活是在蜂巢引入的,所以你不能在那之前使用它
  2. Activated 现在是每个视图的属性。它有 setActivated ()和 isActivated ()方法
  3. 激活后将传播到设置它的视图的子级
  4. Checked 围绕着一个实现 Checkable 接口的视图
  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 变量。它跟踪列表中的哪些位置被选中/激活。这些都可以通过,例如,getCheckedItemposition ()来访问。另请注意,对 ListView.setItemChecked ()的调用将调用上述内容。换句话说,它同样可以被称为 setItemActivated ()。

  6. 在 Honeycomb 之前,我们必须实现变通方法来反映列表项中的 state _ check。这是因为 ListView 调用 setChecked ()仅在布局的最上面的视图上(布局不实现可检查的) ... 而且它不会在没有帮助的情况下传播。这些解决方案的形式如下: 扩展根布局以实现 Checable。在它的构造函数中,递归地找到所有实现 Checable 的子级。当 setChecked ()等。.被调用,将调用传递给这些视图。如果这些视图实现了状态列表绘制(例如 CheckBox) ,并为 state _ check 实现了不同的绘制,那么选中的状态就会反映在 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. 为了在 HoneyComb 之前为列表项做一个好的背景,您需要对 state _ check 执行类似上面的操作,并且您还需要扩展您的最顶层视图来实现 Checable 接口。在这个范围内,您需要通过实现 onCreateDrawableState ()并在状态发生变化时调用 resh DrawableState ()来告诉 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 中实现 Checable 和 state _ check 的代码可以是:

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

Here is other solution for this problem: 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;
}
}
});