OnItemCLickListener не працює в перегляді списку


243

Activity код класу:

conversationList = (ListView)findViewById(android.R.id.list);
ConversationArrayAdapter conversationArrayAdapter=new  ConversationArrayAdapter(this, R.layout.conversation_list_item_format_left, conversationDetails);
conversationList.setAdapter(conversationArrayAdapter);
conversationList.setOnItemClickListener(new AdapterView.OnItemClickListener(){ 
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
        Log.d("test","clicked");
    }
});

getViewФункція в Adapterкласі:

if (v == null) {                                
    LayoutInflater vi = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if(leftSideMessageNumber.equals(m.getTo())) {
        v = vi.inflate(R.layout.conversation_list_item_format_left, null);
    } else {
        v = vi.inflate(R.layout.conversation_list_item_format_right, null);
    }
}

Чи є проблема із використанням двох xmls при надуванні?


4
@hiei Моя проблема полягала в тому, що я використовував кнопки зображення в клітинках макета. Навіть після додавання "android: descendantFocusability" мій слухач кліків не відповідав. Що я і робив, я змінив усі ImaegButtons на ImageViews. Це вирішило мою проблему.
Аджіт Мемана

Відповіді:


731

Я просто знайшов рішення звідси, але глибоким клацанням.

Якщо будь-який рядок у списку містить перегляд, який можна орієнтувати або натискати, він OnItemClickListenerне працює.

Елемент рядка повинен мати параметр на зразок android:descendantFocusability = "blocksDescendants".

Тут ви можете побачити приклад того, як повинен виглядати елемент вашого списку. Елемент списку xml має бути ... row_item.xml( your_xml_file.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:baselineAligned="false"
    android:descendantFocusability="blocksDescendants"
    android:gravity="center_vertical" >

    // your other widgets here

</LinearLayout>

не працює для мене. Може хто - небудь поглянути на [ stackoverflow.com/questions/21692209 / ...
suitianshi

3
Ви також можете встановити це програмно з тим, listView.setDescendantFocusability(int focus);де focusзнаходиться один ViewGroup.FOCUS_BEFORE_DESCENDANTS, ViewGroup.FOCUS_AFTER_DESCENDANTSабоViewGroup.FOCUS_BLOCK_DESCENDANTS
Макс Ворг,

Я думаю, що це смішно, що як 20 людей подякували вам у коментарі. Я зіткнувся з цією проблемою протягом останніх 8 годин, тому дуже дякую за це.
sparticvs

1
Моє запитання: це андроїд-помилка чи це дизайн?
fangzhzh

Я затримався на цьому вже 6 годин, і мені дуже потрібна допомога. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item / ...
Ruchir Baronia

89

Проблема полягає в тому, що у ваших макетах містяться елементи, що орієнтуються або можна натискати. Якщо представлення містить елемент, що фокусується, або його можна натискати, OnItemCLickListener не буде викликаний.

Клацніть тут для отримання додаткової інформації.

Будь ласка, опублікуйте один із ваших макетів xmls, якщо це не так.


2
Це було вирішенням для мене, я заявив, що мій погляд є доступним. Дякую!
kingraam

1
Дякую! Я змінив свої 2 EditTextс на TextViewс, і CheckBoxдозволено залишатися (і залишатися можливим переключенням) із android:descendantFocusability="blocksDescendants"доданим до мого LinearLayout.
Azurespot

Так! У мене був android:focusableInTouchMode="true"за рядок, як тільки його зняли, він почав працювати нарешті! :-)
SharpC

58

У моїх списках у моїх рядках є інші речі, які можна натискати, як-от кнопки, тому робити ковдру blocksDescendantsне працює. Натомість я додав рядок у xml кнопки:

android:focusable="false"

Це запобігає блокуванню кнопок у рядках, але все ж дозволяє кнопкам здійснювати кліки.


@ user1840899 Це звичайна відповідь, і я навчився цього, тому я передав її далі. Це правильна інформація, не гідна голосування.
Джейн Паппас

Це працює для мене на CheckBox у елементах ListView (без блоківDescendants)
thpitsch

Це виправляє помилку, зберігаючи кнопки (ToggleButton для мене) натискання
Mohsen Afshin

Єдиний спосіб, коли я міг отримати GridView з RadioButtons в ньому, це застосувати android: descendantFocusability = "блокиDescendants" на LinearLayout, що містить RadioButton, та встановивши android: clickable = "false" у самій RadioButton.
Стівен Маккормік

Я затримався на цьому вже 6 годин, і мені дуже потрібна допомога. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item / ...
Ruchir Baronia

34

вам потрібно зробити 2 кроки у списку listview_item.xml

  1. встановити кореневий макет за допомогою: android:descendantFocusability="blocksDescendants"
  2. встановіть у цьому елементі будь-який фокусируемый або натискання
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false"

Ось приклад: listview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:gravity="center_vertical"
    android:orientation="vertical"
    android:descendantFocusability="blocksDescendants">

    <RadioButton
        android:id="@+id/script_name_radio_btn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textColor="#000"
        android:padding="5dp"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        />

</LinearLayout>

Якщо встановити clickable="trueна панелі перегляду, елемент onItemClickне викликає. Тож зверніть увагу на те, щоб також додати clickable="false"до елемента кореневого перегляду елемента, у цьому випадку цеLinearLayout
vovahost

Налаштування андроїда: descendantFocusability = "блокиDescendants" допомагає мені. Дякую!
LLIAJLbHOu

21.12.16, а після годин пошуків ЦЕ спрацювало, дякую людино!
Таннер Саммерс

Якщо у вас такий же макет, як у пейзажу тощо, переконайтеся, що ви це робите і там.
Іммі

19

використовуйте наведений нижче код всередині тегу кнопок у власному макеті рядків перегляду списку

 android:focusable="false"
 android:clickable="false"

Велика Людина це була дійсно корисна !!
divyansh ingle

це працювало тут !! У мене в цьому представленні багато прапорців, і я намагаюсь android:descendantFocusability="blocksDescendants"і заблокувати ці прапорці для натискання
Армандо Маркес Собріньо

17

У мене була така ж проблема, і я щойно побачив, що випадково встановив:

@Override
public boolean isEnabled(int position)
{
    return false;
}

в моєму класі CustomListViewAdapter.

Змінивши це на:

return true;

Мені вдалося виправити проблему. Про всяк випадок, якщо хтось зробив ту саму помилку ...


7
У мене теж був@Override public void onApplicationStart { ExplodeThisDevice(); }
Леон Пелтьє,

17

Використовуйте android: descendantFocusability

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dip"
    android:background="@color/light_green"
    android:descendantFocusability="blocksDescendants" >

Додайте вище в кореневу компонування


2
Додавання деталей може полегшити відповідь та поставити +1.
Вбивця

Це працювало для мене, і моя кнопка в елементі списку все ще працювала за призначенням.
Густав Ерікссон

11

Я вирішив це за допомогою цієї відповіді

1.Додайте наступне у лінійному макеті list_items.xml android:descendantFocusability="blocksDescendants"

2.Діти перегляду LinearLayout у list_items.xml

 android:focusable="false" 

Ваше посилання розірвано.
Джейсон C

1
@JasonC Дякую за вашу інформацію Ось посилання stackoverflow.com/a/14915758/5740760
RAJESH KUMAR Арумугі

10

якщо у режимі перегляду рядків у вас є лише перегляд тексту, кнопки або stg, які можна натискати або вибирати

android:descendantFocusability="blocksDescendants"

недостатньо. Ви повинні встановити

android:textIsSelectable="false"

до ваших текстових переглядів та

android:focusable="false"

до ваших кнопок та інших об'єктів, що фокусуються.


Я навчився цього важким шляхом. android: textIsSelectable = "false" Слідкуйте за цим :)
diyoda_

10

Навіть у мене була така ж проблема, я маю прапорець, зробив наступне, щоб працювати маскувач itemClickListener,

Додані наступні властивості у прапорець,

android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"

і ItemClickListner почали працювати.

Для детального прикладу ви можете перейти за посиланням,

http://knowledge-cess.com/android-itemclicklistner-with-checkbox-or-radiobutton/

Сподіваюся, це допомагає ура!


5

У мене була та сама проблема, і я спробував усі згадані рішення безрезультатно. Через тестування я виявив, що вибір тексту вибирає заважає слухачеві викликати. Тож переключивши його на помилкове або видаливши його, мого слухача знову викликали.

android:textIsSelectable="false"

сподіваюся, що це допоможе тому, хто застряг, як я.


4
  1. Додайте це в основний макет

    android:descendantFocusability="blocksDescendants"
  2. Введіть цей код у кожну кнопку, Textview, ImageView тощо, які мають onClick

    android:focusable="false"
    
    android:clickable="false"

Сподіваюся, це спрацює.


3

Два дивовижні рішення полягали в цьому: якщо ваш розширюваний ListFragment з фрагмента знає, що mListView.setOnItemClickListenerне буде викликано раніше, ніж буде створена ваша діяльність, це забезпечить її встановлення, коли діяльність створена

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mListView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long rowId) {
            // Do the onItemClick action

            Log.d("ROWSELECT", "" + rowId);
        }
    });
}

Переглядаючи вихідний код для ListFragment, я натрапив на це

public class ListFragment extends Fragment {
    ...........................................
    ................................................

    final private AdapterView.OnItemClickListener mOnClickListener
                = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            onListItemClick((ListView)parent, v, position, id);
        }
    };

    ................................................................
    ................................................................

    public void onListItemClick(ListView l, View v, int position, long id) {
    }
}

onItemClickListenerОб'єкт приєднаний , і він викликає onListItemClick() як такого іншого аналогічного рішення, яке працює в точно так же, щоб перевизначитиonListItemClick()

@Override
public void onListItemClick(ListView l, View v, int position, long rowId) {
    super.onListItemClick(l, v, position, id);
   // Do the onItemClick action

   Log.d("ROWSELECT", "" + rowId);
} 

3

в моєму випадку жодна з властивостей макета xml не була корисною.

Я просто додаю такий рядок коду, як це: convertView.setClickable (false);

@NonNull
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
    ViewHolder viewHolder;
    if (convertView == null || convertView.getTag() == null) {
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(R.layout.my_layout_id, parent, false);
        viewHolder = new ViewHolder(convertView);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    ...
    convertView.setClickable(false);
    return convertView;
}

так що в основному це робиться те саме, що і налаштування властивостей у форматі XML, але в моєму випадку це було єдине, що працює.

Це не ідеальні терміни, але, можливо, це допоможе комусь Happy кодування


1

Я спробував усе вищесказане, і НІЧОГО не працювало.

Я вирішив проблему так:

Спочатку я визначаю користувацьку кнопку під назвою ListButton

public class ListButton extends android.widget.Button
{

private ButtonClickedListener clickListener;

public ListButton(Context context)
{
    this(context, null);
}

public ListButton(Context context, AttributeSet attrs)
{
    this(context, attrs, 0);
}

public ListButton(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);
}

public void setClickListener(ButtonClickedListener listener) {
    this.clickListener = listener;
}

@Override
public boolean isInTouchMode() {
    return true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    return false;
}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    switch (event.getAction()) 
      {
          case MotionEvent.ACTION_DOWN:
              break;
          case MotionEvent.ACTION_UP:

              eventClicked();

              break;
          case MotionEvent.ACTION_CANCEL:
              break;
          case MotionEvent.ACTION_MOVE:
              break;
          default :

      }
    return true;
}

private void eventClicked() {
    if (this.clickListener!=null) {
        this.clickListener.ButtonClicked();
    }
}

}

XML виглядає так:

<dk.example.views.ListButton
android:id="@+id/cancel_button"
android:layout_width="125dp"
android:layout_height="80dp"
android:text="Cancel"
android:textSize="20sp" 
android:layout_margin="10dp"
android:padding="2dp"
android:background="#000000"
android:textColor="#ffffff"
android:textStyle="bold"  
/>

Тоді я визначаю власний ButtonClickedінтерфейс слухача:

public interface ButtonClickedListener {
    public void ButtonClicked();
}

Тоді я використовую власного слухача так, ніби це нормально OnClickListener:

final ListButton cancelButton = (ListButton) viewLayout.findViewById(R.id.cancel_button);

    cancelButton.setClickListener(new ButtonClickedListener() {

        @Override
        public void ButtonClicked() {
            //Do your own stuff here...
        }

    });

1

У мене був той самий випуск, я використовував стиль для своїх текстів у макеті рядків, який мав атрибут "фокусуваність". Це спрацювало після того, як я його зняв.


1

У моєму випадку мені довелося видалити наступний рядок із Layout

android:clickable="true"


0

Якщо ви хочете скористатися як простим клацанням, так і довгим клацанням на пунктах перегляду списку, кращим способом реалізації цього буде використання контекстного меню для довгого натискання. Уникайте використання setItemLongClickListener, особливо якщо для перегляду списку є кілька макетів рядків.


0

Зіткнувся з тією ж проблемою, намагався годинами. Якщо ви спробували все вищезазначене, ніж спробуйте змінити layout_width Listview і елемента списку на match_parent від wrap_content.


0

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

Ви дійсно повинні бути обережними, які атрибути Android ви додаєте до свого xml-макета тут (у цьому оригінальному запитанні він називається list_items.xml). Для мене причиною проблеми було те, що я перейшов з перегляду EditText в TextView і мав залишковий атрибут атрибуту від зміни (в моєму випадку inputType). Компілятор не впіймав цього, а можливість натискання просто не вдалося, коли я пішов запускати додаток. Двічі перевірте всі атрибути, які є у вашому макеті xml-вузлів.


0
private AdapterView.OnItemClickListener onItemClickListener;

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
 .......

final View view = convertView;
convertView.setOnClickListener(new View.OnClickListener() {
    @Override
     public void onClick(View v) {
         if (onItemClickListener != null) {
             onItemClickListener.onItemClick(null, view, position, -1);
         }
      }
 });

return convertView;
}

public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
    this.onItemClickListener = onItemClickListener;
}

Потім у своїй діяльності використовуйте adapter.setOnItemClickListener () перед тим, як приєднати його до перегляду списку.

Скопійовано з github його працювало на мене


0

Для мене працювало те, щоб додати наведений нижче код до кожного підпогляду всередині макета мого файлу row.xml:

android:focusable="false"
android:focusableInTouchMode="false"

Тож у моєму випадку:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/testingId"
        android:text="Name"
       //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/dummyId"
        android:text="icon"
        //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/assignmentColor"
       //other stuff 
       />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/testID"
        //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text="TextView"
        //other stuff 
        />

</android.support.constraint.ConstraintLayout>

І це мій виклик setOnItemClickListener в моєму підкласі Fragment:

CustomListView = (PullToRefreshListCustomView) layout.findViewById(getListResourceID());
        CustomListView.setAdapter(customAdapter);
        CustomListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d("Testing", "onitem click working");
              //  other code
            }

        });

Я отримав відповідь звідси !


-1

Я вирішив проблему, видаливши зі списку перегляди, які можна натиснути.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.