Ответ 1
Разница между проверенными и активированными на самом деле довольно интересная. Даже документация Google является апологетической (добавление ниже):
... Например, в виде списка с одним или несколькими выделениями включены, в текущем наборе выбора активируются представления. (Um, да, мы очень сожалеем о терминологии здесь.) Активированный состояние распространяется до детей вида, на который оно установлено.
Итак, вот в чем разница:
- Активированный был введен в Honeycomb, поэтому вы не можете использовать его до этого
- Активированный теперь является свойством каждого представления. Он имеет методы setActivated() и isActivated()
- Активированный распространяется на дочерние элементы представления, на котором он установлен
- Проверено вращение вокруг представления, реализующего интерфейс Checkable. Методы 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. Когда вызываются setChecked() и т.д., Передайте вызов этим представлениям. Если эти представления реализуют ярлыки списка состояний (например, CheckBox) с другим drawable для state_checked, тогда проверенное состояние отражается в пользовательском интерфейсе.
-
Чтобы сделать приятный фон в элементе списка после того, как Honeycomb вам понадобится, вы получите список состояний с возможностью рисования для состояния 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, и вам также нужно расширить свой верхний вид для реализации интерфейса Checkable. В этом случае вам нужно сообщить 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: Custom Checkable View, который отвечает 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/