Android. Элемент Keep ListView подсвечивается после того, как вы нажали
Итак, у меня есть активность с 2 ListView
виджетами, когда вы выбираете значение в первом, второе заполняется значениями, относящимися к выбору в первом ListView
. Этот механик работает без проблем, но теперь я хочу, чтобы пользовательские варианты оставались выделенными. Я прочитал хороший вопрос, связанный с этой темой, и кажется, что существует множество способов сделать это, но после того, как вы попробовали около 4-5 из них, я все еще не могу заставить его работать.
У меня есть работа над вторым ListView
с использованием атрибута XML android:listSelector="#CCCCCC"
, но это, кажется, очищается после того, как в микс добавлен OnItemClickListener
(например, тот, который я использую при первом ListView
).
Пока что у меня есть:
Пользовательский OnItemClickListener
Я нашел просмотр различных ответов по этому вопросу (немного изменил его, чтобы он мог загрузить мою информацию во второй ListView):
private class ItemHighlighterListener implements OnItemClickListener {
private View oldSelection = null;
public void clearSelection() {
if(oldSelection != null) {
oldSelection.setBackgroundColor(android.R.color.transparent);
}
}
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
clearSelection();
oldSelection = view;
view.setBackgroundDrawable(view.getContext().getResources().getDrawable(R.drawable.list_selector));
loadClubs(mXMLPortalOptions.getRegion(pos).getId());
mClubList.setAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.list_item_white, mClubs));
}
}
Здесь мой list_selector.xml
файл:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"><shape>
<solid android:color="#CCCCCC" />
</shape></item>
<item android:state_selected="false"><shape>
<solid android:color="#FFFFFF" />
</shape></item>
</selector>
Вызывается и выполняется метод (OnItemClick), но фон моего ListItem
остается одного цвета:/
Я не могу поверить, что эта простая задача оказалась настолько сложной.
Если я пропустил код, который может быть полезен, или если у моего вопроса не хватает деталей, не стесняйтесь указать на это, и я сделаю все возможное, чтобы объяснить себя.
Ответы
Ответ 1
Поместите переменную позиции для выбранного элемента. Измените положение в методе onItemClicked()
. Проверьте выбранную позицию в списке Адаптер внутри getView()
и установите фон для выбранного элемента.
public class TestAdapter extends BaseAdapter
{
private Context context;
private ArrayList<TestList> testList;
private int selectedIndex;
private int selectedColor = Color.parseColor("#1b1b1b");
public TestAdapter(Context ctx, ArrayList<TestList> testList)
{
this.context = ctx;
this.testList = testList;
selectedIndex = -1;
}
public void setSelectedIndex(int ind)
{
selectedIndex = ind;
notifyDataSetChanged();
}
@Override
public int getCount()
{
return testList.size();
}
@Override
public Object getItem(int position)
{
return testList.get(position);
}
@Override
public long getItemId(int position)
{
return position;
}
private class ViewHolder
{
TextView tv;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View vi = convertView;
ViewHolder holder;
if(convertView == null)
{
vi = LayoutInflater.from(context).inflate(R.layout.test_list_item, null);
holder = new ViewHolder();
holder.tv = (TextView) vi;
vi.setTag(holder);
}
else
{
holder = (ViewHolder) vi.getTag();
}
if(selectedIndex!= -1 && position == selectedIndex)
{
holder.tv.setBackgroundColor(Color.BLACK);
}
else
{
holder.tv.setBackgroundColor(selectedColor);
}
holder.tv.setText("" + (position + 1) + " " + testList.get(position).getTestText());
return vi;
}
}
Теперь установите переменную selectedIndex, когда элемент списка нажат.
public class TestActivity extends Activity implements OnItemClickListener
{
// Implemented onItemClickListener
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
adapter.setSelectedIndex(position);
}
}
Ответ 2
Чтобы расширить решение Shaiful, вы можете не заставить его работать в вашей ситуации.
Если вы используете свой код в public void onListItemClick(ListView l, View v, int index, long id)
, если вы используете фрагменты и должны объявлять интерфейс вместо реализации OnListItemClickListener или что-то другое, вызывающее появление вашей IDE ошибки, вам может потребоваться доступ к переменным и методы статически.
public static int selectedPosition = 0;
ArrayAdapter<Your_obj> adapter = null;
@Override
public void onListItemClick(ListView l, View v, int index, long id) {
super.onListItemClick(l, v, index, id);
selectedPosition = index;
Your_adapter.setSelectedIndex(selectedPosition);
adapter.notifyDataSetChanged();
}
И в Your_adapter:
private static int selectedIndex;
//public Your_adapter...
public static void setSelectedIndex(int ind) {
selectedIndex = ind;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
WellHolder holder = null;
if (null == convertView) {
//set up your "holder"
}
if (position == selectedIndex) {
convertView.setBackgroundColor(convertView.getResources().getColor(R.color.cyan));
}
else {
convertView.setBackgroundColor(convertView.getResources().getColor(R.color.silver));
}
return convertView;
}
Некоторые другие отличия заключаются в том, что вам не нужно инициализировать какие-либо переменные как "0" или "-1", а в вашей активности вызывается notifyDataSetChanged().
Еще раз спасибо за ваше решение @Shaiful. Это, безусловно, помогло мне сэкономить время, пытаясь получить то, что по умолчанию в iOS для работы на Android, все, избегая при этом селектора/элемента/сфокусированного/нажатого/и т.д.
Ответ 3
У меня возникла аналогичная проблема. Это мое решение:
Сначала добавьте настраиваемый селектор списков в список:
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:listSelector="@drawable/listselector" />
Внутри listselector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_accelerated="false"
android:drawable="@drawable/bg" />
</selector>
И, наконец, выталкиваемый bg.xml с цветом вашего выделения:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#33b5e6"/>
</shape>
Ответ 4
Я искал его две недели назад, и результат невозможен с помощью переносного селектора.
Для получения дополнительной информации прочитайте этот пост в блоге разработчиков Android: Touch Mode
В возобновлении: только когда ваш палец находится на экране, элемент выбирается.
Другая возможность - сохранить, какой элемент выбран в var и paint, используя ваш пользовательский адаптер, например Shaiful.
Ответ 5
lv.setSelector(R.drawable.highlighter);
поместите изображение highlighter.png
в папку с возможностью копирования
Самый простой способ выделить выделенный элемент в виде списка.
Ответ 6
//create a list_itemselectorin drawable folder
//you will get the list item selected background color change once you select //the item
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Focused State -->
<item android:state_focused="true"><shape>
<solid android:color="#66FFFFFF" />
</shape></item>
<!-- Pressed State -->
<item android:state_pressed="true"><shape>
<solid android:color="@color/Black" />
</shape></item>
<!-- Default State -->
<item><shape>
<solid android:color="@color/Black" />
</shape></item>
</selector>
//create a list in layout folder
<ListView
android:id="@+id/mySlidingList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:divider="@color/GrayHot"
android:dividerHeight="1dip"
android:listSelector="@drawable/list_itemselector"
android:scrollbars="none" />
//И посмотрим вывод.
Ответ 7
Я думаю, что лучшее и самое простое решение - это. Вам не нужно устанавливать любой android:listSelector
в самом ListView или вносить какие-либо изменения в адаптер. Вы не даже должны вызывать любой setSelection(position)
в OnItemClickListener
, поскольку он обрабатывается автоматически.
-
Установите для своего списка ListView:
android:choiceMode="singleChoice"
-
Установить фон самого элемента списка:
android:background="?android:attr/activatedBackgroundIndicator"
-
Что это.
Таким образом вы получите поведение системы по умолчанию. Как это делается в макете android.R.layout.simple_list_item_activated_1
по умолчанию.
Ответ 8
Если вы можете использовать drawable для отображения listItem Highlighted, вы должны использовать следующий код: -
listView.setSelector(R.drawable.bg_image);
Он работает.
Ответ 9
Существует простое полностью-XML-решение, которое сработало для меня.
Во-первых, определите XML-drawable с селекторным кодом, в котором "нормальное" состояние будет соответствовать "выбранному не нажатому" визуальному состоянию элемента списка, а state_pressed = true - "нажатому" визуальному состоянию.
Пример файла "custom_item_selector.xml", напоминающий выбор голубого цвета:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid
android:color="#643292ff">
</solid>
<stroke
android:width="1dp"
android:color="#c83292ff">
</stroke>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid
android:color="#323292ff">
</solid>
<stroke
android:width="1dp"
android:color="#783292ff">
</stroke>
</shape>
</item>
</selector>
(также может быть установлено сфокусированное состояние).
Во-вторых, примените этот xml-drawable как ListView listSelector и установите желаемый параметр выбора:
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/listView"
android:choiceMode="singleChoice"
android:listSelector="@drawable/custom_item_selector"/>
Это все. Он позволяет определять различные визуальные состояния для "просто выбранных" и "нажатых выбранных" элементов, например, делая ярлыки при нажатии.
Ответ 10
Чтобы сохранить выделенные элементы списка (несколько выделенных), нажмите (активировано), следуя инструкциям.
1. Установите фон, чтобы отобразить макет элемента как возможно.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/list_item_selector">
<ImageView
android:id="@+id/icon"
android:layout_width="22px"
android:layout_height="22px"
android:layout_marginLeft="4px"
android:layout_marginRight="10px"
android:layout_marginTop="4px"
android:src="@mipmap/ic_launcher" >
</ImageView>
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@+id/label"
android:textSize="20px" >
</TextView>
</LinearLayout>
2. выбираемый селектор
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@android:color/holo_red_light" />
<item android:state_activated="true" android:drawable="@android:color/holo_orange_dark" />
</selector>
3. Listview устанавливает режим множественного выбора
getListView() setChoiceMode (ListView.CHOICE_MODE_MULTIPLE);.
При нажатии: ![введите описание изображения здесь]()
Ниже показано изображение, когда пользователь выбрал несколько элементов списка.
При активации: ![введите описание изображения здесь]()
Ответ 11
Подводя итог этому сообщению и, возможно, помогите кому-то в будущем, я предлагаю ответить:)
Сначала нам нужно создать файл res/drawable/list_item_background.xml
со следующим содержимым:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_activated="true"
android:drawable="@color/list_item_activated" />
<item
android:drawable="@color/list_item_default" />
</selector>
Укажите свои ресурсы, конечно. И вы также можете добавить другие элементы <item>
с различными состояниями, такими как state_pressed
, state_focused
и т.д.
Затем мы должны установить параметр background
в наш элемент пользовательского списка ViewGroup
(f.i. res/layout/list_item_layout.xml
) следующим образом:
android:background="@drawable/list_item_background"
Следующий шаг - изменение нашего пользовательского класса Adapter
. Вот фрагмент кода:
public class CustomAdapter extends BaseAdapter {
private List<Item> items;
private LayoutInflater itemInflater;
private int selectedIndex; // add this
public CustomAdapter(Context c, List<Item> items) {
this.items = items;
this.itemInflater = LayoutInflater.from(c);
selectedIndex = -1; // add this
}
/* add this */
public void setSelectedIndex(int index) {
selectedIndex = index;
notifyDataSetChanged();
}
/* other adapter stuff */
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = itemInflater.inflate(R.layout.list_item_layout, parent, false);
}
// add this
convertView.setActivated(selectedIndex != -1 && position == selectedIndex);
/* do some stuff */
return convertView;
}
}
Наконец, мы должны вызвать метод адаптера setSelectedIndex(position)
в методе onItemClick(...)
AdapterView.OnItemClickListener
.
public class YourActivity extends Activity
implements AdapterView.OnItemClickListener {
private CustomAdapter mCustomAdapter;
/* activity implementation */
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mCustomAdapter.setSelectedIndex(position);
}
}
Теперь мы можем быть довольны соответствующими элементами списка, выделяющими:)
P.S. Если мы хотим включить режим множественного выбора в нашем списке, мы просто поместим следующую строку в наш класс активности, где хранится экземпляр listView
:
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
Таким образом, мы получим соответствующие несколько элементов.
- Надеюсь, это поможет кому угодно:)