State_activated on pre Honeycomb Devices
Вы не можете использовать в качестве фона для элементов списка следующее состояние:
<item android:drawable="@drawable/ic_launcher" android:state_activated="true"/>
На устройствах Pre Honeycomb, потому что этот селектор не поддерживается там, и версия Android не отслеживает активированные элементы.
Как можно эмулировать такое поведение? Особенно при использовании смещений (список слева в одном фрагменте и в зависимости от того, что выбрано в виде подробного просмотра справа) этот показатель очень важен.
Я знаю, что этот вопрос задавали до здесь, но принятый ответ там ссылается на статью в блоге, в которой говорится, что в "Шаге 4" нет возможность иметь активированный индикатор и вместо этого отключает использование только для предотвращения ошибок. Это приводит к тому, что индикатор не отображается, что я ищу.
Ответы
Ответ 1
Я решил проблему, используя небольшой трюк: пропустив свойство state_checked
, которое существует с Android версии 1, можно эмулировать поведение state_activated
. Нет необходимости изменять адаптер List или сохранять состояние самостоятельно.
Я написал подробный пример, содержащий весь код, необходимый для переопределения и публикации в репозитории github.
Ответ 2
Многое, как предложил Крис Дженкинс, я просто добавляю небольшой код к моему переопределению getView
:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// ...
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
convertView.setBackgroundColor(Color.WHITE);
if (listView.isItemChecked(position)) {
convertView.setBackgroundColor(Color.LTGRAY);
}
}
}
Элемент, который проверяется или нет, автоматически обрабатывается в моем случае (используя CHOICE_MODE_MULTIPLE и v7 ActionMode.Callback с setOnItemLongClickListener, вызывающим обратный вызов)
Ответ 3
Просто измените фон выбранного элемента списка в вашем адаптере на "активированный".
Итак, в моем адаптере метод просмотра может выглядеть примерно так:
getView(int pos, View convertView, ViewGroup parent){
//... etc get view etc
if(mSelectedItemPos == pos){
v.setBackgroundDrawable(ctx.getResources().getDrawable(R.drawable.list_item_selected_state);
//or v.setBackgroundResource(R.drawable.list_item.....);
} else {
v.setBackgroundDrawable(ctx.getResources().getDrawable(R.drawable.list_item_selector);
}
}
Это все, что я делаю, если хочу поддерживать выбранные/активированные состояния на представлениях. Немного больше работы, но может быть столь же гибким, как вы хотите.
Ответ 4
Я сделал это вручную следующим образом:
Создайте массив для хранения выбранного состояния списка, инициализируйте его в конструкторе адаптера, а затем укажите его в методе getView (в случае, если текущий выбранный элемент прокручивается из поля зрения) и ваш метод onItemClick (чтобы изменить текущий выбор и отключение старого).
public static boolean selectedStatus[]; // array to hold selected state
public static View oldView; // view to hold so we can set background back to normal after
Конструктор инициализирует массив
public class MyCursorAdapter extends SimpleCursorAdapter {
private LayoutInflater mInflater;
private int layout;
public MyCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
mInflater = LayoutInflater.from(context);
this.layout = layout;
selectedStatus = new boolean[c.getCount()];
for (int i = 0; i < c.getCount(); i++) {
selectedStatus[i] = false; // Start with all items unselected
}
}
}
getView, необходимый для того, когда ребенок прокручивается вне поля зрения
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = View.inflate(context, layout, null);
if(selectedStatus[position] == true){
v.setBackgroundResource(R.color.blue);
} else {
v.setBackgroundResource(R.color.black);
}
return v;
}
onItemClick изменить выбранный элемент в массиве и на экране
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
mRowId = id;
EventDisplayFragment eventdisplay = new EventDisplayFragment();
getFragmentManager().beginTransaction()
.replace(R.id.rightpane, eventdisplay).commit();
if(MyCursorAdapter.oldView != null){
MyCursorAdapter.oldView.setBackgroundResource(R.color.black); // change the background of the old selected item back to default black }
MyCursorAdapter.oldView = v; // set oldView to current view so we have a reference to change back on next selection
for (int i = 0; i < selectedStatus.length; i++) {
if(i == position){ // set the current view to true and all others to false
selectedStatus[i] = true;
} else {
selectedStatus[i] = false;
}
}
}
v.setBackgroundResource(R.color.blue);
return true;
}
});