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

时间:2012-07-16 13:00:07

标签: android android-view selected checked

我想知道这些州的不同之处。我没有找到任何网页澄清这一点。

3 个答案:

答案 0 :(得分:170)

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

  

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

所以区别在于:

  1. 在Honeycomb中引入了Activated,因此您无法在此之前使用它
  2. 已激活现在是每个视图的属性。它有方法setActivated()和isActivated()
  3. 已激活传播到设置了
  4. 的视图的子项
  5. Checked围绕实现Checkable界面的View展开。方法setChecked(),isChecked(),toggle()
  6. ListView(在Honeycomb之后)调用setChecked()或setActivated(),具体取决于Android版本,如下所示(取自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()。

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

  8. 要在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"/>
    

  9. 要在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"/>
    

  10. ...在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);
        }
    }
    

    感谢以下内容:

    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/

答案 1 :(得分:18)

根据doc

  • android:state_selected 布尔。 “true”如果在导航时对象是当前用户选择时应使用此项目 使用方向控制(例如在列表中导航时) 用d-pad); “false”如果对象在此时应使用此项 未选中的。焦点时使用选定的状态 (android:state_focused)是不够的(比如列表视图有的话) 使用d-pad选择焦点和其中的项目。

  • android:state_checked 布尔。 “true”如果在检查对象时应使用此项; “false”如果应该使用的话 对象未经检查。

  • android:state_activated 布尔。 “true”如果在将对象激活为持久选择时应使用此项(例如 至于“突出显示”持久性中先前选择的列表项 导航视图); “false”如果在对象不是时应该使用它 活性。在 API级别11

  • 中引入

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

答案 2 :(得分: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;
    }
    }
});