I have a fragment with an expandable list view which should be scrollable if the content is larger than the remaining screen. However, I cannot find a way to get the scrolling working properly. Here's the fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:id="#+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/titleView"
android:textColor="#color/textColor"
android:paddingHorizontal="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textSize="8pt"
tools:layout_editor_absoluteY="9dp" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/nestedScrollView"
android:fillViewport="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/titleView"
app:layout_constraintBottom_toBottomOf="parent"
>
<ExpandableListView
android:id="#+id/expListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:padding="8dp"
/>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
I tried to wrap a LinearLayout around the NestedScrollView (because some other post said that), but it did not work. When I open an element at the bottom of the list it scrolls down to show the complete child in the view, but the view does not respond to any scrolling attempts, neither by sliding up/down on the items nor clicking on the scroll bar.
Adapter code taken 1:1 from here: http://developine.com/expandable-listview-android-kotlin/ only xml is changed as shown above.
Any ideas?
I found an answer to my question which solves the problem but as pointed out by #Mwasz this should not be the way you do it. So I document it here just for reference and maybe if somebody has really a reason to use the NestedScrollView
In the ExpandableListView add
android:nestedScrollingEnabled="true"
to enable the scrolling inside the NestedScrollView.
I don't understand why is ExpandableListView wrapped in the NestedScrollView. If you don't have an exact reason for this - remove NestedScrollView
If you need to keep the NestedScrollView - I think Your list isn't scrolling, because the ScrollView consumes touch events. You could try to make a custom ExpendableListView that disallows to intercept the touch event.
Kotlin (if you're using java then change it to java code):
class MyOwnExpendableListView #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : ExpandableListView(context, attrs) {
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
parent.requestDisallowInterceptTouchEvent(true)
return super.dispatchTouchEvent(ev)
}
}
Then use it in your xml:
<MyOwnExpandableListView
android:id="#+id/expListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:padding="8dp"
/>
Related
Here is my Persistent BottomSheet
<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/bs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bottom_sheet_background"
android:elevation="2dp"
android:padding="#dimen/base_margin"
app:behavior_hideable="true"
app:behavior_peekHeight="#dimen/bottom_sheet_peek_height"
app:layout_behavior="#string/bottom_sheet_behavior">
When User scrolls RecycleView, BottomNavigation hides and I reduce height of BottomSheet accordingly in RecycleView's addOnScrollListener using:
binding.rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
//148 = 80(bottom navigation) + 56(bottom sheet)
if (dy < 0)//scroll down
bottomSheetBehavior.setPeekHeight(136, true);
else if (dy > 0)//scroll up
bottomSheetBehavior.setPeekHeight(56, true);
}
After BottomNavigation is hidden and BottomSheet height is reduced, if BottomSheet is clickable,
(either through code binding.bs.bs.setClickable(false); or through xml android:clickable="true")
I can't drag it to expand. If it is not clickable, click event goes through it and user click on RecycleView item underneath it.
Even when its height is not reduced and it isn't clickable then also click event goes under it and fire on RecycleView item.
I also tried setting nestedScrolling, which allowed expanding but after that start creating issues when collapsing. :(
UPDATE:
I noticed BottomSheet drag not works when I set Bottomsheet clickable and its peekheight < 80 dp, ie the height of BottomNavigation.
Reference:
Why am I able to click "behind" the bottomsheet in Android?
I had same use case of having a recycler view inside a bottom sheet and here's what my Bottom sheet XML looks like. Please try to check if this works for you!
Apart from this, I did not actually get it why you want to reduce the height of the bottom sheet, as Bottom sheet has the behavior of self adjusting its height respect to the content inside it.
Please if possible share your use case so that it will be easier for the community to answer which gonna hit the bonsai. Thanks!
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:background="#color/transparent"
android:layout_height="match_parent"
android:paddingTop="50dp"
android:id="#+id/rootLayout"
>
<include
android:id="#+id/progress"
layout="#layout/item_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="#+id/rootView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bottom_sheet_rounded_background"
android:backgroundTint="#color/background_gray"
android:clipToPadding="true"
android:orientation="vertical"
app:layout_behavior="#string/bottom_sheet_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<RelativeLayout
android:id="#+id/title_rl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginStart="24dp"
android:height="24sp"
android:fontFamily="#font/silka_bold"
android:text="#string/error_select_prescription"
android:textColor="#color/text_color_semi_black"
android:textSize="16sp" />
<ImageView
android:id="#+id/iv_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:src="#drawable/ic_close_btn_gray" />
</RelativeLayout>
<View
android:id="#+id/view"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/btn_gray"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/title_rl" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewPrescription"
android:layout_width="match_parent"
android:layout_height="0dp"
android:paddingTop="#dimen/dimen_16dp"
tools:itemCount="10" />
</androidx.core.widget.NestedScrollView>
<include
android:id="#+id/btn_select_and_proceed"
layout="#layout/sticky_footer_design_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
val bottomSheet = dialog!!.findViewById<View>(R.id.design_bottom_sheet) as FrameLayout
val behavior: BottomSheetBehavior<*> = BottomSheetBehavior.from<View>(bottomSheet)
behavior.state = BottomSheetBehavior.STATE_EXPANDED
These all are the states which you can use to manipulate the height or basically the behavior of the BottomSheet.
I am trying to put recyclerView with a screen (Fragment) that has textView.
The .xml file of the fragment i'm trying to add to:
<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=".ui.ways.WaysFragment">
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/ways_quote"
android:layout_marginTop="#dimen/card_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:textSize="18sp"
android:layout_marginBottom="10dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView"
tools:listitem="#layout/custom_ways_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
I will try to describe the appearance (result) of what I tried to do with code and words, rather than pictures, I think it will be easily understood that way.
At first I added textView and just put the recyclerView under it.
And the result(appearance on my test device) I got look like:
Layout:
....
TextView:
....
ScrollView:
....
and the contents of my recyclerView
By this I mean, the textView doesn't scroll but the recyclerView does.
Next I put the textView and recyclerView inside the a single scrollView. But the textView scrolls seperately from the recyclerView, as if textView and recyclerView were in different scrollView.
the result(appearance on my test device) I got look like:
Layout:
....
ScrollView:
....
TextView:
....
ScrollView:
....
and the contents of my recyclerView
And my desired Appearances, is:
Layout:
....
ScrollView:
....
TextView:
....
Contents of my recyclerView:
....
I have discovered I named this question wrong it should have been "how to put header in a recyclerview using kotlin".
To do I created a new layout for the header, and an adapter.
Then I used ConcatAdapter To add the adapter of the header and recyclerview together.
I followed this tutorial on medium.
The structure of my layout file: Coordinator layout - NestedScrollView - Coordinator Layout - objects that i want to be able to scroll
My TextInputLayout with TextInputEditText is at the bottom of the screen and when filled, extends out of bounds of the screen. When I collapse the keyboard it’s still not scrollable.
Note: I don’t want to set maxLines to Edittext and make it scrollable itself. I want it to scroll with other elements.
However, if I put, for example, TextView at the bottom of the screen and it doesn’t fit, the page is scrollable. Any ideas?
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--other items i want to scroll-->
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/descriptionLayout"
android:layout_width="348dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="545dp"
android:ems="16"
android:fontFamily="#font/montserrat"
android:hint="Add image description (optional)"
android:inputType="textMultiLine|textAutoCorrect"
app:counterEnabled="true"
app:counterMaxLength="256"
app:boxBackgroundColor="#color/white"
app:srcCompat="#drawable/ic_round_cloud_upload_24"
android:textColor="#68B2A0"
android:textColorHint="#68B2A0"
app:hintTextColor="#68B2A0"
app:layout_anchor="#id/titleLayout"
app:boxStrokeErrorColor="#F75010"
app:boxStrokeColor="#68B2A0"
app:boxStrokeWidth="2dp"
app:errorIconTint="#color/error"
app:errorTextColor="#color/error"
app:layout_anchorGravity="center|bottom"
app:counterOverflowTextColor="#color/error"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
app:counterTextColor="#color/main_green"
>
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/descriptionTxt"
android:ems="16"
android:textSize="18sp"
android:textColor="#68B2A0"
android:fontFamily="#font/montserrat"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:maxLines="7"
/>
</com.google.android.material.textfield.TextInputLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.core.widget.NestedScrollView>
<!--bottom app bar-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
This is because you hard set android:layout_marginTop="545dp". Try never to do that. Also i think use costaint layour in youre case is better. Just change <androidx.coordinatorlayout.widget.CoordinatorLayout> inside nested scroll view to <androidx.constraintlayout.widget.ConstraintLayout> and add this atributes:
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent
If you need to show nested view in fullscteen, just chaange android:layout_height="wrap_content" to android:layout_height="match_parent"
I have to hide Particular views in recyclerview, I am trying to hide some views but view has gone but space is there,I have tried putting heights=0 in cardview but still did not work , what I should I do?
This is my XML code list data
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-
auto">
<android.support.v7.widget.CardView
android:id="#+id/child_card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2sp"
app:cardElevation="12sp"
android:visibility="gone">
<LinearLayout
android:id="#+id/main_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:orientation="vertical"
android:padding="3dp"
android:visibility="visible">
<ImageView
android:id="#+id/icon"
android:layout_width="48dp"
android:layout_height="48dp"
app:srcCompat="#drawable/bsp_icon" />
<android.support.v7.widget.AppCompatTextView
android:id="#+id/label_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:lines="2"
android:maxLines="2"
android:padding="0dp"
android:textColor="#color/Black" />
</LinearLayout>
</android.support.v7.widget.CardView>
</layout>
and this is my recyclerview
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="0dp"
tools:listitem="#layout/list_layout_dashboard_child_view">
</android.support.v7.widget.RecyclerView>
this is my Adapter code
if (txnTypeMap.get("CUST_CR") != null &&
obj.getChildName().equalsIgnoreCase(txnTypeMap.get("CUST_CR"))) {
binding.childCardView.setVisibility(View.VISIBLE);
}
important always set this if you are sure your data will change in recyclerview mRecyclerView.setHasFixedSize(false);
first remove the item from list e.g. list.remove(position which you want to hide)
next call notifyItemChanged(postion) and it should work ->this is better approach than calling notifyDataSetChanged()
You should hide all views or parent from UsersViewholder layout xml. You should hide entire viewholder or each view
Entire viewholder:
itemView.setVisibility(View.GONE);
or each element:
view.setVisibility(View.GONE);
But don't forget to set them VISIBLE otherwise, you will end up with some strange things from recycling
Without setting setVisibility to View.GONE, try to remove the the data from the data source and call notifyDataSetChanged()
This is the more efficient way to hide a view from RecyclerView
you have to set visibility gone to view in else case because views are reused in recycler view
if (txnTypeMap.get("CUST_CR") != null &&
obj.getChildName().equalsIgnoreCase(txnTypeMap.get("CUST_CR"))) {
binding.childCardView.setVisibility(View.VISIBLE);
} else binding.childCardView.setVisibility(View.GONE);
I hope it will work.
I am having a weird issue which might be very simple to solve but I don't know why its behaving like it does. I have two screens A and B. Navigation is from A -> B. On B, I have parent view as LinearLayout (LL) as
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="#+id/container"
android:orientation="vertical"
android:background="#color/tcRaspberry"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:animateLayoutChanges="true"
android:layout_height="match_parent">
<include
app:layout_constraintBottom_toTopOf="#+id/bottomSheetContainer"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:id="#+id/toolbarx"
layout="#layout/include_toolbarx"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_marginStart="#dimen/itinerary_start_margin"
android:layout_marginEnd="#dimen/itinerary_start_margin"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:contentDescription="#null"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="#dimen/itinerary_start_margin"
app:layout_constraintStart_toStartOf="parent"
android:id="#+id/myAccountImage"
android:layout_gravity="center"
app:srcCompat="#drawable/ic_panorama_circle_24dp"
android:layout_width="#dimen/image_size_profile"
android:layout_height="#dimen/image_size_profile"/>
<androidx.appcompat.widget.AppCompatTextView
android:textSize="20sp"
android:contentDescription="#string/travel_counsellor_contact"
android:layout_marginStart="#dimen/top_margin"
app:layout_constraintTop_toTopOf="#+id/myAccountImage"
app:layout_constraintStart_toEndOf="#+id/myAccountImage"
app:layout_constraintBottom_toBottomOf="#+id/myAccountImage"
android:id="#+id/myAccountTitle"
android:textAppearance="#style/TcTextAppearance.Bold.Header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/my_account"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
Even though the parent LL's height (id: container) is set as match_parent and is filling whole screen, its still accepting click events from previous screen A. The only way I got it to not accept clicks from A is to put a ClickListener on it which seems like a hack to me. What can I do to prevent it taking clicks from A.
Make the view that should block the call clickable via xml android:clickable="true" or set a click handler for it from fragment/activity