material-components-android icon indicating copy to clipboard operation
material-components-android copied to clipboard

[BottomSheetDialogFragment] RecyclerView items inside BottomSheetDialogFragment need double touch after fast scrolling

Open hkchakladar opened this issue 4 years ago • 9 comments

I have a RecyclerView inside BottomSheetDialogFragment. The RecyclerView items touch working normally when it's scrolling slowly.

But when the RecyclerView is scrolled fast and after the list stops (without touching), than touching on any item doesn't work on fast touch. It needs double touching.

See in the below example gif, when touching on Andhra Pradesh it's working fine. After slow scrolling, touching on Haryana also works fine. Then doing a fast scroll and touching on Punjab doesn't work on the first touch. Touching again it works.

RV GIF

Following is the code: OperatorListDialogFragment.java

package com.*;

import *;

public class OperatorListDialogFragment extends BottomSheetDialogFragment{

    private static final String ARG_NAME = "item_name";
    private static final String ARG_LOGO = "item_logo";
    private Listener mListener;
    private String header;
    private Context mContext;

    public static OperatorListDialogFragment newInstance(String[] name, int[] logo, String header) {
        final OperatorListDialogFragment fragment = new OperatorListDialogFragment();
        final Bundle args = new Bundle();
        args.putStringArray(ARG_NAME, name);
        args.putIntArray(ARG_LOGO, logo);
        args.putString("header", header);
        fragment.setArguments(args);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_operator_list_dialog_list_dialog, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {

        TextView headerTV = view.findViewById(R.id.title);
        headerTV.setText(getArguments().getString("header"));

        final RecyclerView recyclerView = view.findViewById(R.id.list);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.setAdapter(new OperatorAdapter(getArguments().getStringArray(ARG_NAME), getArguments().getIntArray(ARG_LOGO)));

        view.findViewById(R.id.dismiss).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        mContext = context;

        final Fragment parent = getParentFragment();
        if (parent != null) {
            mListener = (Listener) parent;
        } else {
            mListener = (Listener) context;
        }
    }

    @Override
    public void onDetach() {
        mListener = null;
        super.onDetach();
    }

    public interface Listener {
        void onFilterSelected(String selected, String selectedQuery);
    }

    private class ViewHolder extends RecyclerView.ViewHolder {

        final TextView text;
        ImageView logo;

        ViewHolder(LayoutInflater inflater, ViewGroup parent) {
            // TODO: Customize the item layout
            super(inflater.inflate(R.layout.fragment_operator_list_dialog_list_dialog_item, parent, false));
            text = itemView.findViewById(R.id.tv_operator_name);
            logo = itemView.findViewById(R.id.iv_recharge_provider_icon);
        }
    }

    private class OperatorAdapter extends RecyclerView.Adapter<ViewHolder> {

        private String[] mNames;
        private int[] mLogos;

        OperatorAdapter(String[] name, int[] logo) {
            mNames = name;
            mLogos = logo;
        }

        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            return new ViewHolder(LayoutInflater.from(parent.getContext()), parent);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {

            holder.text.setText(mNames[position]);

            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.e("clicked", "" + position);
                }
            });
        }

        @Override
        public int getItemCount() {
            return mNames.length;
        }
    }
}

dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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_height="match_parent"
    android:layout_width="match_parent"
    >

    <ImageView
        android:focusable="true"
        android:clickable="true"
        android:background="?attr/selectableItemBackgroundBorderless"
        android:contentDescription="Close"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:id="@+id/dismiss"
        android:padding="14dp"
        android:src="@drawable/ic_close_black_24dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/title"
        app:layout_constraintTop_toTopOf="@id/dismiss"
        app:layout_constraintBottom_toBottomOf="@id/dismiss"
        app:layout_constraintLeft_toRightOf="@id/dismiss"
        android:padding="14dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        tools:text="Select operator"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <View
        app:layout_constraintTop_toBottomOf="@id/dismiss"
        android:background="#969696"
        android:layout_width="match_parent"
        android:layout_height="0.5dp"/>

    <androidx.recyclerview.widget.RecyclerView
        app:layout_constraintTop_toBottomOf="@id/dismiss"
        app:layout_constraintBottom_toBottomOf="parent"
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipToPadding="false"
        app:layout_constrainedHeight="true"
        android:paddingTop="@dimen/list_item_spacing_half"
        android:paddingBottom="@dimen/list_item_spacing_half"
        tools:context=".fragments.OperatorListDialogFragment"
        tools:listitem="@layout/fragment_operator_list_dialog_list_dialog_item" />
</androidx.constraintlayout.widget.ConstraintLayout>

recycler_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:gravity="center_vertical"
    android:orientation="horizontal"
    android:id="@+id/ll_operator_list_wrapper"
    android:background="?android:attr/selectableItemBackground"
    android:clickable="true"
    android:focusable="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:visibility="gone"
        android:layout_marginLeft="16dp"
        android:id="@+id/iv_recharge_provider_icon"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_marginVertical="16dp"
        android:layout_centerVertical="true"
        android:src="@drawable/ic_bsnl_logo"
        tools:visibility="visible"/>

    <TextView
        android:padding="16dp"
        android:textColor="#212121"
        android:textSize="14sp"
        android:ellipsize="end"
        android:id="@+id/tv_operator_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="false"
        android:text="BSNL"
        android:layout_toRightOf="@+id/iv_recharge_provider_icon"
        android:layout_centerInParent="true"/>

    <View
        android:layout_below="@id/iv_recharge_provider_icon"
        android:id="@+id/divider0"
        android:background="#eeeeee"
        android:visibility="visible"
        android:layout_width="wrap_content"
        android:layout_height="1dp"
        android:layout_marginLeft="16dp"
        android:layout_toRightOf="@+id/iv_recharge_provider_icon"
        />

</RelativeLayout>

hkchakladar avatar Mar 22 '20 14:03 hkchakladar

same to me. how to solve it?

pennya avatar Jun 16 '20 02:06 pennya

same problem. even does not work by double touch

hsnmrd avatar Aug 03 '20 08:08 hsnmrd

add android:nestedScrollingEnabled="false" in RecyclerView

VishnuKantAgarwal avatar Sep 05 '20 06:09 VishnuKantAgarwal

Same problem. @VishnuKantAgarwal 's solution not working too.

tanvir93 avatar Jan 28 '21 06:01 tanvir93

any update?

Android563 avatar May 19 '21 13:05 Android563

any update?

bayuwijdev avatar Dec 15 '21 14:12 bayuwijdev

Hey, dod anyone solve it?

krobert avatar Mar 21 '22 10:03 krobert

I have RecyclerView inside ConstraintLayout and when I scrolldown view from top not fully came down

bhavin-qfonapp avatar May 09 '22 05:05 bhavin-qfonapp

add android:nestedScrollingEnabled="false" in RecyclerView

This works for me, but I have to set up other things as well


binding.tableContent.listView.setNestedScrollingEnabled(false)
    binding.tableContent.listView.setOnTouchListener { v, event ->
      when (event.action) {
        MotionEvent.ACTION_DOWN -> {
          v.parent.requestDisallowInterceptTouchEvent(true)
        }
        MotionEvent.ACTION_MOVE -> {
          v.parent.requestDisallowInterceptTouchEvent(true)
        }

        MotionEvent.ACTION_UP -> {
          v.parent.requestDisallowInterceptTouchEvent(false)
        }
        else -> {}
      }
      v.onTouchEvent(event)
      true
    }

gsdukbh avatar Jan 03 '24 07:01 gsdukbh