OnItemCLickListenerがリストビューで機能しない


242

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);
    }
}

膨張中に2つのxmlを使用することに問題はありますか?


4
@hiei私の問題は、レイアウトセルでimagebuttonsを使用していたことでした。「android:descendantFocusability」を追加した後でも、クリックリスナーが応答しませんでした。私がしたことは、すべてのImaegButtonsをImageViewsに変更したことです。それで私の問題は解決しました。
Ajith Memana 2015年

回答:


730

私はここから解決策を見つけましたが、深くクリックしました。

リストの行項目にフォーカス可能なビューまたはクリック可能なビューが含まれている場合、機能しOnItemClickListenerません。

行アイテムにはのようなパラメータが必要 android:descendantFocusability = "blocksDescendants"です。

ここでは、リストアイテムの例を確認できます。リストアイテムのxmlは... row_item.xmlyour_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_DESCENDANTSViewGroup.FOCUS_AFTER_DESCENDANTSまたはViewGroup.FOCUS_BLOCK_DESCENDANTS
Max Worg

これは面白いと思います。20人ほどがコメントであなたに感謝したようです。私は過去8時間この問題に遭遇してきました。これに感謝します。
sparticvs 2015

1
私の質問は、これはアンドロイドのバグですか、それとも設計によるものですか?
fangzhzh 2015年

私はこれで6時間もこだわっていて、本当に助けが必要です。stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/...
Ruchir Baronia

89

問題は、レイアウトにフォーカス可能なアイテムまたはクリック可能なアイテムが含まれていることです。ビューにフォーカス可能またはクリック可能なアイテムが含まれている場合、OnItemCLickListenerは呼び出されません。

クリックここで詳細は。

そうでない場合は、レイアウトxmlの1つを投稿してください。


2
これが私の解決策でした。私は自分の見解をクリック可能であると宣言しました。ありがとう!
kingraam

1
ありがとう!私は2 EditText秒をTextViews に変更し、CheckBoxをにandroid:descendantFocusability="blocksDescendants"追加したままにしておくことができました(切り替え可能なままです)LinearLayout
Azurespot 2016年

はい!私はandroid:focusableInTouchMode="true"列のために持っていました、削除されるとそれはついに動作し始めました!:-)
SharpC 2016

58

私のリストでは、ボタンのように、クリックできる他のものが行にあるため、毛布を実行blocksDescendantsしても機能しません。代わりに、ボタンのxmlに行を追加しました。

android:focusable="false"

これにより、ボタンが行のクリックをブロックするのを防ぎますが、ボタンはクリックを受け付けます。


@ user1840899これは一般的な応答であり、私が学んだものなので、引き継ぎました。これは正しい情報であり、反対票を投じる価値はありません。
Janene Pappas 2013

これは、ListViewアイテムのチェックボックス(blockDescendantsなし)で機能します
thpitsch

これにより、ボタン(私にとってはToggleButton)をクリック可能にしたまま、バグが修正されます
Mohsen Afshin 2013

RadioButtonが含まれるGridViewを機能させる唯一の方法は、RadioButtonを含むLinearLayoutにandroid:descendantFocusability = "blocksDescendants"を適用し、RadioButton自体にandroid:clickable = "false"を設定することでした。
Stephen McCormick

私はこれで6時間もこだわっていて、本当に助けが必要です。stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/...
Ruchir Baronia

34

listview_item.xmlで2つのステップを実行する必要があります

  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 '15

android:descendantFocusability = "blocksDescendants"を設定すると役立ちます。ありがとう!
LLIAJLbHOu

12/21/16、そして何時間もの検索の後、これはうまくいきました、ありがとうございます!
Tanner Summers 2016

ランドスケープなどと同じレイアウトの場合は、そこにも配置するようにしてください。
2018年

19

リストビューのカスタム行レイアウトのボタンタグ内で以下のコードを使用します

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

グレートマンは本当に役に立ちました!!
divyansh ingle 2017

これはここで働いた!! このビューには多くのチェックandroid:descendantFocusability="blocksDescendants"ボックスがあり、クリックのためにこれらのチェックボックスを試してブロックします
Armando Marques Sobrinho

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になる場合があります。
キラー

これは私にとっては機能し、リスト要素の私のボタンはまだ意図したとおりに機能しました。
グスタフエリクソン2018年


10

行ビューのみでテキストビュー、ボタン、またはstgをクリックまたは選択できる場合

android:descendantFocusability="blocksDescendants"

十分ではありません。設定する必要があります

android:textIsSelectable="false"

あなたのtextviewsに

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. onClickを持つすべてのボタン、Textview、ImageViewなどにこのコードを書き込みます

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

それがうまくいくことを願っています。


3

2つの素晴らしい解決策はこれでした。フラグメントから拡張した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レイアウトプロパティはどれも役に立ちませんでした。

次のようなコードを1行追加するだけです 。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

同じ問題がありました。「focusable」属性を持つ行レイアウトのテキストにスタイルを使用していました。私がそれを削除した後にそれは働いた。




0

リストビューアイテムでシンプルクリックとロングクリックの両方を使用したい場合は、ロングクリックのコンテキストメニューを使用することをお勧めします。リストビューに複数の行レイアウトがある場合は特に、setItemLongClickListenerの使用を避けてください。


0

同じ問題に直面し、何時間も試してみました。上記のすべてを試した場合は、Listviewのレイアウト幅とリストアイテムをwrap_contentからmatch_parentに変更してみてください。


0

上記のすべてが私にとって失敗しました。しかし、私は問題を解決することができました(何時間も頭を叩いた後-Google、聞いている場合は、可能であれば、コンパイラエラーの形式で以下に遭遇したものを修正することを検討してください)

ここでxmlレイアウトに追加するandroid属性に注意する必要があります(この元の質問では、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>

そして、これは私のFragmentサブクラスのsetOnItemClickListener呼び出しです。

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

リストからクリック可能なビューを削除して問題を解決しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.