【问题标题】:Expandable List view with recycler list view as child以回收者列表视图为子项的可扩展列表视图
【发布时间】:2017-07-17 09:06:50
【问题描述】:

如图所示,我可以渲染视图。但是 Expandable 视图的 onChildClick 事件没有被触发。

适配器中的触摸事件也没有响应。我的布局细节如下。

完整的源代码可以在here找到。

main_activity.xml

<ExpandableListView
    android:id="@+id/list_brands"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@null"
    android:groupIndicator="@null"
    android:dividerHeight="5dp" />

item_parent.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/text_brand"
        android:textSize="18dp"
        android:text="Text"
        android:layout_weight="1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ImageView
        android:id="@+id/image_indicator"
        android:src="@drawable/ic_keyboard_arrow_down_black_18dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

item_group_child.xml

<android.support.v7.widget.RecyclerViewxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mobiles"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

item_child.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp">

        <ImageView
            android:id="@+id/image_mobile"
            android:layout_width="70dp"
            android:adjustViewBounds="true"
            android:layout_height="120dp" />


        <TextView
            android:id="@+id/text_mobile_model"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center" />

        <TextView
            android:id="@+id/text_mobile_price"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center" />

</LinearLayout>

**我的解决方案:** 触摸事件直接传递给 Recycler List 视图中 View holder 的 UI Elements。但是为了给整个布局提供触摸事件,我在 child_item 布局顶部添加了透明按钮并添加了一个点击监听器。以下是更新后的 child_item.xml

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_width="match_parent" >

        <Button
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/dummy_click"
            android:background="@android:color/transparent"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:padding="10dp"

            android:background="@color/colorGrey"
            >
        <ImageView
            android:id="@+id/img_subcategory"
            android:layout_gravity="center"
            android:src="@mipmap/ic_launcher"
            android:layout_marginTop="10dp"
            android:layout_width="180dp"
            android:layout_height="90dp"

            android:scaleType="fitXY"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Sub Category"
            android:textColor="@color/colorWhite"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="5dp"
            android:gravity="center"
            android:id="@+id/txt_subcategory"
            android:textSize="@dimen/app_text_title"/>

        </LinearLayout>
        </FrameLayout>
    </LinearLayout>

【问题讨论】:

    标签: android expandablelistview expandablerecyclerview


    【解决方案1】:

    理论

    ExpandableListView, child click 样本:

    点击孩子,可以这样处理。

    getExpandableListView().setOnChildClickListener(new OnChildClickListener() {              
        public boolean onChildClick(ExpandableListView parent, View v,
                    int groupPosition, int childPosition, long id) { 
            // your code...
        }
    });
    

    可扩展的RecyclerView,有用的library 和简单的item click support

    Hugo 的这篇博文展示了一种没有听众的替代方法: http://www.littlerobots.nl/blog/Handle-Android-RecyclerView-Clicks/

    归结为添加以下几行:

    ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
        @Override
        public void onItemClicked(RecyclerView recyclerView, int position, View v) {
            // do it
        }
    });
    

    当使用这个类时:

    public class ItemClickSupport {...}
    

    以及 ids.xml 中的这个值:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <item name="item_click_support" type="id" />
    </resources>
    

    Why doesn't RecyclerView have onItemClickListener()? And how RecyclerView is different from Listview?

    自从引入ListView以来,onItemClickListener 有问题的。当您拥有任何一个点击监听器时 不会触发回调的内部元素,但不是 通知或有据可查(如果有的话),所以有很多 困惑和关于它的问题。

    OnItemClickListener doesn't work with ListView item containing button

    只需将此行添加到项目视图中,而不是 listView 本身

    android:focusable="false"

    查看更多详情,请访问:Android custom ListView unable to click on items


    练习

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    
        ChildHolder childHolder = null;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.item_group_child, parent, false);
            childHolder = new ChildHolder();
    
            // Fix listview onclicklistener issue: inner views can not be focusable
            childHolder.YOUR_INNER_BUTTON = (YOUR_BUTTON_TYPE) convertView.findViewById(R.id.YOUR_BUTTON_ID);
            childHolder.YOUR_INNER_BUTTON.setFocusable(false);
    
            convertView.setTag(childHolder);
        }
        else {
            childHolder = (ChildHolder) convertView.getTag();
        }
    
        childHolder.horizontalListView = (RecyclerView) convertView.findViewById(R.id.mobiles);
        LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
        childHolder.horizontalListView.setLayoutManager(layoutManager);
    
        MobileAdapter horizontalListAdapter = new MobileAdapter(context, brands.get(groupPosition).mobiles);
        childHolder.horizontalListView.setAdapter(horizontalListAdapter);
    
        return convertView;
    }
    

    根据我的legacy code 在您的代码中添加了两行:

        // Creates a ViewHolder and store references to the children views (collapsed)
        holder = new ViewHolderChildren();
        holder.textLine = (TextView) convertView.findViewById(R.id.usersTextLine);
        holder.subtextLine = (TextView) convertView.findViewById(R.id.usersSubtextLine);
        holder.iconLine = (ImageView) convertView.findViewById(R.id.usersIconLine);
        holder.buttonLine = (ImageButton) convertView.findViewById(R.id.usersButtonLine);
        holder.infoLine = (TextView) convertView.findViewById(R.id.usersInfoLine);
        holder.infoLine.setVisibility(TextView.GONE);
        holder.userprofileButton = (ImageButton) convertView.findViewById(R.id.usersUserprofileBtn);
    
        holder.buttonLine.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                // if gone, set visible and arrow up image
                if (holder.infoLine.getVisibility() == TextView.GONE) {
                    holder.infoLine.setVisibility(TextView.VISIBLE);
                    holder.buttonLine.setImageLevel(1);
                }
                // if visible, set gone and arrow down image
                else {
                    holder.infoLine.setVisibility(TextView.GONE);
                    holder.buttonLine.setImageLevel(0);
                }
            }
        });
        //fixed listview onclicklistener bug: inner views can not be focusable
        holder.buttonLine.setFocusable(false);
    
        convertView.setTag(holder);
    

    【讨论】:

    • @Ardrock 不幸的是,即使在 Recycler List 视图项目的视图持有者中,触摸事件也直接由点击处理。所以我设法通过使用设置器将列表中的选定项目传递给活动。
    • @iDroid 您是否按照您的说法分享了完整的源代码?我没有看到相关的部分,只有一年前制作的分叉和布局,所以我建议一些阅读和处理点击的简单方法。
    • 我可以渲染视图。但是 Expandable 视图的 onChildClick 事件没有被触发。适配器中的触摸事件也没有响应。我的布局细节如下所述。 - 来自我的实际问题
    • 我的意思是,如果您在问题中添加需要修复的相关代码(java 代码)(查看器、侦听器...),例如 here
    猜你喜欢
    • 2014-07-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多