How to apply fitsSystemWindows on Fragment pages of a ViewPager? - android

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

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

Android Adding a button with multiline text inside MaterialButtonToggleGroup doesn't work

I am trying to show a multiline button inside a MaterialButtonToggleGroup but it always shows me ... at the newline
but it works fine outside the MaterialButtonToggleGroup I have tried
using \n and
using <br/> HTML tag with Html.form method
As shown in the image below the first button is outside the MaterialButtonToggleGroup but the second is inside it.
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".conversation.ui.conversations.AddNewConversationFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_margin="20dp"
android:background="#drawable/register_field_background"
android:orientation="vertical"
android:padding="10dp">
<ImageView
android:id="#+id/img_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_baseline_close_24"
android:tint="#android:color/darker_gray"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<com.google.android.material.button.MaterialButton
android:id="#+id/add_anyone"
android:singleLine="false"
android:maxLines="2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#color/gray100"
android:text="This is Multi Line Text
Line2"
android:textAllCaps="false"
android:textColor="#color/gray700"
app:iconTint="#color/gray700"
/>
<com.google.android.material.button.MaterialButtonToggleGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginBottom="10dp"
android:orientation="vertical"
app:checkedButton="#+id/button_add_native"
app:layout_constraintBottom_toTopOf="#+id/tv_select_address"
app:layout_constraintTop_toBottomOf="#+id/textView"
app:selectionRequired="true"
app:singleSelection="true">
<com.google.android.material.button.MaterialButton
android:id="#+id/add_anyone"
android:singleLine="false"
android:maxLines="2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#color/gray100"
android:text="This is Multi Line Text
Line2"
android:textAllCaps="false"
android:textColor="#color/gray700"
app:iconTint="#color/gray700"
/>
</com.google.android.material.button.MaterialButtonToggleGroup>
<TextView
android:id="#+id/textView"
style="#style/bottomSheetDialogHeader"
android:layout_marginStart="16dp"
android:letterSpacing="0.1"
android:text="#string/add_conversation_dialog_title"
android:textAllCaps="true"
app:layout_constraintBottom_toBottomOf="#+id/img_close"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/img_close" />
<com.google.android.material.button.MaterialButton
android:id="#+id/tv_select_address"
style="#style/LinguisticMainLayoutOrangeButton"
android:paddingBottom="10dp"
android:text="#string/start_chatting"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
</layout>
It is an expected result.You can check the source code below where the multiline is overridden.
You can set it programmatically. Something like:
val button : MaterialButton = findViewById(R.id.add_anyone)
button.maxLines = 2
Source code:
https://github.com/material-components/material-components-android/blob/e944d1b2a6ee5d9d5a338de0c0061f7b02790f77/lib/java/com/google/android/material/button/MaterialButtonToggleGroup.java#L751-L754
private void setupButtonChild(#NonNull MaterialButton buttonChild) {
buttonChild.setMaxLines(1);
buttonChild.setEllipsize(TruncateAt.END);
buttonChild.setCheckable(true);
An alternative trick for future reference:
Provide your own custom class, let's name it CustomMaterialButtonToggleGroup, which extends MaterialButtonToogleGroup
example:
public class CustomMaterialButtonToggleGroup extends MaterialButtonToggleGroup {
public CustomMaterialButtonToggleGroup(#NonNull Context context) {
super(context);
}
public CustomMaterialButtonToggleGroup(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public CustomMaterialButtonToggleGroup(#NonNull Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
super.addView(child, index, params);
if(child instanceof MaterialButton)
{
((MaterialButton) child).setMaxLines(2);
}
}
This way we enforce via code the child views of the MaterialToggleGroup to implement maxLines!
Final the 2nd weird part is:
Go to your Activity/Fragment in which you define your button...and set it via code!
example:
SampleButton.setText("Hey\nI'm multiline"); // notice the escape character of newline-> \n
Afterwards extract it in the strings.xml as you would do normally!

TextClock causes ScrollView to jump - Android Studio

I have created a tabLayout that swipes between two fragments using a viewPager2 + Fragment State Adapter
Within Fragment 2, I have a TextClock within a scroll view.
When I scroll down to the bottom of the page, it keeps jumping to the top if the page
Video link showing issue
Any help would be appreciated
<?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=".BarcodeFragment">
Xml Code:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
tools:layout_editor_absoluteY="104dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextClock
android:id="#+id/simpleTextClock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:format24Hour="HH : mm : ss"
android:textColor="#color/colorDark"
android:textScaleX=".94"
android:textSize="18sp"
android:textStyle="bold"
app:fontFamily="#font/tlcircular_bold"
app:layout_constraintBottom_toTopOf="#+id/box02"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/box02"
android:layout_width="329dp"
android:layout_height="283.99986dp"
android:layout_marginTop="450dp"
android:background="#drawable/box_rounded_ticket"
android:shadowColor="#00FF0A0A"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
Java Code:
</**
* A simple {#link Fragment} subclass.
*/
public class TicketFragment extends Fragment {
public TicketFragment() {
// Required empty public constructor
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_ticket, container, false);
return rootView;
}
}>
SOLVED
Whenever configuring the height / width of a TextClock - never use 'wrap_content'. I had to reverse engineer my entire app to find such such a simple problem.
My question is: why has this never been flagged before?!

accessing different children in different pages of ViewPager

The layout of my StartupPreference is defined with only one ViewPager as:
<?xml version="1.0" encoding="utf-8"?>
<androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/startPref_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
and the associated activity associates this as:
public class StartupPreference extends AppCompatActivity implements StartupPrefFrag_interfaces{
private final static int no_of_prefs = 2;
private LinearLayout dot_animation_holder;
private static int temp_count = 0;
public void ViewUpdater(View updatedView){
dot_animation_holder = (LinearLayout) updatedView;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_startup_preference);
//we're not using the layout natively, but using Fragment's layout
//but setContentView is required -> it is accessed by : R.id.startPref_pager
dot_animation_holder= findViewById(R.id.dot_animation_holder);
StartPrefPagerAdapter prefPagerAdapter =
new StartPrefPagerAdapter(getSupportFragmentManager());
ViewPager StartPref_Viewpager = findViewById(R.id.startPref_pager);
StartPref_Viewpager.setAdapter(prefPagerAdapter);
StartPref_Viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
((ImageView)(findViewById(R.id.dot_animation_holder).findViewById(R.id.page1))).setImageResource(R.drawable.active_dot);
((ImageView)(findViewById(R.id.dot_animation_holder).findViewById(R.id.page2))).setImageResource(R.drawable.inactive_dot);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
private class StartPrefPagerAdapter extends FragmentPagerAdapter {
public StartPrefPagerAdapter(FragmentManager fm){
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
#Override
public int getCount(){
return StartupPreference.no_of_prefs;//no. of preference pages
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new Frag_StartPref_Layout();
case 1:
return new Frag_StartPref_Theme();
}
return null;
}
}
}
The problem I am having is that I'm not getting it how to access different Views associated with the ViewPager. Since both the layout of the fragments include a common layout called dot_animation.xml using the <include...> tag, but the code in the onPageSelected method above updates only the first page, and if I use different ids in the <include...> like:
fragment_startpref_layout.xml:
...
<include
layout="#layout/dot_animation"
android="#+id/dot_animation_holder1"
/>
...
fragment_startpref_theme.xml
...
<include
layout="#layout/dot_animation"
android="#+id/dot_animation_holder2"
/>
...
and I use these ids to update the ImageView then I get a NullPointer Exception.(I use the code in the activity)
So, what can I do to access the different Views in the respective pages of the ViewPager?
The layout of the fragments are given below:
fragment_startpref_layout.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:id="#+id/C_startPref_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"
>
<ImageView
android:id="#+id/startPref_Layout"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toTopOf="#+id/startPref_layout_info"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#mipmap/ic_launcher" />
<TextView
android:id="#+id/startPref_layout_info"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:gravity="center"
android:text="#string/Frag_startPref_layout_info"
android:textSize="25sp"
app:layout_constraintBottom_toTopOf="#+id/startPref_layout_select1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent=".125"
app:layout_constraintStart_toStartOf="parent" />
<RadioGroup
android:id="#+id/startPref_layout_select1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="#+id/dot_animation_holder"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent=".125"
app:layout_constraintStart_toStartOf="parent">
<RadioButton
android:id="#+id/radioButton1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:checked="true"
android:text="#string/Frag_startPref_Radio1"
android:textSize="15sp" />
<RadioButton
android:id="#+id/radioButton2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="#string/Frag_startPref_Radio2"
android:textSize="15sp" />
</RadioGroup>
<include
layout="#layout/dot_animation"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_theme_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/C_startPref_theme"
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:id="#+id/startPref_Theme"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toTopOf="#+id/startPref_layout_info"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#mipmap/ic_launcher" />
<TextView
android:id="#+id/startPref_layout_info"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:gravity="center"
android:text="#string/Frag_startPref_layout_info"
android:textSize="25sp"
app:layout_constraintBottom_toTopOf="#+id/startPref_layout_select2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent=".125"
app:layout_constraintStart_toStartOf="parent" />
<RadioGroup
android:id="#+id/startPref_layout_select2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="#+id/dot_animation_holder"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent=".125"
app:layout_constraintStart_toStartOf="parent">
<RadioButton
android:id="#+id/radioButton1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:checked="true"
android:text="#string/Frag_startPref_Radio1"
android:textSize="15sp" />
<RadioButton
android:id="#+id/radioButton2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="#string/Frag_startPref_Radio2"
android:textSize="15sp" />
</RadioGroup>
<include
layout="#layout/dot_animation"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
First of all you need to update the view in fragmnet on onViewCreated.
the reason that you cant update other views is the viewpager only shows the current fragment.and the reason for nullpointexception also is that the other view are not loaded into the activity by viewpager.(You may also want to check if the correct layout is being called in the onCreateView method.) If you want to load all of them even if they are out of the screen you can use viewPager.setOffscreenPageLimit(); but this lose the viewpager purpose. so what i suggest is to create call back to communicate with your fragment and send data through callbacks and update your view inside of there fragment. also this make your activity less messy.
Update :
example of using ViewPager with multiple layouts
Document About setOffscreenPageLimit
Set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state. Pages beyond
this limit will be recreated from the adapter when needed.
This is offered as an optimization. If you know in advance the number
of pages you will need to support or have lazy-loading mechanisms in
place on your pages, tweaking this setting can have benefits in
perceived smoothness of paging animations and interaction. If you have
a small number of pages (3-4) that you can keep active all at once,
less time will be spent in layout for newly created view subtrees as
the user pages back and forth.
You should keep this limit low, especially if your pages have complex
layouts. This setting defaults to 1.

RecyclerView inside NestedScrollView - scroll wont work

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!

Categories

Resources