Recyclerview preventing touch events after notifyItemChanged in Android - java

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.

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

call fragments when clicking RecyclerView item and show them both in the same activity

Since I only changed from buttons to RecyclerView (and it worked just fine with the buttons), I know my java code is working fine, so now I face a problem because clicking a cards in the RecyclerView calls the fragment with the FragmentManager, but not showing it.
Here is my activity.xml code.
<LinearLayout
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"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".mainSearch"
android:background="#f2f2f2">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recyclerView"
android:orientation="horizontal" />
</androidx.constraintlayout.widget.ConstraintLayout>
<fragment
android:name="com.diamcom.blue.StoneCodeFragment"
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent">
</fragment>
</LinearLayout>
I wonder what am I doing wrong ?
I think the issue you have here is having both the recyclerview and the fragment as match_parent for both width and height. A way I think you can do that is by wrapping the containerview which holds the recyclerview and the fragment in a framelayout and making the containerview to be gone when you click on any of the cards in the recyclerview.

How to make my fragment fit between my toolbar and bottom navigation bar and still make it scrollable?

So I will have my main-activity layout file below so you can understand what is happening
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include
android:id="#+id/toolbar"
layout="#menu/toolbar"/>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottom_nav">
</FrameLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_navigation"
app:itemIconTint="#android:color/white"
android:background="#39b54a"
app:labelVisibilityMode="unlabeled">
</com.google.android.material.bottomnavigation.BottomNavigationView>
</RelativeLayout>
The problem with this layout is that the toolbar on the top and the bottom navigation bar cover content from my fragments. Also one of my fragments has got a recyclerview with many items and I canĀ“t scroll down for some reason ? Is there a way to make the fragments fit exactly between the toolbar and bottomnavigation like resizing itself to fit into that area without cutting content and still make it scrollable ?
Do it like this ...
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar_layout"/> <!--include your layout file here -->
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_below="#id/toolbar"
android:layout_height="match_parent"
android:layout_above="#+id/bottom_nav">
</FrameLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_nav_menu"
app:itemIconTint="#android:color/white"
android:background="#39b54a"
app:labelVisibilityMode="unlabeled">
</com.google.android.material.bottomnavigation.BottomNavigationView>
</RelativeLayout>
And by the way, you are supposed to set a layout resource file into the toolbar layout while including but you are passing the menu resource file. Change that also accordingly...

RecyclerView inside LinearLayout and NestedScrollView - How to scroll to top of item on a certain position?

I implemented RecyclerView. I would like a view scroll to top of item on 5th position in RecyclerView. scrollToPosition(5) don't work
XML file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="128dp"
android:orientation="vertical">
<androidx.core.widget.NestedScrollView
android:id="#+id/nestedScrollView_mark"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/linearLayout_markView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView_marks"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="1dp" />
<LinearLayout
android:id="#+id/linearLayout_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:background="#drawable/layout_bg"
android:orientation="vertical"
android:visibility="invisible">
in Fragment:
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.getLayoutManager().scrollToPosition(5);
recyclerView.setAdapter(adapter);
The scrollToPosition() needs to be used with any of the following ways to restore the scroll position to the selected position.You can save the selected position in onPause() and then restore subsequently.
There might be two useful ways :-
Using onSaveInstanceState() function to save the state as explained here.
Using Shared Prefereneces to store the position, and restoring the state after the onCreateView.

Making LinearLayout with ListView scrollable

I have a linear layout that looks something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linear_layout"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:orientation="vertical"
tools:context=".activities.EnrolStudentFormActivity">
<include
layout="#layout/app_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:fitsSystemWindows="true" />
<ListView
android:id="#+id/list_view
android:layout_width="match_pare
android:layout_height="wrap_cont
android:divider="#null"
android:dividerHeight="0dp" />
</LinearLayout>
With a few ImageViews, TextInputLayouts and TextInputEditTexts in between. I want to make this layout scrollable. I tried to make it scrollable with ScrollView and NestedScrollView, but both of them messed the ListView up.
I am also changing the ListView contents dynamically and I have a few TextInputEditTexts inside TextInputLayouts inside the ListView. Resizing the ListView doesn't help much, and I cannot click on the TextInputEditText inside the ListView. It seems that the ScrollView captures the touch input.
Are there any workarounds that will let me have a ListView inside a ScrollView or make the linear layout scrollable while making the TextInputEditText inside the ListView usable?
Use RecyclerView instead of ListView and add NestedScrollView on top:
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="
http://schemas.android.com/apk/res/android"
xmlns:http="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:orientation="vertical"
tools:context=".activities.EnrolStudentFormActivity">
<include
layout="#layout/app_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:fitsSystemWindows="true" />
<android.support.v7.widget.RecyclerView
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#null"
android:dividerHeight="0dp" />>
</LinearLayout>
and finally in your code add:
RecyclerView.setNestedScrollingEnabled(false);

Hiding Toolbar when setting Recycleviewer background

When I set the background paramter on my RecyclerView, it hides the Toolbar.
Simple, but I can't figure out how can I fix it.
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:background="#android:color/darker_gray"
tools:context="los.printers.MainActivity"
app:theme="#style/Theme.MyTheme">
<android.support.v7.widget.Toolbar
android:id="#+id/tb_main"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<RelativeLayout
android:id="#+id/rl_fragment_container"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
fragment_printer.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="los.printers.fragment_printer">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_List"
android:scrollbars="vertical"
android:paddingTop="?attr/actionBarSize"
android:background="#color/colorTextIcons"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
The padding works fine in RecyclerView, but the toolbar doesn't shows up.
Your rl_fragment_container is drawn on top of your toolbar.
But I think you know that because you apply a padding in your fragment.
A padding will draw the view in the same size and is applied to its contents, while a margin will be outside of the views bounds, making the whole view smaller. This is important if you draw backgrounds.
As said befoer, your fragment is on top of your toolbar, your recyclerview fills the whole fragment and draws a background on top.
You can now
move the rl_fragment_container before the toolbar in xml -> this will get it drawn below the toolbar
change padding to margin
or just layout the rl_fragment_container below your toolbar with android:layout_below="#+id/tb_main" and remove paddings & margins.
Update the activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:background="#android:color/darker_gray"
tools:context="los.printers.MainActivity"
app:theme="#style/Theme.MyTheme">
<android.support.v7.widget.Toolbar
android:id="#+id/tb_main"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<RelativeLayout
android:id="#+id/rl_fragment_container"
android:layout_below="#+id/tb_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>

Categories

Resources