Вибраний елемент Android ListView залишається виділеним


76

У мене є XMLдвоє ListView, один зі списком клієнтів, заповнений запитом вибору ( lv_cli), а інший із даними про вибраного клієнта ( lv_cli_det). Я хотів би, щоб клієнт був обраний lv_cliпід час lv_cli_detпоказу деталей.

XML:

<ListView
    android:id="@+id/cli_lista"
    android:layout_width="512dp"
    android:layout_height="wrap_content"
    android:fadeScrollbars="false"
    >
</ListView>

<ListView
    android:id="@+id/cli_lista_det"
    android:layout_width="512dp"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@+id/cli_lista"
    android:fadeScrollbars="false" >
</ListView>

Java:

Cursor cursor = db.rawQuery("Select NrCl||';'||Nome From Clientes", null);
final ListView t = (ListView)findViewById(R.id.cli_lista);
ArrayAdapter<String> myarrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, listItems);
t.setAdapter(myarrayAdapter);

final ListView td = (ListView)findViewById(R.id.cli_lista_detalhe);
final ArrayAdapter<String> myarrayAdapter2 = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, listItems2);

t.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        String item = ((TextView)view).getText().toString();
        String[] strArray = item.split("\\;");

        cli.load(strArray[0].toString());
        td.setAdapter(myarrayAdapter2);
        listItems2.clear();
        listItems2.add("Nome: " + cli.getNome());
        listItems2.add("Morada: " + cli.getMorada());
        listItems2.add("Localidade: " + cli.getLoca());
        listItems2.add("Código Postal: " + cli.getCp());
        listItems2.add("Pais: " + cli.getPais());
        listItems2.add("Nif: " + cli.getNif());
        listItems2.add("Tel: " + cli.getTel());
        listItems2.add("Tlm: " + cli.getTlm());
        listItems2.add("Tipo Preço: " + cli.getTipoPvn());
        listItems2.add("Cond. Pagamento: " + cli.getCpg());
        listItems2.add("Obs: " + cli.getObs());
        td.setAdapter(myarrayAdapter2);
        myarrayAdapter2.notifyDataSetChanged(); 
    }
});

покажіть свій код. ти використовував фрагмент чи що ??
— Авінаш Кумар Панкадж

просто робити реверс. як ви робите код для виділення списку? поштовий індекс тут ..
— Dhaval Parmar

Відповіді:


135

Щоб зберегти колір елемента перегляду списку під час натискання, включіть такий рядок у макет елемента перегляду списку:

android:background="@drawable/bg_key"

Потім визначте bg_key.xmlв drawableтакій папці:

<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item 
        android:state_selected="true"
        android:drawable="@color/pressed_color"/>
    <item
        android:drawable="@color/default_color" />
</selector>

Нарешті, включіть це у свій ListView onClickListener:

listView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,long arg3) {
        view.setSelected(true);
        ... // Anything
    }
});

Таким чином, у будь-який час буде обрано лише один предмет. Ви можете визначити свої значення кольору res/values/colors.xmlприблизно так:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="pressed_color">#4d90fe</color>
    <color name="default_color">#ffffff</color>
</resources>

помилка: Помилка: Не знайдено жодного ресурсу, який би відповідав даному імені (у 'drawable' зі значенням '@ drawable / Press_color'). помилка: Помилка: Не знайдено жодного ресурсу, який би відповідав вказаному імені (у "drawable" зі значенням "@ color / default_color").
— Сельта

2
Назва кольору - лише приклад. Це показує, що ви можете або 1) створити кольорове зображення 9patch у форматі png, а потім помістити його в папку, що малюється, або 2) ви можете визначити колір у res / values ​​/ colors.xml, а потім викликати його за допомогою android: drawable = "@ колір / вашкольор ". Вам потрібно спочатку створити colors.xml, якщо він не існує.
— Neoh,

Чи працює перший перегляд списку належним чином? Вам потрібно зробити те саме, що стосується макета xml другого списку та його onClickListener ()
— Neoh,

мені не потрібен другий перегляд списку, щоб діяти як перший
— Сельта

1
Цей метод слід записати в офіційний документ android.
— Річард

165

Я знайшов правильний шлях. Це дуже просто. У ресурсі опишіть наступне:

android:choiceMode="singleChoice"
android:listSelector="#666666"

(або ви можете вказати посилання на ресурс замість значення кольору)

Програмно:

listView.setSelector(Drawable selector);
listView.setSelector(int resourceId);
listView.setChoiceMode(int mode);

режим може бути одним із таких: AbsListView.CHOICE_MODE_SINGLE, AbsListView.CHOICE_MODE_MULTIPLE, AbsListView.CHOICE_MODE_NONE (за замовчуванням)

(AbsListView є абстрактним предком класу ListView)

Маніпуляції PS з onItemClick та зміна фону подання збанкрутують, оскільки сам погляд є тимчасовим об'єктом. Отже, ви не повинні відстежувати вид.

Якщо наш список досить довгий, подання, пов’язані з прокручуваними елементами, будуть видалені з ієрархії та відтворені, коли ці елементи з’являться знову (з кешованими параметрами відображення, наприклад, фоном). Отже, вид, який ми відстежували, тепер не є фактичним видом товару, і зміна його фону не означає нічого для фактичного подання товару. В результаті ми вибрали кілька елементів.


15
Це повинна бути прийнята відповідь. Простий і дуже ефективний.
— Хостакович

2
Проста та елегантна відповідь!
— темний лицар

1
Хоча інші відповіді є правильними, ця відповідь є чистою та простою.
— Вельваль,

1
Я хочу один із елементів listView, вибраний за замовчуванням, як я можу це зробити?
— Апурва

3
@AJG Якщо я змінив режим на одиночний на Множинний, це не спрацює. Він відображає лише останній кольоровий вибраний елемент. Але я хочу, щоб якщо я вибрав три елементи, то всі три повинні бути кольоровими.
— Аджай Шарма

37
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

            for (int j = 0; j < adapterView.getChildCount(); j++)
                adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);

            // change the background color of the selected element
            view.setBackgroundColor(Color.LTGRAY);
});

Можливо, вам може знадобитися зберегти поточний вибраний елемент у глобальній змінній, використовуючи індекс i.


6
Коли показується клавіатура, відбувається щось дивне. відбувається мультивідбір.
— Рікардо,

1
Це неправильно, оскільки для перегляду списку для економії пам’яті використовуються однакові подання кожних 10 елементів (або, можливо, кожного n елемента, де n більше, ніж кількість елементів, видимих ​​на екрані). Ось чому відбувається мультивідбір.
— marco

13

Спрощений спосіб: якщо ви використовуєте viewview у xml, використовуйте ці атрибути у своєму viewview,

android:choiceMode="singleChoice"
android:listSelector="#your color code"

якщо не використовується xml, програмно

listview.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
listview.setSelector(android.R.color.holo_blue_light);

10
Ти трохи запізнився. Відповідь AJG випереджає вашу дату на рік і є більш повною.
— SMBiggs

5

Вам потрібен такий селектор:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<!-- State when a row is being pressed, but hasn't yet been activated (finger down) -->
<item android:drawable="@color/app_primary_color_light" android:state_pressed="true" />

<!-- Used when the view is "activated". -->
<item android:drawable="@color/app_primary_color" android:state_activated="true" />

<!-- Default, "just hangin' out" state. -->
<item android:drawable="@android:color/transparent" /></selector>

А потім встановіть android:choiceMode="singleChoice"ваш ListView.


Не забудьте додати рядок: android:listselector="@drawable/my_selector"у своєму ListView!
— SMBiggs

Це рішення працює для мене в Android Kitkat 19 Велике спасибі
— DoctorDoom

2

На прикладі Авінаша Кумара Панкаджа

View v;

то при методі oncreate

v = new View(getActivity());

а потім метод onlistitemclick, який я написав

public void onListItemClick(ListView listView, View view, int position,
       long id) {
   v.setBackgroundResource(0);
   view.setBackgroundResource(R.color.green);
   v = view;
}

У мене це спрацювало. Дякую.

Я замінив

v = new View(getActivity());

до

v = new View(this);

і код працював добре.

Необхідні також файли xml "кольори" та "bg_key" з попередніх прикладів, а також атрибут ListView android: background = "@ drawable / bg_key"

Мауро


2

* будь ласка, переконайтеся, що у вашому кореневому макеті списку контейнерів немає Ripple

додати цей рядок до перегляду списку

android:listSelector="@drawable/background_listview"

ось файл "background_listview.xml"

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/white_background" android:state_pressed="true" />
<item android:drawable="@color/primary_color" android:state_focused="false" /></selector>

кольори, використані у файлі background_listview.xml:

<color name="primary_color">#cc7e00</color>
<color name="white_background">#ffffffff</color>

після них

.


1

Одним із способів зробити це є відстеження поточної вибраної позиції у вашій діяльності:

@Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position,
            long arg3) {
        currentPosition = position
        lv_cli.notifyDataSetChanged();
    }

Тепер переконайтеся, що ви присвоїли ідентифікатор батьківському макету (linearLayout, boxLayout, relativeLayout, .. все, що вам подобається) елемента списку.

Тоді у вашому ListView ви можете зробити щось на зразок цього:

layoutBackground = (LinearLayout) convertView.findViewById(R.id.layout_background);

if (YourActivity.this.currentPosition == position) {
    layoutBackground.setBackgroundColor(YourActivity.this.getResources().getColor(R.color.hilight_color));
} else{
    layoutBackground.setBackgroundResource(R.drawable.list_item_drawable);
}

В основному, ви просто встановлюєте кольоровий присвіт на макеті як фон, коли він дорівнює поточній вибраній позиції. Зверніть увагу, як я встановлюю фоновий ресурс, який можна малювати, коли елемент не вибрано. У вашому випадку це може бути інакше (оскільки ви не розмістили жодного коду). У моєму випадку цей малюнок - це селектор, який гарантує, що елемент підсвічується при натисканні.

ПРИМІТКА. У цьому простому коді не використовується переглядач, але я справді рекомендую використовувати його.


0

Замість цього використовуйте ідентифікатор:

Це найпростіший метод, з яким можна впоратися, навіть якщо список довгий:

public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    Holder holder=new Holder();
    View rowView;
    rowView = inflater.inflate(R.layout.list_item, null);
    //Handle your items.
    //StringHolder.mSelectedItem is a public static variable.
    if(getItemId(position)==StringHolder.mSelectedItem){
        rowView.setBackgroundColor(Color.LTGRAY);

    }else{
        rowView.setBackgroundColor(Color.TRANSPARENT);
    }
    return rowView;
}

А потім у своєму onclicklistener:

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            StringHolder.mSelectedItem = catagoryAdapter.getItemId(i-1);
            catagoryAdapter.notifyDataSetChanged();
.....
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.