RecyclerView inside NestedScrollView - scroll wont work - android

I have tried many solutions found in StackOverflow now and it is not working on what I was expecting. I want to disable the Recycler View Scroll allowing only the Nested scrollView to scroll my content.
Below is my 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"
android:clickable="true"
android:focusable="true"
android:background="#color/backgroundColor">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:fillViewport="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/clProfileInfoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/background_divider"
android:paddingStart="#dimen/ps_container_padding_start"
android:paddingTop="#dimen/ps_container_padding_top"
android:paddingEnd="#dimen/ps_container_padding_end"
android:paddingBottom="#dimen/ps_container_padding_bottom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/ivPhotoSelector"
android:layout_width="#dimen/ps_photo_selector_max_width"
android:layout_height="#dimen/ps_photo_selector_max_height"
android:contentDescription="#string/cd_photo_selector"
android:maxWidth="#dimen/ps_photo_selector_max_width"
android:maxHeight="#dimen/ps_photo_selector_max_height"
android:src="#drawable/blue_profile_img_placeholder"
app:civ_circle_background_color="#color/colorAccent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/llUsernameContainer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginStart="#dimen/ps_username_margin_start"
android:layout_marginTop="#dimen/ps_username_margin_top"
app:layout_constraintStart_toEndOf="#+id/ivPhotoSelector"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tvUserName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="center_vertical"
android:text="Username"
android:textColor="#color/tvMainTextColor"
android:textSize="#dimen/ps_username_text_size"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="#+id/ivPhotoSelector"
app:layout_constraintTop_toTopOf="#+id/ivPhotoSelector" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="#+id/btnEditProfile"
style="#style/AppTheme.Button.Blue"
android:adjustViewBounds="true"
android:layout_width="wrap_content"
android:layout_height="#dimen/small_button_height"
android:layout_gravity="end"
android:src="#drawable/edit_icon"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/llLocationContainer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2"
android:layout_marginStart="#dimen/ps_location_margin_start"
android:layout_marginTop="#dimen/ps_location_margin_top"
app:layout_constraintStart_toEndOf="#+id/ivPhotoSelector"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/llUsernameContainer" >
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tvLocation"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Location"
android:textColor="#color/tvSubTextColor"
android:textSize="#dimen/ps_location_text_size"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/btnShare"
style="#style/AppTheme.Button.Blue"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="#dimen/small_button_height"
android:minWidth="#dimen/small_share_button_min_width"
android:text="#string/ps_label_share_profile"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.appcompat.widget.LinearLayoutCompat>
<me.zhanghai.android.materialratingbar.MaterialRatingBar
android:id="#+id/rbRating"
style="#style/Widget.MaterialRatingBar.RatingBar.Indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/ps_star_rating_margin_start"
android:layout_marginTop="#dimen/ps_star_rating_margin_top"
android:layout_marginEnd="#dimen/ps_star_rating_margin_end"
android:maxHeight="#dimen/ps_star_rating_max_height"
android:minHeight="#dimen/ps_star_rating_min_height"
android:numStars="5"
android:rating="4"
app:layout_constraintStart_toEndOf="#+id/ivPhotoSelector"
app:layout_constraintTop_toBottomOf="#+id/llLocationContainer"
app:mrb_fillBackgroundStars="true"
app:mrb_progressBackgroundTint="#color/rbBackgroundColor"
app:mrb_progressTint="#color/rbProgressBackgroundColor" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/clListingContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#android:color/white"
android:paddingStart="#dimen/ps_container_padding_start"
android:paddingTop="#dimen/ps_container_padding_top"
android:paddingEnd="#dimen/ps_container_padding_end"
android:paddingBottom="#dimen/ps_container_padding_bottom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/clProfileInfoContainer"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/etShortBio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="#dimen/ps_bio_min_height"
android:gravity="top"
android:padding="#dimen/ps_bio_padding"
android:text="Short Bio About Yourself"
android:inputType="textMultiLine"
android:clickable="false"
android:focusable="false"
android:enabled="false"
android:textColor="#color/labelColor"
android:background="#drawable/white_background"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvListing"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="#dimen/ps_listing_margin_top"
android:paddingTop="#dimen/ps_listing_padding_top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/etShortBio"
tools:listitem="#layout/row_user_listing_item">
</androidx.recyclerview.widget.RecyclerView>
<com.github.ybq.android.spinkit.SpinKitView
android:id="#+id/skUserListingLoading"
style="#style/SpinKitView.Wave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:SpinKit_Color="#color/colorPrimaryDark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/rvListing" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
and in my activity, I set this to disable the scroll of recycler view
private void setupListing() {
// rvMenuList should not be null
assert rvListing != null;
// initialize Recycler View Adapter
userListingAdapter = new UserListingAdapter(getContext());
// initialize GridLayoutManager
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), gridSize);
// initialize custom divider item decorator
SpacesItemDecoration itemDecorator = new SpacesItemDecoration(10, 10, 30);
rvListing.addItemDecoration(itemDecorator);
ViewCompat.setNestedScrollingEnabled(rvListing, false);
// set the adapter to the recycler view
rvListing.setAdapter(userListingAdapter);
// set the layout manager to the recycler view
rvListing.setLayoutManager(gridLayoutManager);
}
Here's how it looks like
Now I can't scroll the recycler view because of using this code ViewCompat.setNestedScrollingEnabled(rvListing, false); and also I can't scroll the whole content to view the other items of my recycler view.

this may work for you, apply layout behavior:
<android.support.v7.widget.RecyclerView
android:id="#+id/conversation"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

Instead of using this line:
ViewCompat.setNestedScrollingEnabled(rvListing, false);
Use this line:
rvListing.setNestedScrollingEnabled(false);
after setting the adapter like this:
private void setupListing() {
// rvMenuList should not be null
assert rvListing != null;
// initialize Recycler View Adapter
userListingAdapter = new UserListingAdapter(getContext());
// initialize GridLayoutManager
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), gridSize);
// initialize custom divider item decorator
SpacesItemDecoration itemDecorator = new SpacesItemDecoration(10, 10, 30);
rvListing.addItemDecoration(itemDecorator);
// set the adapter to the recycler view
rvListing.setAdapter(userListingAdapter);
// set the layout manager to the recycler view
rvListing.setLayoutManager(gridLayoutManager);
rvListing.setHasFixedSize(true);
rvListing.setNestedScrollingEnabled(false);
}
use RecyclerView width
android:layout_height="wrap_content"

finally got the solution. the rvListing.setNestedScrollingEnabled(false); actually works. the issue was the parent height i accidentally set it to 0dp which is suppose to be wrap_content. that was the fix of this issue.

Just override the GridLayoutManager as below, and invoke the method setCanScroll(false).
public class CustomLayoutManager extends GridLayoutManager {
private boolean canScroll;
public CustomLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
/**
*
* #param canScroll true--enable scroll, false--disable scroll
*/
public void setCanScroll(boolean canScroll) {
this.canScroll = canScroll;
}
#Override
public boolean canScrollHorizontally() {
return this.canScroll;
}
#Override
public boolean canScrollVertically() {
return false;
}
}

To disable scrolling of RecyclerView, you can do it programmatically:
recyclerView.setNestedScrollingEnabled(false);
Or through xml:
<android.support.v7.widget.RecyclerView
android:nestedScrollingEnabled="false"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
But be careful when your RecyclerView contain many items. It will cause lag
Disable RecyclerView scrolling is bad practice, use RecyclerView with multiple item types instead!

Related

RecyclerView inside NestedScrollview Freezes when adapter Starts Listening

My issue is: ui freezes when recycler view adapter start listening
my xml Code is as below
<?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"
tools:context=".MainAdminPackage.AdminDashboardActivity">
<!--Navigation Drawer Setup-->
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/home_background"
app:headerLayout="#layout/menu_header_design"
app:menu="#menu/main_menu" />
<LinearLayout
android:id="#+id/contentViewLl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/home_background"
android:orientation="vertical">
<!--Navigation Menu and Fab Layout Setup-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="68dp"
android:padding="20dp">
<!--Menu Button-->
<ImageView
android:id="#+id/menuIcon"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="4dp"
android:layout_centerVertical="true"
android:focusable="true"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:src="#drawable/ic_menu_icon_dark_gray"
app:tint="#color/icon_color"
android:contentDescription="#null"/>
<!--FAB Layout System-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/addQuestionPollCl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="#+id/menuIcon"
android:minHeight="68dp">
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
<!--Nested Scroll View-->
<androidx.core.widget.NestedScrollView
android:id="#+id/dashboardNestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<!--Main Container Layout-->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--LAYOUT FOR SEARCH WINDOW AND START DIALOG-->
<RelativeLayout
android:id="#+id/searchAndSloganRl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintVertical_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
</RelativeLayout>
<!--CATEGORIES BUTTON-->
<LinearLayout
android:id="#+id/categoryButtonsLl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:orientation="horizontal"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintVertical_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/searchAndSloganRl"
app:layout_constraintBottom_toBottomOf="parent">
</LinearLayout>
<!--FEATURED COURSE LAYOUT-->
<RelativeLayout
android:id="#+id/featuredCourseRl"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_marginBottom="10dp"
android:background="#color/banner_background_light"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintVertical_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/categoryButtonsLl"
app:layout_constraintBottom_toBottomOf="parent">
<!--Banner-->
<!--Recycler View for Featured Courses-->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/featuredCoursesRv"
android:layout_width="match_parent"
android:layout_height="300dp"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:layout_toEndOf="#id/featuredBackground"
android:background="#color/home_background"
tools:listitem="#layout/row_featured_courses" />
</RelativeLayout>
<!--NEWS FEED-->
<androidx.appcompat.widget.LinearLayoutCompat
android:visibility="visible"
android:id="#+id/newsFeedMiniLlc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:minHeight="100dp"
android:orientation="vertical"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintVertical_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/featuredCourseRl"
app:layout_constraintBottom_toBottomOf="parent">
<!--News Feed Recycler View-->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/newsFeedRv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="horizontal"
android:background="#color/home_background"
tools:listitem="#layout/row_news_feed_dashboard" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!--NOTES CATEGORIES-->
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/notesCategoryLlc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="vertical"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintVertical_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/newsFeedMiniLlc"
app:layout_constraintBottom_toBottomOf="parent">
</androidx.appcompat.widget.LinearLayoutCompat>
<!--ASK QUESTION RECYCLER VIEW LAYOUT-->
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/askedQuestionMiniLlc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:orientation="vertical"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintVertical_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/notesCategoryLlc"
app:layout_constraintBottom_toBottomOf="parent">
<!--Recycler View for Asked Questions-->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/askQuestionRv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="vertical"
tools:itemCount="10"
android:nestedScrollingEnabled="false"
tools:listitem="#layout/row_asked_question" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>
java code for recycler views
//For hiding the FAB when nest scroll is scrolled
dashboardNestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener(){
#Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY){
//For Adapters to Start listening
if(scrollY - oldScrollY != 0) {
if(isVisible(newsFeedMiniLlc)) {
indexOtherPost++;
if(indexOtherPost == 1) {
adapterNewsFeedListFireStoreDashBoard.startListening();
Log.d("NESTED_CHILD", "onScrollChange: indexOtherPost: " + indexOtherPost);
}
}
//Log.d("NESTED_CHILD", "onScrollChange: otherPostMiniLlc: " + isVisible(otherPostMiniLlc));
if(isVisible(askedQuestionMiniLlc)) {
indexAskedQuestion++;
if(indexAskedQuestion == 1) {
adapterAskedQuestionsFireStore.startListening();
Log.d("NESTED_CHILD", "onScrollChange: indexAskedQuestion: " + indexAskedQuestion);
}
}
//Log.d("NESTED_CHILD", "onScrollChange: askedQuestionMiniLlc: " + isVisible(askedQuestionMiniLlc));
}
}
});
//Function for getting Visibility of any View or Layout on the Screen
private static boolean isVisible(final View view) {
if (view == null) {
return false;
}
if (!view.isShown()) {
return false;
}
final Rect actualPosition = new Rect();
view.getGlobalVisibleRect(actualPosition);
int widthPixels = Resources.getSystem().getDisplayMetrics().widthPixels;
int heightPixels = Resources.getSystem().getDisplayMetrics().heightPixels;
final Rect screen = new Rect(0, 0, widthPixels, heightPixels);
return actualPosition.intersect(screen);
}
//For LOADING ASK QUESTIONS
private void loadAskQuestions(){
//for question Recycler view
LinearLayoutManager askQuestionLayoutManager = new LinearLayoutManager(getApplicationContext());
askQuestionLayoutManager.setReverseLayout(false);
askQuestionLayoutManager.setStackFromEnd(false);
askQuestionLayoutManager.setOrientation(RecyclerView.VERTICAL);
askQuestionRv.setLayoutManager(askQuestionLayoutManager);
//get all Question limited to last 10 questions
Query query = FirebaseFirestore.getInstance()
.collection("Asked Questions")
.orderBy("questionId", Query.Direction.DESCENDING)
.limit(10);
FirestoreRecyclerOptions<ModelAskedQuestion> options = new FirestoreRecyclerOptions.Builder<ModelAskedQuestion>()
.setQuery(query, ModelAskedQuestion.class)
.build();
adapterAskedQuestionsFireStore = new AdapterAskedQuestionsFireStore(this, options);
askQuestionRv.setAdapter(adapterAskedQuestionsFireStore);
}
ui freezes when ask question recycler view adapter start listening and ui only freezes for few seconds until all data is loaded in recycler view.
Any one have any solutions ???
More elaboration of the Issue:
1)I have three recycler view under this layout: Two top most Horizontal and last one Vertical in direction.
2)As this is my main dashboard. I have put nested scroll view listener for adapters to start listening when the particular layout containing that recycler view appears on the screen. Top most two adapters and their corresponding recycler views are working perfectly fine.
But when the last recycler view which is vertical in Direction, appears on the screen, It freezes the entire UI, as its adapter starts listening, for few seconds(aprrox. 1-2 seconds).
In this, adapter loads only last 10 items from the server.
I have tried:
1). Fixing the hieght of recyler view.
2). Fixing the height of Layout containing that recycler view.
3). Changed the Main Container Layout From Linear Layout to Constraint Layout.(As It was suggested in one of the comments under that thread(mentioned at the end of this thread)).
4). Tried android:nestedScrollingEnabled="false".
5). Tried app:layout_behavior="#string/appbar_scrolling_view_behavior".
Nothing has worked for this particular problem.
How to get rid of this this freezing of Ui. It should kept scrolling along the items get recycled in recycler view.
It could be same question asked in this thread.
RecyclerView inside NestedScrollview alternative

Recycler view not scrolling to last position

I'm having an issue maybe for misunderstanding how android recyclerview scroll works. I hope this can help the community too, and if you answer please provide information about the causes and fixes in a detailed way. Thanks.
The main problem I'm having is that I have a stack from end true RecyclerView that shows firebase real-time database messages. When a child is added, removed etc I call my method display messages witch sets the adapter with the new messages list and then it scrolls to the last position. The problem is that is not scrolling to the last position as you will see in the video ill show here.
Error video (Click here)
I leave here the ChatFragment Class which is the one used. Also the layout for the ChatFragment.
ChatFragment:
private void setAdapter() {
loadingLayout.setVisibility(View.VISIBLE);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setStackFromEnd(true);
recyclerViewMessageList.setLayoutManager(linearLayoutManager);
}
private void displayMessages(List<Message> messages) {
if (messages.size() > 0) {
MessageAdapter messageAdapter = new MessageAdapter(getActivity(), messages);
recyclerViewMessageList.setAdapter(messageAdapter);
recyclerViewMessageList.scrollToPosition(messages.size() - 1);
}
loadingLayout.setVisibility(View.GONE);
lottieAnimationViewLoading.cancelAnimation();
}
fragment_chat layout:
<?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"
tools:context=".Fragments.ChatFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewMessageList"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/constraintLayoutChatInput"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraintLayoutChatInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/recyclerViewMessageList">
<EditText
android:id="#+id/editTextChatSendMessage"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="24dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="10dp"
android:autofillHints="#string/write_message"
android:background="#android:color/transparent"
android:ems="10"
android:hint="#string/write_message"
android:inputType="textMultiLine"
android:maxLines="6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/imageViewChatSendMessage"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="#+id/imageViewChatSendMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="10dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="8dp"
android:src="#drawable/ic_send_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/editTextChatSendMessage"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<include
layout="#layout/loading_messages_layout"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
EDIT:
I have solved it by changing the order of setting the layout manager:
private void setAdapter() {
loadingLayout.setVisibility(View.VISIBLE);
}
private void displayMessages(List<Message> messages) {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setStackFromEnd(true);
recyclerViewMessageList.setLayoutManager(linearLayoutManager);
MessageAdapter messageAdapter = new MessageAdapter(getActivity(), messages);
recyclerViewMessageList.setAdapter(messageAdapter);
recyclerViewMessageList.scrollToPosition(messages.size() - 1);
loadingLayout.setVisibility(View.GONE);
lottieAnimationViewLoading.cancelAnimation();
}
what happens if you do not use (on this line recyclerViewMessageList.scrollToPosition(messages.size() - 2);) the -2 because what i saw on the video it was openning on correct position but after scrolls to -2 position

How to reach the last items of a scroll view?

I'm trying to display a list in a fixed size scrollview, at first it was the first items who weren't showing and I fixed it but now it's the last ones that aren't reachable.
Here is my xml code:
<?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"
android:background="#color/colorPrimary"
tools:context=".ui.home.AperoDetailFragment">
<TextView
android:id="#+id/name_apero"
android:layout_width="156dp"
android:layout_height="53dp"
android:textSize="18sp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="#+id/date_apero"
android:layout_width="238dp"
android:layout_height="53dp"
android:textSize="18sp"
android:ems="10"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.907"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<ScrollView
android:id="#+id/ingredient_apero"
android:layout_width="410dp"
android:layout_height="607dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/ingredient_title_apero"
app:layout_constraintVertical_bias="0.0">
<LinearLayout
android:id="#+id/vertical_layout_ingredient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
<TextView
android:id="#+id/ingredient_title_apero"
android:layout_width="115dp"
android:layout_height="28dp"
android:text="Liste d'achat:"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.005"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.125" />
</androidx.constraintlayout.widget.ConstraintLayout>
and here is my java code to populate the list:
public class AperoDetailFragment extends Fragment {
private View root;
private Apero detailApero;
public AperoDetailFragment(Apero apero) {
this.detailApero = apero;
}
#Override
public View onCreateView(#NonNull final LayoutInflater inflater,
final ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_detail_apero, container, false);
TextView name = (TextView)root.findViewById(R.id.name_apero);
name.setText(detailApero.getName());
TextView date = (TextView)root.findViewById(R.id.date_apero);
date.setText(detailApero.getDate());
LinearLayout ll = (LinearLayout)root.findViewById(R.id.vertical_layout_ingredient);
LinearLayout a = new LinearLayout(root.getContext());
a.setOrientation(LinearLayout.VERTICAL);
for(int i = 0; i < 20; i++)
{
Button b = new Button(root.getContext());
b.setText("Button "+i);
a.addView(b);
}
ll.addView(a);
return root;
}
}
When I scroll I can reach the number 16 but not the other, it's like they are under the layout I don't really know how to explain better.
So the question is how can I scroll my list until the last items ?
There are a few issues with your code: first and foremost if you want to display data as a list you should use a RecyclerView instead of a ScrollView. ScrollViews are there to allow the content (or part of it) in your activity/fragment to be scrollable.
Second, it's not a good practice to set specific sizes to your views, especially when using ConstraintLayout.
Third, onCreateView is meant to be a method that will simply inflate your fragment's layout and return it as a View. For handling the UI, use onViewCreated. That way you will guarantee that your UI will never be handled before your fragment is actually attached to the activity.
So answering your question, use a RecyclerView to display your items as a list instead of the ScrollView and you'll be good to go from there

Recycler view is not rendering when width & height are set to 0dp

I have a simple layout, which contains a text view, ImageView, and a recycler view, If i set recycler's view width & height to 0dp, and connects its constraint to parent, it does not render the recycler view.
But if i define height in numbers then it works fine, and renders recyclerview
This is my code
<android.support.design.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"
android:background="#color/blue"
tools:context=".activities.MyActivityV2">
<include layout="#layout/content_more_activity" />
</android.support.design.widget.CoordinatorLayout>
Inner Layout
<android.support.constraint.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"
tools:context=".activities.MyActivityV2"
tools:showIn="#layout/activity_more">
<ImageView
android:id="#+id/imageView23"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/logo" />
<TextView
android:id="#+id/tvLabelMore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="10dp"
android:letterSpacing="0.1"
android:text="MORE"
android:textAllCaps="true"
android:textColor="#color/white"
android:textSize="24dp"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="#+id/imageView23"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rvMoreItems"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageView23" />
Class File
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
generateDataForRecyclerView();
initRecyclerView();
}
private void init() {
rvMoreItems= findViewById(R.id.rvMoreItems);
}
private void generateDataForRecyclerView() {
MoreDataClass moreDataClass= new MoreDataClass();
moreDataClass.setLabel("AAA");
moreDataClass.setHeaderItem(true);
dataList.add(moreDataClass);
dataList.add(moreDataClass);
}
private void initRecyclerView() {
MoreAdapter moreAdapter= new MoreAdapter(this);
moreAdapter.setData(dataList);
rvMoreItems.setLayoutManager(new LinearLayoutManager(this));
rvMoreItems.setAdapter(moreAdapter);
}
Update this function check below.
private void initRecyclerView() {
MoreAdapter moreAdapter= new MoreAdapter(this);
rvMoreItems.setLayoutManager(new LinearLayoutManager(this));
rvMoreItems.setAdapter(moreAdapter);
moreAdapter.setData(dataList);
}

How to apply fitsSystemWindows on Fragment pages of a ViewPager?

I can't get my pages of my ViewPager respect the statusbar height.
My ViewPager has several pages, on one of them there is an image that needs to go under the translucent statusbar. The rest of the pages only require a coloured statusbar, so my idea was to use fitsSystemWindows="true" on the fragment layouts that will serve as pages for the viewpager. But This doesn't work. It seems on the first draw only the second pages gets the paddings applied. But when scrolling through the pages. It disappears. So it seems to me that the pages don't get the dispatch from the ViewPager to apply the insets. But I have no clue how to make it happen.
I have tried to do something with
public static void setOnApplyWindowInsetsListener(View v, OnApplyWindowInsetsListener listener), but I couldn't get working. My idea was to somehow on every new page to apply the insets. Maybe it is the right approach, but I couldn't find the right place to call this method.
So is there anybody that can help me address this problem?
I will place some of my code below to give some context on the problem.
Activity.xml
<..WindowInsetsFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
This is a custom layoutmanager to support changing fragments (fragment transitions) and apply the windowInset again. Just for reference this is the code:
public class WindowInsetsFrameLayout extends FrameLayout {
public WindowInsetsFrameLayout(#NonNull Context context) {
this(context, null);
}
public WindowInsetsFrameLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public WindowInsetsFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// Look for replaced fragments and apply the insets again.
setOnHierarchyChangeListener(new OnHierarchyChangeListener() {
#Override
public void onChildViewAdded(View parent, View child) {
requestApplyInsets();
}
#Override
public void onChildViewRemoved(View parent, View child) {
}
});
}
}
Then at some point in time I load the following fragment to the fragment_container.
fragmentWithViewpager.xml
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.ViewPagerController
android:id="#+id/view_pager_controller"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:showConfirmButton="true" />
</android.support.constraint.ConstraintLayout>
Where the ViewPagerController is a holder for the ViewPager, TabLayout(for the page indication of the ViewPager) and some buttons that I omitted in the layout below.
ViewPagerController
<merge>
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#id/tab_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="spread" />
...some other buttons for next en previous of the ViewPager...
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="wrap_content"
android:layout_height="#dimen/size_48"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/view_pager"
app:tabBackground="#drawable/tab_selector"
app:tabIndicatorHeight="0dp" />
</merge>
And finally the majorty of the pages for the ViewPager have this layout:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="handler"
type="fragmentX" />
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_white">
<android.support.constraint.ConstraintLayout
android:id="#+id/top_panel"
android:layout_width="0dp"
android:layout_height="#dimen/header_input_height"
android:background="#color/colorPrimary"
android:fitsSystemWindows="true"
android:paddingEnd="#dimen/size_16"
android:paddingStart="#dimen/size_16"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageButton
android:id="#+id/close_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/actionBarItemBackground"
android:minHeight="#dimen/size_48"
android:minWidth="#dimen/size_48"
android:onClick="#{(V) -> handler.onClose()}"
android:src="#drawable/ic_close"
app:layout_constraintBottom_toBottomOf="#id/icon_img"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#id/icon_img" />
<ImageView
android:id="#+id/icon_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/size_16"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_logo" />
<TextView
android:id="#+id/title_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/size_32"
android:fontFamily="#font/alvania_regular"
android:text="title or page"
android:textColor="#color/white"
android:textSize="#dimen/font_size_biggest"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/icon_img" />
<TextView
android:id="#+id/message_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/size_8"
android:alpha="0.87"
android:fontFamily="#font/frutiger_light"
android:gravity="center"
android:lineSpacingExtra="8sp"
android:text="sub title fo a page"
android:textColor="#color/white"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/title_txt" />
</android.support.constraint.ConstraintLayout>
...more views
</android.support.constraint.ConstraintLayout>
</layout>
First of all you have to apply Fullscreen to your activity so all fragments in your activity will be on fitsSystemWindow (Fullscreen), then on every fragment you can set statusBar color, which will trigger fullscreen or normal case. If statubar transparent then fragment in fullscreen.
Enable Fullscreen:
window.decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
Enable/Disable Fullscreen by coloring StatusBar:
activity?.window?.statusBarColor = Color.TRANSPARENT //Fullscreen
activity?.window?.statusBarColor = Color.TRANSPARENT //non-Fullscreen
Just enable disable it when your Fullscreen is visible or hidden
Read post about it:
https://medium.com/jama9779/single-activity-with-fullscreen-simple-fragments-fefe7f041765

Categories

Resources