I have a little strange problem for me. I need to translate view which is located over a viewpager on recyclerview scroll. RecyclerView is located in fragment and fragments are located in viewpager. When I scroll recyclerview in fragment and want to translate View which is located over viewpager my problem occurs. ViewPager is moving up to fill space left by translated view, but fragments aren't. Because of it I can see space empty space on viewpager. I checked it by setting viewpager background and i saw that viewpager actually resized to match container but fragments remained still. Any ideas how to force it to works as it should be? This code works perfectly when recyclerview and view which I want to resize are on same fragment.
Issue look like this http://i.imgur.com/wyxXGYh.png
Layout look like this
ViewPagerFragment
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:clipToPadding="false">
<android.support.v7.widget.RecyclerView
android:id="#+id/subcategory_fragment_recycle_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
Layout with Viewpager
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/fragment_category_sliding_tab_layout">
<android.support.v4.view.ViewPager
android:id="#+id/fragment_category_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="100dp"
android:clipToPadding="false"
android:background="#0000FF"
android:animateLayoutChanges="true">
</android.support.v4.view.ViewPager>
<TextView
android:id="#+id/scrollTemp"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#FF0000"
android:gravity="center|center_vertical"
android:text="TEMP"
android:textSize="40dp" />
</FrameLayout>
For detecting scrollevents and triggering show/hide of temp view I am using basically this HidingScrollListener https://mzgreen.github.io/2015/02/28/How-to-hideshow-Toolbar-when-list-is-scrolling%28part2%29/. As I said it works perfectly when recyclerview and view which I want to scroll are on same fragment.
Related
I have a view that acts like BottomSheetBehavior and this view has ViewPager2 inside. Each ViewPager2's page is a vertical RecyclerView. The issue is that BottomSheet doesn't scroll down when current vertical RecyclerView (which is a page of ViewPager) can't scroll vertically anymore. Everything works file when instead of ViePager I have only one vertical RecyclerView.
The temporary solution is to wrap ViewPager with NestedScrollView but it's horrible for performance and has it's own bugs.
The original layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/core"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#C7C7C7"
tools:context=".MainActivity">
<LinearLayout
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:elevation="8dp"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="300dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:layout_gravity="center_horizontal"
app:tabGravity="center"
app:tabMode="scrollable" />
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
[Here's how it looks (sorry for the gif quality)]
I've found a solution for this case, I set isNestedScrollingEnabled = false for inner RecyclerView so that BottomSheetBehavior finds another scrolling view
viewPager.children.find { it is RecyclerView }?.let {
(it as RecyclerView).isNestedScrollingEnabled = false
}
BottomSheetBehaviour only detects the first scrollable view. So it is always recommended to use only one scrollable view inside of it.
For More information check this answer bottomsheetbehavior-with-two-recyclerview
And this one also Scroll not working for multiple RecyclerView in BottomSheet
If you really want to have the two scrollable views I recommend you to take a look at this library also AndroidSlidingUpPanel
I have this problem - I guess someone can surely put light on what the heck is going wrong here...
My overall flow goes like this - Activity(#+id/activity) shows a fragment(#+id/image_container) from screen bottom when a button is tapped(keyboard closes if present and fragment shown sliding upwards from bottom), this fragment shows a viewpager with page indicator in linear layout, viewpager shows another fragment which contains recycler view with horizontal gridlayoutmanager. This recycler view contains various imageview and i need to arrange them keeping my rows fixed say 3 but columns can be variable based on screen width and density. Imageview has fixed height and width.
This is my activity layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/activity">
<include
layout="#layout/toolbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentTop="true" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="4dp"
android:id="#+id/divider"
android:layout_below="#+id/toolbar"/>
<include
layout="#layout/edit_bar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_below="#+id/divider"/>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/edit_bar" />
<FrameLayout
android:id="#+id/image_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/container"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
// Fragment inside the image_container
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="1">
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="12dp"
android:layout_weight=".9"/>
<LinearLayout
android:id="#+id/sliderDots"
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="center_vertical|center_horizontal"
android:orientation="horizontal"
android:layout_weight=".1"/>
// Fragment inside viewpager
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="26dp"
android:paddingRight="26dp">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
// Item inside recycler view
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/imageView"
android:layout_width="48dp"
android:layout_height="48dp"
tools:visibility="visible"
android:layout_margin="6dp"/>
// Fragment code which gets added to image_container upon button tap
FragmentManager fm = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.view_transition_up_from_bottom, R.anim.view_transition_down_to_bottom);
fragmentTransaction.add(R.id.image_container, new ImageFragment(activity.getApplicationContext())).commit();
Inside this ImageFragment i calculate the rows(this is fixed let's say 3) and columns(Math.round((dpWidth - 52) / 60)) - 52(26*2 - for both side of recycler view, 60 - space occupied my 1 item including width and margin(L+R)), hence i know the images to be shown in each page and pass it to ImageViewFragment containing the recycler view which is used by adapter.
I use
recyclerView.setLayoutManager(new CustomGridLayoutManager(getActivity(), 3, CustomGridLayoutManager.HORIZONTAL, false));
to make my recycler view and hence i use fixed rows.
So my question is -
1. I wrote the code to keep my rows fixed and calculate columns based on screen width but sometimes i see too much spacing from right side of recycler view to screen edge, i kept it fixed with 26 dp but it shows more that that. How can i implement this type of functionality where i see uniform spacing in grid form??
2. How to handle orientation change when grid fragment is open, my activity is not redrawn. as i see i can only override onConfigurationChanged.
I have created and xml file like:
<android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.AppBarLayout>
<android.support.design.widget.CollapsingToolbarLayout/>
<android.support.design.widget.AppBarLayout/>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
app:layout_behavior="CustomScrollingBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TableLayout
android:layout_width="fill_parent"
android:layout_height="?attr/actionBarSize"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="true"
app:layout_behavior="CustomScrollingBehavior"/>
<LinearLayout/>
<android.support.v4.widget.NestedScrollView/>
<android.support.design.widget.CoordinatorLayout/>
ViewPager has FragmentStatePagerAdapterand each fragment has a RecyclerView insdie. Everything is working fine except when loading content the first Fragment of the ViewPager has scrolling issue.
When I scroll first Fragment it gets stuck and does not scroll after the CollapsingToolbarLayout is collapsed completely. But after waiting for 2-3 seconds or switching to another fragment inside ViewPager and scrolling, it starts scrolling normally.
If anyone else has come across this problem please help me.
I'm currently working on app with a view hierarchy of CoordinatorLayout -> Viewpager -> Framelayout (contained in a fragment). The CoordinatorLayout ensures that the actionbar scrolls away when scrolling in the fragment.
The problem I'm facing is, that I would like to have a view in the bottom of the fragment that does not scroll, but instead always stays at the bottom of the fragment. The view should only exist in one of the fragments, meaning placing it outside the Viewpager does not work.
Is it possible to create a static view in the fragment (Framelayout)?
im not 100% sure if this is what your looking for if it isnt explain (with code) what your looking for.
good luck with the project
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="1"
android:id="#+id/coordinatorLayout"
android:fitsSystemWindows="true">
//Part that will be static
<ScrollView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/imageView2">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
//part in the scrollfiew
</LinearLayout>
</ScrollView>
</RelativeLayout>
I want to create a Fragment with a RecyclerView that slides up and shows more items as you slide it up.
Here is an example of what I am talking about.
Initial Creation:
User Swipes Up to slide RecyclerView up, shows more items:
There are a few issues, I would like to not use a CoordinatorLayout, and I would like to set it to where the items in the RecyclerView stack up directly on top of the EditText.
This is the layout code I am using:
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coordinatorLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#android:color/transparent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<View
android:id="#+id/emptyView"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#android:color/transparent"
app:layout_collapseMode="parallax"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="#+id/editText"
android:paddingLeft="16dp"
android:inputType="textAutoCorrect"
android:layout_centerVertical="true"
android:background="#android:color/transparent"
android:layout_width="match_parent"
android:layout_height="56dp"/>
</RelativeLayout>
</RelativeLayout>
And I get something like this:
This is definitely not scalable, and empty view would need to be consistently measured.
I solved this by using a custom TouchListener all of the other solutions were very basic and limited to a specific and boxed use-case.
The way I did this was to implement a new TouchListener based off of this library:
BounceTouchListener
I get the following results:
Use RecyclerView with 2 types of rows:
Empty row/rows colored gray (without divider)
Rows with content as you already have
The RecyclerView will have to match_parent to the entire fragment
So you will get the right effect of a "blank" area on top of the RecyclerView.
You can use setReverseLayout of LinearLayoutManager
Used to reverse item traversal and layout order. This behaves similar
to the layout change for RTL views. When set to true, first item is
laid out at the end of the UI, second item is laid out before it etc.
For horizontal layouts, it depends on the layout direction. When set
to true, If RecyclerView is LTR, than it will layout from RTL, if
RecyclerView} is RTL, it will layout from LTR. If you are looking for
the exact same behavior of setStackFromBottom(boolean), use
setStackFromEnd(boolean)