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, если это не так.

balazsbalazs
источник
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"

на ваши кнопки и другие фокусируемые предметы.

savepopulation
источник
Я научился этому нелегко. 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"

надеюсь, это поможет тому, кто застрял как я.

u2tall
источник
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...
        }

    });
AndreasReiff
источник
1

У меня была та же проблема, я использовал стиль для своих текстов в макете строки, который имел атрибут «фокусируемый». Это сработало после того, как я его убрал.

Мигель Рдз
источник
1

В моем случае мне пришлось удалить следующую строку из Layout

android:clickable="true"
IgniteCoders
источник
1

Android: атрибут autoText также делает TextView автоматически фокусируемым.

Юрий Финченко
источник
0

Если вы хотите использовать как простой щелчок, так и длительный клик по элементам представления списка, лучший способ реализовать это - использовать контекстное меню для длинного клика. Избегайте использования setItemLongClickListener, особенно если у вас есть несколько рядов макетов для вашего списка.

Сэмюэл Роберт
источник
0

Столкнулся с той же проблемой, пытался часами. Если вы попробовали все вышеперечисленное, попробуйте изменить layout_width для Listview и элемента списка на match_parent из wrap_content.

Prashant
источник
0

Все вышеперечисленное не удалось для меня. Тем не менее, я смог решить проблему (после многих часов ударов головой - Google, если вы слушаете, пожалуйста, по возможности исправьте то, с чем я столкнулся ниже, в форме ошибок компилятора)

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

Ted_Zactly
источник
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
            }

        });

Я получил ответ отсюда !

spcarlin
источник
-1

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

sidKhalid
источник