Вибраний елемент 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.