OnItemCLickListener ไม่ทำงานใน listview


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

มีปัญหากับการใช้สอง xml ในขณะที่พองตัวหรือไม่?


4
@hiei ปัญหาของฉันคือฉันใช้ imagebuttons ในเซลล์เลย์เอาต์ของฉัน แม้หลังจากเพิ่ม "android: descendantFocusability" ฟังการคลิกของฉันไม่ตอบสนอง สิ่งที่ฉันทำคือฉันเปลี่ยน ImaegButtons เป็น ImageViews ทั้งหมด นั่นช่วยแก้ไขปัญหาของฉัน
Ajith Memana

คำตอบ:


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
นอกจากนี้คุณยังสามารถตั้งค่านี้ programatically กับlistView.setDescendantFocusability(int focus);ที่focusเป็นหนึ่งViewGroup.FOCUS_BEFORE_DESCENDANTS, ViewGroup.FOCUS_AFTER_DESCENDANTSหรือViewGroup.FOCUS_BLOCK_DESCENDANTS
แม็กซ์ worg

ฉันคิดว่ามันตลกดีที่มีคน 20 คนขอบคุณในความคิดเห็น ฉันพบปัญหานี้เป็นเวลา 8 ชั่วโมงที่ผ่านมาขอบคุณมากสำหรับสิ่งนี้
sparticvs

1
คำถามของฉันคือนี่เป็นข้อผิดพลาดของ android หรือโดยการออกแบบ?
fangzhzh

ฉันติดอยู่กับเรื่องนี้เป็นเวลา 6 ชั่วโมงแล้วและฉันต้องการความช่วยเหลือจริงๆ stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/ …
Ruchir Baronia

89

ปัญหาคือเลย์เอาต์ของคุณมีรายการที่สามารถโฟกัสได้หรือคลิกได้ หากมุมมองมีรายการที่โฟกัสหรือคลิกได้ OnItemCLickListener จะไม่ถูกเรียก

คลิกที่นี่สำหรับข้อมูลเพิ่มเติม

โปรดโพสต์หนึ่งในเลย์เอาต์ xml ของคุณหากไม่เป็นเช่นนั้น


2
นี่คือทางออกสำหรับฉันฉันได้ประกาศมุมมองของฉันว่าคลิกได้ ขอบคุณ!
kingraam

1
ขอบคุณ! ผมเปลี่ยน 2 ของฉันEditTextที่จะTextViews และCheckBoxได้รับอนุญาตให้เข้าพัก (และยังคงสลับสามารถ) ด้วยการเพิ่มของฉันandroid:descendantFocusability="blocksDescendants" LinearLayout
Azurespot

ใช่ ฉันมีandroid:focusableInTouchMode="true"สำหรับแถวเมื่อลบมันก็เริ่มทำงานในที่สุด! :-)
SharpC

58

สำหรับรายการของฉันแถวของฉันมีสิ่งอื่น ๆ ที่สามารถคลิกได้เช่นปุ่มการทำผ้าห่มblocksDescendantsไม่ทำงาน แต่ฉันเพิ่มบรรทัดลงใน xml ของปุ่มแทน:

android:focusable="false"

ที่ป้องกันไม่ให้ปุ่มปิดกั้นการคลิกในแถว แต่ก็ยังช่วยให้ปุ่มสามารถทำการคลิกได้


@ user1840899 นี่เป็นคำตอบทั่วไปและอย่างหนึ่งที่ฉันได้เรียนรู้ดังนั้นฉันก็เลยส่งมันต่อ เป็นข้อมูลที่ถูกต้องไม่ควรลงคะแนน
Janene Pappas

สิ่งนี้ใช้ได้กับฉันในกล่องกาเครื่องหมายในรายการมุมมอง (โดยไม่บล็อกบล็อค)
thpitsch

วิธีนี้แก้ไขข้อผิดพลาดขณะที่ยังคงปุ่ม (ToggleButton สำหรับฉัน) ให้คลิกได้
Mohsen Afshin

วิธีเดียวที่ฉันจะได้รับ GridView กับ RadioButtons ในการทำงานคือการใช้ android: descendantFocusability = "blocksDescendants" บน LinearLayout ที่มี RadioButton และโดยการตั้งค่า android: clickable = "false" ใน RadioButton เอง
Stephen McCormick

ฉันติดอยู่กับเรื่องนี้เป็นเวลา 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

การตั้งค่า android: descendantFocusability = "blocksDescendants" ช่วยฉันได้ ขอบคุณ!
LLIAJLbHOu

12/21/16 และหลังจากผ่านไปหลายชั่วโมงของการค้นหาสิ่งนี้ได้ผลขอบคุณมนุษย์
แทนเนอร์ซัมเมอร์ส

หากคุณมีเลย์เอาต์เดียวกันกับภูมิประเทศ ฯลฯ ให้แน่ใจว่าคุณทำที่นั่นเช่นกัน
Immy

19

ใช้รหัสด้านล่างภายในแท็กปุ่มในเค้าโครงแถวที่กำหนดเองของ listview

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

Great Man มันเป็นประโยชน์จริงๆ !!
divyansh ingle

สิ่งนี้ทำงานที่นี่ !! ฉันมีช่องทำเครื่องหมายมากมายในมุมมองนี้และฉันลองandroid:descendantFocusability="blocksDescendants"และปิดกั้นช่องทำเครื่องหมายเพื่อคลิก
Armando Marques Sobrinho

17

ฉันมีปัญหาเดียวกันและฉันเพิ่งเห็นว่าฉันตั้งใจตั้ง:

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

ในคลาส CustomListViewAdapter ของฉัน

โดยการเปลี่ยนเป็น:

return true;

ฉันจัดการเพื่อแก้ไขปัญหา ในกรณีที่มีคนทำผิดพลาดเหมือนกัน ...


7
ฉันก็มี@Override public void onApplicationStart { ExplodeThisDevice(); }
Léon Pelletier

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 ดีขึ้น
Killer

สิ่งนี้ใช้งานได้สำหรับฉันและปุ่มของฉันในองค์ประกอบรายการยังคงทำงานตามที่ตั้งใจไว้
กุสตาฟ Eriksson

11

ฉันแก้ไขมันด้วยความช่วยเหลือของคำตอบนี้

1. เพิ่มข้อมูลต่อไปนี้ใน Linear Layout ของ list_items.xml android:descendantFocusability="blocksDescendants"

2.Child Views ของ LinearLayout ใน list_items.xml

 android:focusable="false" 

ลิงก์ของคุณเสีย
Jason C

1
@ JasonC ขอบคุณสำหรับข้อมูลของคุณ นี่คือลิงค์stackoverflow.com/a/14915758/5740760
RAJESH KUMAR ARUMUGAM

10

หากคุณมี textviews ปุ่มหรือ stg คลิกหรือเลือกได้ในมุมมองแถวของคุณเท่านั้น

android:descendantFocusability="blocksDescendants"

ไม่พอ. คุณต้องตั้งค่า

android:textIsSelectable="false"

ไปที่ textviews ของคุณและ

android:focusable="false"

ที่ปุ่มและรายการที่สามารถโฟกัสได้อื่น ๆ


ฉันเรียนรู้วิธีนี้อย่างหนัก android: textIsSelectable = "false" คอยดูสิ่งนี้ :)
diyoda_

10

แม้ว่าฉันจะมีปัญหาเดียวกันฉันมีช่องทำเครื่องหมายต่อไปนี้เพื่อ masker 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 แต่มันเป็นสิ่งเดียวที่ใช้ได้ในกรณีของฉัน

มันไม่ใช่เวลาที่สมบูรณ์แบบ แต่บางทีมันอาจช่วยให้ใครบางคนมีความสุขในการเขียนโปรแกรม


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

ฉันมีปัญหาเดียวกันฉันใช้สไตล์สำหรับข้อความของฉันในเค้าโครงแถวที่มีคุณลักษณะ "โฟกัสได้" มันทำงานหลังจากที่ฉันลบมัน




0

หากคุณต้องการใช้ทั้งการคลิกแบบง่ายและการคลิกแบบยาวบนไอเท็มมุมมองรายการวิธีที่ดีกว่าในการนำไปใช้นั้นจะเป็นการใช้เมนูบริบทสำหรับการคลิกแบบยาว หลีกเลี่ยงการใช้ setItemLongClickListener โดยเฉพาะถ้าคุณมีเค้าโครงแถวหลายแถวสำหรับ listview ของคุณ


0

ประสบปัญหาเดียวกันพยายามเป็นเวลาหลายชั่วโมง หากคุณลองทำตามข้างบนทั้งหมดแล้วลองเปลี่ยน layout_width ของ Listview และ list list เป็น 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 ()ก่อนแนบไปยัง listview

คัดลอกมาจาก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
            }

        });

ฉันได้รับคำตอบจากที่นี่ !


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.