Я хотел бы знать, чем отличаются эти состояния. Я не нашел никакой веб-страницы, разъясняющей это.
Я хотел бы знать, чем отличаются эти состояния. Я не нашел никакой веб-страницы, разъясняющей это.
Ответы:
На самом деле разница между Проверено и Активировано довольно интересно. Даже документация Google извиняется (выделение добавлено ниже):
... Например, в представлении списка с включенным одиночным или множественным выбором активизируются представления в текущем наборе выбора. (Гм, да, мы глубоко сожалеем о терминологии здесь.) Активированное состояние передается дочерним элементам представления, для которого оно установлено.
Итак, вот разница:
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 () и т. Д., Передайте вызов этим представлениям. Если эти представления реализуют объекты для вывода списка состояний (например, CheckBox) с другим выводом для 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: настраиваемый проверяемый вид, который реагирует на селектор
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/
Selection is a transient property, representing the view (hierarchy) the user is currently interacting with. Activation is a longer-term state that the user can move views in and out of. 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.)
source
setItemChecked()
а затем использование селектора со свойствомandroid:state_activated="true"
Согласно документу :
android: state_selected логическое . " 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 и проверил разные случаи в коде. Но однозначно решение Марвина намного лучше.
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;
}
}
});