I want to implement view anchoring, I have a Horizontal ScrollView which I want to anchor to a button, the button files the screen width, in the ScrollView is a linearlayout with images, I want the Images to be looking like they are pass on the Button, I want to make something like how a Fab manages to anchor between view except I do not know where to start, Fab has attributes like app:layout_anchor="#+id/appbar"
app:layout_anchorGravity="bottom|right|end"
which make it very easy to anchor it, I once tried implementing anchoring but on Big screens it was cutting off from the anchor, below is my XML layout
<FrameLayout
style="#style/commonListItemStyle"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent">
<FrameLayout
android:id="#+id/container"
android:paddingTop="4dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:paddingBottom="4dp"
android:foreground="?attr/selectableItemBackground">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<HorizontalScrollView
android:layout_width="match_parent"
android:scrollbars="none"
android:id="#+id/scrollView"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/imageHolder"
android:orientation="horizontal">
<ImageView
android:layout_width="70dp"
android:layout_height="70dp"
android:src="#drawable/clothes"/>
</LinearLayout>
</HorizontalScrollView>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="2dp"
app:cardElevation="1dp"
android:layout_below="#+id/scrollView"
app:cardMaxElevation="2dp"
app:cardUseCompatPadding="true"
android:id="#+id/relativeLayout">
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Add New Item"
android:textStyle="bold"
android:id="#+id/addNewItem"
android:textSize="16sp"
style="?android:buttonBarButtonStyle"
android:textColor="#color/google_darkblue"
android:layout_weight="1"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
</FrameLayout>
</FrameLayout>
So I will give an example of Gem Player here https://android-arsenal.com/details/3/2679 I want the HorizontalScrollview to act like the Fab and the Button to act like the red view anchoring the fab, I want when Images are being scrolled within the Horizontal scrollview to look like they are halfway on the Button, I want the user to feel like the image is on the button.
Related
I am trying to move items between two recyclerviews, one of them into a bottom sheet.
I get this working without problems if the bottom sheet is in the same LinearLayout that the target recylcerview, as you can see in this gif:
This is the working layout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:orientation="vertical"
app:layout_constraintBaseline_toTopOf="parent"
android:gravity="center_horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="25sp"
android:paddingTop="20dp"
android:paddingBottom="10dp"
android:text="Target RecyclerView" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"/>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/bottom_sheet_dialog" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
My problem is when I try it with the bottom sheet overlapping the main content, I mean using a FrameLayout or Relativelayout as parent. In this case onDrag() is not fired outside the bottom sheet. Not working:
Not working layout, using a RelativeLayout:
<RelativeLayout 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=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:orientation="vertical"
app:layout_constraintBaseline_toTopOf="parent"
android:gravity="center_horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="25sp"
android:paddingTop="20dp"
android:paddingBottom="10dp"
android:text="Target RecyclerView" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"/>
</LinearLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/bottom_sheet_dialog" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</RelativeLayout>
I need the bottom sheet over the main content. Any idea?
Thanks!
Edit: Further investigations point that the problem is the CoordinatorLayout (which is a Bottom Sheet requirement). CoordinatorLayout is a "super-powered FrameLayout" and it acts at "top-level application decor", and I do not know why it does not allow onDrag events get views outside of CoordinatorLayout.
Workaround: For the moment my workaround is setting CorrdinatorLayout visibility to GONE when one of its views is dragged. This allow me to drop the view outside of CoordinatorLayout successfully, but I think should be some other way, some CoordinatorLayout parameter to allow dragging outside it.
I have a RecyclerView with a fixed height inside a NestedScrollView with a few other layouts inside it. The recycler view won't scroll, but it scrolls fine if I set its height to wrap_content.
I cannot make the RecyclerView use wrap_content because there is an issue with EndlessRecyclerViewScrollListener that it keeps loading data from the server and pushing it into my Adapter even if the user has not scrolled down at all.
Most are suggesting to set nested scrolling to false, but if I disable nested scrolling, the NestedScrollView does not allow me to scroll my RecyclerView. But if I leave nested scrolling enabled, the scroll view does not scroll unless I start touching from outside the RecyclerView.
My layout code:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/scoop_background"
tools:context=".module.scoop.timeline.ScoopTimelineFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="92dp">
<ImageView
android:id="#+id/ivTimelineBanner"
android:layout_width="match_parent"
android:layout_height="92dp"
android:layout_margin="0dp"
android:clickable="true"
android:padding="0dp"
android:scaleType="fitXY"
android:src="#drawable/banner_placeholder" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="92dp">
<TextView
android:id="#+id/tvGroupMembership"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textSize="#dimen/text_content" />
<TextView
android:id="#+id/tvGroupName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textSize="#dimen/text_header"
android:textStyle="bold" />
<TextView
android:id="#+id/tvGroupMemberCount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textSize="#dimen/text_content" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#null"
android:paddingStart="#dimen/divider_normal"
android:paddingEnd="#dimen/divider_normal"
android:src="#drawable/ic_chevron_right_white_24dp" />
</LinearLayout>
</FrameLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeRefreshLayoutTimeline"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.NestedScrollView
android:id="#+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="4dp">
<android.support.v7.widget.CardView
android:id="#+id/cvCreateScoop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/divider_small"
android:layout_marginRight="#dimen/divider_small"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="#dimen/divider_normal">
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:src="#drawable/svg_nav_create_scoop" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:paddingStart="#dimen/divider_normal"
android:text="What's on your mind?"
android:textSize="#dimen/text_content" />
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:padding="#dimen/divider_xsmall"
android:src="#drawable/svg_insert_image" />
</LinearLayout>
</android.support.v7.widget.CardView>
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
android:nestedScrollingEnabled="false"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingBottom="4dp">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
What do I have to modify so that the RecyclerView is scrollable, but the whole NestedScrollView also scrolls along with it, so that if the user is scrolling back up (swiping from top to bottom), the RecyclerView will scroll along with the NestedScrollView, which will bring the layouts above RecyclerView.
To visualize:
The layout I'm trying to achieve is similar to that of facebook's. When you scroll down, the timeline will scroll down, and the search bar with the messenger icon at the top is also scrolled so that it is hidden when scrolling down. When you scroll up, the timeline is being scrolled back up, and showing the search bar again.
I decided to do it differently because I wasn't able to solve it with this method. Instead, I used a CollapsingToolbar and put the other layouts inside it, then removing its background so it does not look like a toolbar, and it seamlessly does what I wanted to, just with a different implementation.
My app uses the SlidingUpPanel library. The main sliding up panel holds a RelativeLayout and a LinearLayout as its two children. The TabLayout is in the LinearLayout. Two of the tabs contain scrollable views and the third does not. All of the tabs are fragments.
The sliding up panel works as expected for the non-scrollable view and handles the first scrollable event on the scrollable views. However, the moment I release my finger, the scroll capability goes away and the view sticks.
Looking at other stackoverflow questions, I have tried setting the drag view and setting the scrollview as the documentation suggests but no dice. The view still sticks after the first scroll event.
I also implemented a ScrollableViewHelper as the documentation recommended but that didn't seem to help at all.
Here is a video of the behavior I am describing
SlidingUpPanel documentation on scrollable views
https://github.com/umano/AndroidSlidingUpPanel#scrollable-sliding-views
SlidingUpPanel Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:sothree="http://schemas.android.com/apk/res-auto"
android:id="#+id/eventDetailsFullLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.sothree.slidinguppanel.SlidingUpPanelLayout
android:id="#+id/eventDetailsSlidingUpPanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
sothree:umanoShadowHeight="4dp">
<RelativeLayout
android:id="#+id/eventDetailsHeaderLayout"
android:paddingTop="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/eventDetailsEventImageLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatImageView
android:id="#+id/eventDetailsEventBanner"
android:layout_width="match_parent"
android:layout_height="120dp"
android:background="#color/gray"
android:scaleType="fitXY" />
<LinearLayout
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_centerInParent="true"
android:background="#drawable/grey_circle"
android:gravity="center">
<android.support.v7.widget.AppCompatImageView
android:id="#+id/eventDetailsEventLogo"
android:layout_width="56dp"
android:layout_height="56dp"
android:gravity="center"
app:srcCompat="#drawable/ic_storefront" />
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/eventDetailsEventImageLayout"
android:layout_margin="16dp"
android:orientation="vertical">
<TextView
android:id="#+id/eventDetailsEventName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/darkDarkGray"
android:textSize="18sp"
app:fontFamily="sans-serif-medium" />
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/eventDetailsTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#color/teal"
app:tabSelectedTextColor="#color/teal"
app:tabTextColor="#color/gray" />
<android.support.v4.view.ViewPager
android:id="#+id/eventDetailsViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</com.sothree.slidinguppanel.SlidingUpPanelLayout>
</LinearLayout>
I wanna to build the layout like the diagram below. When I click the button a horizontal recyclerView slide up and appear at the bottom of the screen under the LinearLayout which contain the button.
I looking to use bottom sheet.When the bottom sheet with recyclerView appear,but it cover the whole LinearLayout which contain the button.Here is my layout xml:
<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:fitsSystemWindows="true">
<LinearLayout
android:id="#+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#color/white"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingTop="5dp">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#null"
android:text:"Button"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/horizontalRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_anchor="#id/bottomBar"
android:animateLayoutChanges="false"
android:scrollbars="horizontal"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"/>
</android.support.design.widget.CoordinatorLayout>
So my question is,how can I make the horizontal recyclerView slide up and appear from the bottom of the screen? Am I going the right direction? Or have a better approach to achieve this?
Thanks in advance.
You can achieve that in simple steps:
First keep your linear Layout orientation vertical by adding this.
android:orientation="vertical"
And then add recycler view below button inside linearLayout.Whenever you have to hide recyclerview keep the visibility of recyclerview as "gone" and to show keep visibility as "visible" like this.
Initially keep your recycler hidden in xml and by adding this line in xml
android:visibility="gone"
Thrn whenver button is clciked make your recycler appear in java like this
yourRecycler.setVisibility(View.VISIBLE);
Finally your xml should look like this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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:fitsSystemWindows="true">
<LinearLayout
android:id="#+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:orientation="vertical"
android:paddingBottom="5dp"
android:layout_alignParentBottom="true"
android:paddingTop="5dp">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#null"
android:text="button"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/horizontalRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:animateLayoutChanges="false"
android:scrollbars="horizontal"
/>
try below steps,
First, define XML like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_root"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3"
>
<Button
android:id="#+id/tv1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#FFF"
android:text="hello"
android:textStyle="bold"
android:layout_weight="1"
/>
<RecycleView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:visibility="gone"
>
</RecycleView>
</LinearLayout>
Second, initially set RecycleView visibility gone.
Third, on click of Button set RecycleView visibility visible in run time.
You can use this library.
https://github.com/umano/AndroidSlidingUpPanel
In XML Put RecyclerView in its layout
<com.sothree.slidinguppanel.SlidingUpPanelLayout
I was able to this somehow using RecyclerView. When I create a view for a specific item in my RecyclerView, the recyclerview item layout is matched to parent.
I am wondering if this is also possible using ScrollView?
Here's what I did so far:
ScrollView xml:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/scrollview_homescreen"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:id="#+id/linearlayout_homescreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="#layout/listitem_comic_menu"/>
<LinearLayout
android:id="#+id/linearlayout_comic_listings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
</ScrollView>
Content:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativelayout_homescreen"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageview_menu_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:adjustViewBounds="true" />
<ImageView
android:id="#+id/imageview_menu_title_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/starwars_webtoon_home_1_logo"
android:scaleType="fitXY"
android:adjustViewBounds="true" />
<Button
android:id="#+id/button_start_reading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_above="#+id/button_menu"
android:layout_marginBottom="18dp"
android:text="#string/button_start_reading"
android:gravity="start"
android:drawableRight="#drawable/ic_keyboard_arrow_right_black_24dp"
android:drawableEnd="#drawable/ic_keyboard_arrow_right_black_24dp"
android:background="#drawable/button_bg"
android:textSize="18sp"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp" />
<Button
android:id="#id/button_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="28dp"
android:text="#string/button_menu"
android:textSize="18sp"
android:textColor="#FFFFFF"
android:drawableLeft="#drawable/ic_menu_white_24dp"
android:drawableStart="#drawable/ic_menu_white_24dp"
android:background="?android:attr/selectableItemBackground" />
</RelativeLayout>
So what am I trying to do? Basically this is for comic listing. The first item should be the homescreen, a couple of button here and there and the entire application logo. The next item should show the listings (I have 40 items of the same width and height) and a footer.
I need my homescreen to match the parent which is the screen. So when I scroll the topmost part, the first item (the first view, which is the homescreen) fills the entire devices screen.
I was able to to do this on RecyclerView and looks nice. I have encountered some of problems that plague me which I have to fix extensively to the point that I am hacking through the system and I realize RecyclerView is not really the best layout for this kind of case. I am currently deciding whether to switch to ScrollView and dynamically/statically add the comic items. But, the homescreen, which is the first View is not matching the screen device.
I would just like to ask if this possible at all to do in ScrollView?
Thanks!
Use weight attribute:
<LinearLayout
android:id="#+id/linearlayout_homescreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<include layout="#layout/listitem_comic_menu"/>
<LinearLayout
android:id="#+id/linearlayout_comic_listings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>