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: downndantFocusability» мой слушатель кликов не отвечал. То, что я сделал, я изменил все 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
У меня вопрос это баг андроид или это по замыслу?
фанжжж

Я застрял на этом в течение 6 часов, и мне действительно нужна помощь. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/…
Ручир Барония

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 (без blockDescendants)
thpitsch

Это исправляет ошибку, сохраняя при этом кнопки (ToggleButton для меня) кликабельна
Мохсен Afshin

Единственный способ получить GridView с работающим RadioButton - это применить android: downndantFocusability = "blocksDescendants" к LinearLayout, содержащему RadioButton, и установить андроид: clickable = "false" в самом RadioButton.
Стивен Маккормик

Я застрял на этом в течение 6 часов, и мне действительно нужна помощь. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/…
Ручир Барония

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

Установка андроида: downndantFocusability = "blocksDescendants" помогает мне. Спасибо!
LLIAJLbHOu

21.12.16 и после часов поисков ЭТО сработало, спасибо мужик!
Таннер Саммерс

Если у вас такая же компоновка, как у ландшафта и т. Д., Убедитесь, что вы делаете это там же.
Имми

19

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

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

Великий человек, это было действительно полезно!
Дивьянш ингл

это сработало здесь !! У меня есть много флажков в этом представлении, и я пытаюсь android:descendantFocusability="blocksDescendants"и блокирую эти флажки для щелчка
Armando Marques

17

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

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

в моем классе CustomListViewAdapter.

Изменяя это на:

return true;

Мне удалось решить проблему. На всякий случай, если кто-то сделал ту же ошибку ...


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

17

Используйте Android: потомок Фокусируемость

<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
РАДЖЕШ КУМАР АРУМУГАМ

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

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

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, но это было единственное, что работает в моем случае.

Это не идеальное время, но, может быть, это поможет кому-нибудь Счастливое кодирование


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.