В чем разница между состояниями, выбранными, проверенными и активированными в Android?
Я хотел бы знать, чем отличаются эти состояния. Я не нашел никакой веб-страницы, разъясняющей это.
3 ответов
разница между Checked и Activated на самом деле довольно интересная. Даже документация Google извиняется (акцент ниже добавлен):
... Например, в виде списка с одним или несколькими выделениями включено, представления в текущем наборе выбора активированы. (Хм, да, мы глубоко сожалеем о терминологии.) активированный состояние передается детям, считает он находится на.
так вот в чем разница:
- активированный был введен в Honeycomb, поэтому вы не можете использовать его до этого
- активировано теперь свойство каждого представления. Он имеет методы setActivated () и isActivated ()
- активированный распространяется на дочерние элементы представления, на котором он установлен
- Checked вращается вокруг представления, реализующего проверяемый интерфейс. Методы setChecked (), isChecked(), toggle ()
- 
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 (). 
- до Honeycomb нам пришлось реализовать обходные пути, чтобы отразить state_checked в наших элементах списка. Это связано с тем, что ListView вызывает setChecked() только на самом верхнем представлении в макете (а макеты не реализуют checkable) ... и она не распространяется без посторонней помощи. Эти обходные пути имели следующую форму: расширьте корневой макет для реализации Checkable. В своем конструкторе рекурсивно найдите все дочерние элементы, реализующие Checkable. Когда вызове setchecked() и т. д... вызываются, передают вызов этим представлениям. Если эти представления реализуют список состояний drawables (например, флажок) с другим drawable для state_checked, то проверенное состояние отражается в пользовательском интерфейсе. 
- 
чтобы сделать хороший фон для элемента списка после Honeycomb все, что вам нужно сделать, это иметь список состояний drawable с drawable для состояния 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"/>
- 
чтобы сделать хороший фон для элемента списка до HoneyComb вы сделали бы что-то вроде выше для state_checked, и Вам также нужно расширить свой самый верхний вид для реализации проверяемого интерфейса. В этом случае вам нужно сообщить Android, является ли состояние, которое вы реализуете, истинным или ложным, реализуя onCreateDrawableState () и вызывая refreshDrawableState() всякий раз, когда состояние изменения. <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"/>
... и код для реализации Checkable в сочетании с state_checked в RelativeLayout может быть:
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/
по словам doc:
- android: state_selected Boolean. " - true" Если этот элемент должен использоваться, когда объект текущий выбор пользователя при навигации с управлением по направлению (например, при навигации по списку С d-pad);"- false" если этот элемент должен использоваться, когда объект не выбрать. Выбранное состояние используется при фокусировке (android: state_focused) недостаточно (например при представлении списка фокус и элемент внутри него выбирается с помощью d-pad).
- android: state_checked Boolean. " - true" Если этот элемент должен использоваться при проверке объекта; "- false" если он должен использоваться, когда объект не проверен.
- android: state_activated Boolean. " - true" Если этот элемент должен использоваться, когда объект включается в качестве постоянного выбор ( как "выделить" ранее выбранный элемент списка в постоянном навигации); "- false" если он должен использоваться, когда объект не активированный. Введено в уровень API 11.
Я думаю, что док довольно ясен, так в чем проблема ?
вот другое решение этой проблемы: https://github.com/jiahaoliuliu/CustomizedListRow/blob/master/src/com/jiahaoliuliu/android/customizedlistview/MainActivity.java
Я переопределил метод setOnItemClickListener и проверил случаи differente в коде. Но окончательно решение Марвина гораздо лучше.
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;
    }
    }
});
