Nested Recycler Views, Vertically Scrolled ( Parent using Pagination ) - kotlin

<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_sales_report"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:clipToPadding="false"
android:paddingHorizontal="10dp"
android:paddingBottom="120dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/mtv_sales_report_date"
tools:listitem="#layout/item_reportings_new" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_dynamic_inner_reporting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical"
android:paddingBottom="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toBottomOf="#id/mtv_date_dynamic"
tools:listitem="#layout/item_inner_reporting" />
The inner recycler view is not scrolling I have tried many solutions, non helped me, how can I make the inner recycler view scroll vertically, they both scroll vertically.

android:layout_height="0dp" You shouldn't use this without setting either the layout weight or without constraining both the top and bottom of the view because without constraints, it might just act as wrap_content basically extending beyond the screen.
Also, for the inner view, if the orientation is vertical, then height shouldn't be wrap_content maybe changing that would help.
Also, just a tip, having both recycler be vertical is a bad idea because how would android (or the user) know which view you are scrolling on if they are together.

Issue is solved by showing only four items in the inner Recycler View, and enabling nestedScrollView = true, also handling OnTouch Events for the parent Recycler View.

Related

How can I control navigation and backStack from main activity

I have two activities A and B and Three fragments C,D and E.
I used intent to move from activity A to B and didn't finish activity A as I want to get back to it later.
Activity B contains a custom layout and a fragment container.
Custom layout contains a text view and a back icon image view. This layout act as action bar as I do not use default action bar as theme of activity B is android:theme="#style/AppTheme.NoActionBar".
Fragment Container hosts a navigation graph.
Fragment C is Start destination and navigation graph allows navigation as C->D->E
and back stack in following order.
C->D //After first back Stack
C //After Second back Stack reached final element in back stack.
A //Activity B is finish and Activity A is resumed after pressing one more back icon image
On press back icon image view of custom layout in activity B xml.
As there is no other action bar in any Fragment(C, D, E) so I can only use back icon image view of activity B.
I want to know how I can achieve this functionality
My activity B xml is as follows
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--android:id="#+id/container"-->
<include layout="#layout/custom_tool_bar"
android:id="#+id/toolbar_settings_activity"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_dashboard_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/settings_navigation"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/toolbar_settings_activity"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
xml code for custom tool bar is given bellow
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/app_gradient_color_background">
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/iv_back"
android:layout_width="20dp"
android:layout_height="26dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginEnd="1dp"
android:contentDescription="#string/content_description"
android:scaleType="fitXY"
android:src="#drawable/ic_white_color_back_24dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<LinearLayout
android:id="#+id/customlayout_width"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
app:layout_constraintStart_toEndOf="#+id/iv_back"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<TextView
android:id="#+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingEnd="10dp"
android:paddingTop="6dp"
android:paddingStart="10dp"
android:text="#string/custom_tool_bar_Name"
android:textColor="#color/colorOffWhite"
android:textSize="26sp"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
custom layout used as action bar
Activity B when navgraph start destination is set to C fragment
Navgraph to navigate from fragment C->D->E in Activity B
1- First in your Activity B get the navController:
val navHostFragment = binding.navHostDashboardFragment.getFragment<NavHostFragment>()
val navController = navHostFragment.navController
2- Then you can add a click listener to your back button:
binding.toolbarSettingsActivity.ivBack.setOnClickListener {
val isStackPopped = navController.popBackStack() // Navigate back to the last fragment
if (!isStackPopped) finish() // If there is no fragments in the stack finish the activity and go back to activity A
}

RecyclerView nested in LinearLayout as well as Scrollview not scrolling to specific recycler item position

My code below doesnt work for each specific scrollto or smoothScrollTo, can anyone help me?
I basically want to be able to dynamically scroll to a specific Item position in the activity, e.g. if a specific recyclerviewItem has been clicked on it will go to the activity and scroll to the specific item. The position variable has been ranging from "recyclerview.getChildAdapterPosition(itemview)" to itemview.Bottom which also doesn't work.
Help would be appreciated.
private fun focusOnView(scroll: ScrollView, itemView : View?,position :Int) {
scroll.post(Runnable {
if (editBox != null) {
val x= 1
// scroll.scrollTo(0,NestedScrollView.FOCUS_DOWN)
// scroll.smoothScrollTo(0, scroll.bottom)
scroll.smoothScrollTo(0,position)
//scroll.fullScroll(130)
}
})
}
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/scrollView"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/contentreyclerpager"
android:layout_width="match_parent"
android:paddingTop="10dp"
android:layout_height="wrap_content" />
</RelativeLayout>
</ScrollView>
Why you use the nestedScollView smoothScrollTo with the position you have to give x,y coordonate i think in your case you can use recycleView.smoothScrollToPosition(yourPosition);

How to access RecyclerView adapter itemView items?

I have a recycle view and I manage to access each item view (for example to set color) by using
recycler_view.findViewHolderForAdapterPosition(position).itemView.setBackgroundColor(R.color.red)
However, I also have a button on each item (secondary action).
<LinearLayout
android:id="#+id/lines_container">
<TextView
android:id="#+id/first_text_view"/>
</LinearLayout>
<ImageView
android:visibility="#{contact.status.active ? View.VISIBLE : View.INVISIBLE}"
app:srcCompat="#drawable/ic_call_black_24dp"
android:clickable="true"
android:id="#+id/secondary_action"/>
How can I access the secondary action button/imageView with the 'position' I have?

Glide Cache management in Recyclerview with Grid layout

I am trying to build a gallery for my app. Following some tutorials and stackoverflow, I finally managed to make the gallery. I am using Glide to set images, so no issue of memory crashing and all. The only problem is, when I fling, Images are not set into their views as fast as those views are being shown. Here is a gif. So I get to see the placeholders or the background of the recyclerview while imageviews are being set. Depending on the fling speed, this may last for 500-1000ms. But that is sufficient to make the gallery look bad. This happens when I use fling to scroll up or down. To my knowledge, this is because glide freeing the images from it's cache. Is there any solution for it.
Here is my code.
activity_gallery:
<?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:tools="http://schemas.android.com/tools"
android:id="#+id/activity_monuments"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".GalleryActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview_gallery"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:alwaysDrawnWithCache="true"
android:clipToPadding="false"
android:scrollbars="vertical"
android:scrollbarStyle="insideOverlay"/>
</LinearLayout>
Here is how I am setting recyclerview:
RecyclerView gridView = (RecyclerView)findViewById(R.id.recyclerview_gallery);
gridView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),NUM_OF_COLUMNS);
gridView.setLayoutManager(layoutManager);
gridView.isDrawingCacheEnabled();
gridView.addItemDecoration(new MarginDecoration(GalleryActivity.this, NUM_OF_COLUMNS, GRID_PADDING, true));
gridView.setHasFixedSize(true);
gridView.setVerticalScrollBarEnabled(true);
gridView.setBackgroundColor(getResources().getColor(R.color.colorBlack));
GalleryAdapter galleryAdapter = new GalleryAdapter(GalleryActivity.this, GalleryActivity.this, ImageNamesList, columnWidth);
gridView.setAdapter(galleryAdapter);
Here is how I am setting imageview in adapter:
viewHolder.galleryImage.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth));
Glide.with(context)
.load(uri)
.asBitmap()
.placeholder(R.drawable.monument)
.centerCrop()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(viewHolder.galleryImage);
Please let me know of the possible solutions.
P.S: The gif is low frame rate and hence showing the slow fling which is not the case.
To solve cache management, i use a singleton store best practice. Realm for android is perfect it is NoSql and super fast, what i normally do is create a realm object, in the adapter check if the current url is in realm, if true dont pull new image else, pull and store.
Then when the main activity or fragment is ever being destroy just delete all from realm.

Image view relative position

I'm new to Android programming and I'm facing a problem: I don't know how to set the position of an imageView over another imageView. I want the position to be relative, maybe with percentages, to maintain the aspect on different screens or in both landscape and portrait.
thank you!
to place an Image over another use relativelayout as the root layout for both image views. This will make both image views start at the same coordinate and you can flexibly arrange them as you like.
example :
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
>
<ImageView android:id="#+id/videoImage"
android:layout_width="match_parent"
android:layout_height="170dip"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"/>
<ImageView
android:id="#+id/playVideo"
android:src="#drawable/play_"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"/>
Alternatively you can use frame layout.