Android ListView OnItemClickListener 没有捕捉到内部项目点击事件

Posted

技术标签:

【中文标题】Android ListView OnItemClickListener 没有捕捉到内部项目点击事件【英文标题】:Android ListView's OnItemClickListener did not catch inner item's click event 【发布时间】:2021-07-05 01:51:44 【问题描述】:

在我的列表视图中,有很多组件。我想点击的一个组件是名为 kickOutBtn 的 ImageButton。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_
    android:layout_
    android:id="@+id/drawer_pane"
    android:paddingVertical="6dp"
    android:descendantFocusability="blocksDescendants"
    android:paddingHorizontal="28dp">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/profile_image"
        android:layout_
        android:layout_
        android:layout_centerVertical="true"
        android:background="@color/colorGray"/>

    <TextView
        android:id="@+id/profile_name"
        android:layout_
        android:layout_
        android:maxLines="1"
        android:text="nickname"
        android:layout_centerVertical="true"
        android:layout_marginLeft="8dp"
        android:layout_toRightOf="@id/profile_image"
        android:textColor="@color/colorBlack"
        android:textSize="10dp"/>

    <RelativeLayout
        android:id="@+id/fake_click_layout"
        android:layout_
        android:layout_
        android:clickable="false"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true">

    <TextView
        android:id="@+id/owner"
        android:layout_
        android:layout_
        android:maxLines="1"
        android:text="manager"
        android:layout_centerInParent="true"
        android:textColor="@color/colorBlack"
        android:textSize="10dp"/>

    <ImageButton
        android:id="@+id/kickOutBtn"
        android:layout_
        android:layout_
        android:padding="4dp"
        android:visibility="invisible"
        android:scaleType="fitCenter"
        android:background="@color/colorTransparent"
        android:tint="@color/colorBlack"
        android:src="@drawable/ic_baseline_close_24"/>
    </RelativeLayout>


</RelativeLayout>

它们在视图中的相同位置。

我的意思是,Textview 位于 ImageButton 的中心。

如果 ListView 项的目标是经理,我想让其列表项的 ImageButton 不可见并打开显示经理的 Textview,如果不是,我想让其列表项的 ImageButton 显示相反,我想使所有者 Textview 不可见。 (默认是imagebutton不可见,textview可见)

为此,我尝试了这段代码。

// ListAdapter中的getView

@Override
    public View getView(int i, View convertView, ViewGroup viewGroup) 
        View view;

        if (convertView == null) 
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.navi_list_menu_item, null);
         else 
            view = convertView;
        

        ImageButton kick_btn = (ImageButton) view.findViewById(R.id.kickOutBtn);
        TextView supervisor_tv = (TextView) view.findViewById(R.id.owner);

        if (roomSupervisor.equals(mNavItems.get(i).fb_uid)) 
            kick_btn.setVisibility(View.INVISIBLE);
         else 
            supervisor_tv.setVisibility(View.INVISIBLE);
            if (roomSupervisor.equals(SessionInfo.fb_uid)) 
                kick_btn.setVisibility(View.VISIBLE);
             else 
                kick_btn.setVisibility(View.INVISIBLE);
            
        

        return view;
    

// Activity中的OnItemClickListener

private AdapterView.OnItemClickListener onItemClickListener = (adapterView, view, i, l) -> 
        if(view.getId() == R.id.kickOutBtn) 
            Log.d(TAG, "kick");
            popupDialog(i);
         else 
            Log.d(TAG, i + "is pushed");
        
    ;

在这种情况下,kick ImageButton 是不可点击的……(列表行的点击事件执行良好)

每当我单击该按钮时,Activity 中的 onItemClickListener 都没有响应...

我该怎么办...?

【问题讨论】:

你能发布适配器的完整代码吗? 尝试将supervisor_tv.setVisibility(View.INVISIBLE);更改为supervisor_tv.setVisibility(View.GONE); 【参考方案1】:

所以您的活动实现了 OnItemClickListener。然后,您还需要将点击侦听器设置为您的活动。你做到了吗?

mListView.setOnItemClickListener(activity)

【讨论】:

我也是这样做的。 mDrawerList.setOnItemClickListener(onItemClickListener); mDrawerList 是一个 ListView! 哦,我刚刚将 OnItemClickListener 初始化为变量@Leo Lamas【参考方案2】:

你可以像这样在你的适配器中设置监听器:

if (roomSupervisor.equals(mNavItems.get(i).fb_uid)) 
        kick_btn.setVisibility(View.INVISIBLE);
     else 
        supervisor_tv.setVisibility(View.INVISIBLE);
        if (roomSupervisor.equals(SessionInfo.fb_uid)) 
            kick_btn.setVisibility(View.VISIBLE);
         else 
            kick_btn.setVisibility(View.INVISIBLE);
        
    
 kick_btn.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            // do what you want here
        
    );

【讨论】:

【参考方案3】:

由于建议使用RecyclerView 而不是ListView,所以我使用RecyclerView 来解决您的问题。 我创建了一个数据类,将在RecyclerView 的项目视图中使用。

数据类

 class Item 
    String nickName;
    boolean isManager;
    Item(String nickName, boolean isManager)
        this.nickName = nickName;
        this.isManager = isManager;
    
  

回收站视图适配器

    static class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder>
    List<Item> items;

    RecyclerAdapter(List<Item> itemList)
        items = itemList;
    

    @NonNull
    @Override
    public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
        return new RecyclerViewHolder(view);
    

    @Override
    public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) 
        if (items.get(position).isManager)
            holder.owner.setVisibility(View.VISIBLE);
            holder.kickBtn.setVisibility(View.INVISIBLE);
        else 
            holder.owner.setVisibility(View.INVISIBLE);
            holder.kickBtn.setVisibility(View.VISIBLE);
        
        holder.bind(items.get(position));
    

    @Override
    public int getItemCount() 
        return items.size();
    

    class RecyclerViewHolder extends RecyclerView.ViewHolder
        TextView owner;
        ImageButton kickBtn;
        TextView profileView;
        RecyclerViewHolder(View view)
            super(view);
            profileView = view.findViewById(R.id.profile_name);
            owner = view.findViewById(R.id.owner);
            kickBtn = view.findViewById(R.id.kickOutBtn);
            owner.setOnClickListener(v -> 
                items.get(getAdapterPosition()).isManager = false;
                notifyItemChanged(getAdapterPosition());
            );
            kickBtn.setOnClickListener(v ->
                items.get(getAdapterPosition()).isManager = true;
                notifyItemChanged(getAdapterPosition());
            );
        
        void bind(Item item)
            profileView.setText(item.nickName);
        
    

Recycler View 的 xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <androidx.recyclerview.widget.RecyclerView
        android:layout_
        android:layout_
        android:id="@+id/list_view"
        tools:listitem="@layout/list_item"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

最后,将适配器设置为 Recycler View,如下所示:

   RecyclerView recyclerView = root.findViewById(R.id.list_view);
 // Just creating sample list for testing . You could customize your data class as per your requirement.
    List<Item> items = new ArrayList<>();
    items.add(new Item("Choco",true));
    items.add(new Item("Nrusingha",false));
    items.add(new Item("Barbie",true));
    items.add(new Item("Uttam",false));
    items.add(new Item("Smruti",false));
    items.add(new Item("Choco",true));
    items.add(new Item("Nrusingha",true));
    items.add(new Item("Barbie",true));
    items.add(new Item("Uttam",false));
    items.add(new Item("Smruti",true));
    RecyclerAdapter recyclerAdapter = new RecyclerAdapter(items);


    recyclerView.setAdapter(recyclerAdapter);

【讨论】:

以上是关于Android ListView OnItemClickListener 没有捕捉到内部项目点击事件的主要内容,如果未能解决你的问题,请参考以下文章

Android——listview android:cacheColorHint,android:listSelector属性作用

38.Android之ListView简单学习

Android listview 的用法? 越详细越好。

Android——ListView

ListView / SimpleAdapter 不刷新 - Android

android 怎么让listview 不够一屏 占满一屏