Recyclerview preventing touch events after notifyItemChanged in Android

Viewed 299

The Recyclerview has a ViewHolder that contains TextView typically. The text content is selectable and when long press the text opening a selection menu. The notifyItemChanged function is calling from outside of the Adapter for resize the Textview font. The text selection menu available before resizing but after that the items not selectable. Don't open text selection menu when long press. There are no any request disallowing to event but the issue occurs after the notifyItemChanged.

Edit:

The problem is the TextView xml that item view of the Recyclerview:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textRow"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textIsSelectable="true"
    android:textSize="15sp" />

The problem is solving if the android:layout_width of TextView is WRAP_CONTENT, but it must be MATCH_PARENT, what does that have to do with anything?

Recyclerview:

<androidx.drawerlayout.widget.DrawerLayout
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.ReadBookActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.drawerlayout.widget.DrawerLayout>

Edit-2:

All of my text content wrapping many spans and there is RelativeSizeSpan for font size. It's editing when changing font size. And notifying the item with notifyItemChanged(i). The problem sametimes don't occuring with using notifyDataSetChanged() withoud using Wrap_Content in the item.

Edit-3: The problem stems from editing RelativeSizeSpan completely, because it's renewing with new size when the changing font size. Removed renewing and it's using Textview.setTextSize() now, no problem.

1 Answers

So, reading the documentation for DrawerLayout it explicitly states:

To use a DrawerLayout, position your primary content view as the first child with width and height of match_parent and no <layout_gravity>. Add drawers as child views after the main content view and set the layout_gravity appropriately. Drawers commonly use match_parent for height with a fixed width.

So basically your DrawerLayout CANNOT only contain 1 view, it needs to have your main content first, then your RecyclerView or whatever, and the RecyclerView needs to have a fixed width or potentially wrap_content. Items inside the RecyclerView can now be whatever you want.

Here is an example:

activity_main.xml: (NB notice RecyclerView is not the first item and it has a layout_width of wrap_content)

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />

</androidx.drawerlayout.widget.DrawerLayout>

app_bar_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
    tools:context=".MainActivity">

    <include layout="@layout/content_main" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/main_fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right|end"
        android:layout_margin="16dp"
        android:elevation="@dimen/elevation"
        app:srcCompat="@drawable/ic_add" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

content_main.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_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/app_bar_main">

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>

I haven't actually tested this myself but it should work as I have the exact same setup except, I'm using a NavigationView instead of a RecyclerView simply because I have a set amount of items in my drawer.

Related