I have a layout wich contains next views:
<android.support.v7.widget.RecyclerView
android:id="#+id/rvChat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/stickersContainer"
android:layout_alignParentTop="true" />
<ImageButton
android:id="#+id/ibChatSmile"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="6"
android:background="?attr/selectableItemBackgroundBorderless"
android:paddingBottom="8dp"
app:srcCompat="#drawable/smile" />
<LinearLayout
android:id="#+id/stickersContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical"
android:visibility="visible">
<android.support.design.widget.TabLayout
android:id="#+id/tbStickers"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/stickersPager"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_below="#+id/tbStickers"
android:visibility="gone" />
</LinearLayout>
stickersContainer - is layout which I want to show/hide. Recyclerview contains chat messages and ImageButton shows/hides
stickersContainer. As you see there are tabLayout and ViewPager in stickersContainer.
To ViewPager I load this fragment:
<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="wrap_content"
tools:context="com.oopslab.outarguemechat.Fragments.Stickers.StickersContainerFragment">
<GridView
android:id="#+id/gvStickersContainer"
android:layout_width="match_parent"
android:layout_height="200dp"
android:numColumns="3" />
for hiding/showing layout I use setVisibility() function;
and it seems all works well until I called notifyDataSetChanged() for recyclerview.
when I press a hide button it hides layout but button and recyclerview stayed at their places.
I'm really confused with this situation. I tried to put layout to the fragent and add/remove it but nothing helps
Also I tried adapter.notifyItemInserted() instead of notifyDataSetChanged() but had the same result
As you might guess, I'm trying to create something like sticker layout(like in viber/telegram/skype, etc).
May be there is another way to make it.
Thanks in advance!
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'm in stuck with my layout with a lot of recyclerViews (4).
If three recyclers have up to 20 items per each and they are GONE by default in xml, then fourth recycler has up to 100-400 items (not more) which are dynamically changing in code and it is VISIBLE by default.
I need to scroll (smoothly scroll, ofc) all of menu (layout) including all of it elements.
I was trying NestedScrollView, ScrollView for all layout, for pieces of layout, for recyclerViews.
I was trying this for RecyclerView: app:layout_behavior="#string/appbar_scrolling_view_behavior"
I was trying:
layoutManager.setAutoMeasureEnabled(true); //deprecated
recyclerView.setNestedScrollingEnabled(false);
I was trying android:descendantFocusability="blocksDescendants" for Nested
I was trying android:nestedScrollingEnabled="false" for RecyclerView
I was trying adapter.setHasStableIds(true);
I was trying to combine all of this things from stackoverflow and other resources.
I have achieved scrolling which I want just by simple adding NestedScrollView after my rootLayout (not smooth, but works correct), but only in AVD, real devices with up to 3GB RAM cannot handle adding of NestedScrollView - devices are getting infinite black screen and empty Logs.
Maybe I was trying to do something else and I've forgotten to type about them here. Comment about some another similar fixes and I will reply.
How I can achieve smooth scrolling all of rootLayout elements?
I know that rule about scrolling views inside of another scrolling views, but I need to scroll all of my scrollable recyclers.
<?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="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:id="#+id/rootLayout"
android:background="#color/float_transparent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/LLMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/gray21"
>
<RelativeLayout
android:id="#+id/RLTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<View
android:id="#+id/BluecolorView"
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="#color/colorBlue"
>
</View>
<View
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="#color/white"
android:layout_below="#+id/BluecolorView"
>
</View>
<FrameLayout
android:id="#+id/FLIV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
>
<ImageView
android:id="#+id/logoinmenu"
android:layout_width="50dp"
android:layout_height="50dp"
android:contentDescription="#string/logo"
android:src="#drawable/logoicon"
>
</ImageView>
</FrameLayout>
</RelativeLayout>
<TextView
android:id="#+id/TVUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="#dimen/textViewTextSize"
android:text=""
android:layout_gravity="center"
android:textColor="#color/white"
>
</TextView>
<LinearLayout
android:id="#+id/LLAllM"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="visible"
>
<LinearLayout
android:id="#+id/LL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="visible"
>
<LinearLayout
android:id="#+id/LLIVandBTG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="visible"
>
<ImageView />
<Button
android:id="#+id/BTGenresRV"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#color/float_transparent"
android:text="#string/genres"
android:textAllCaps="false"
android:textColor="#color/white"
android:gravity="start|top"
android:layout_marginStart="5dp"
>
</Button>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/RVGenresList"
android:layout_width="match_parent"
android:layout_height="150dp"
android:visibility="gone"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
Here are three more similar to "<LinearLayout android:id="#+id/LL" blocks...
</LinearLayout>
</LinearLayout>
</LinearLayout>
UPD:
I've forgotten to add that all of this handling by a public class MenuFragment extends Fragment implements View.OnTouchListener
Fragment are located in ActivityName extends AppCompatActivity
UPD2:
Partially fixed it by adding ScrollView after rootLayout and static height to recyclers.
Will see, maybe this is the best solution and I will provide full code in answer.
UPD3: This is because of wrap_content and match_parent I was not able to scroll like I need.
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
Ok, so i`m trying to get the scrollY atribute from my RecycleView (to see the position of where i am scrolling in the CardList. I have the following setup
First, the main activity , which houses a SlidingTabs layout, which has a SwipeToFresh layout as he child and a ViewPager for the 2 fragments of the tabs, like this :
<LinearLayout 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"
tools:context="com.example.popal.soul.MovieListActivity">
<com.example.popal.soul.SlidingTabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="2dp"
android:background="#color/ColorPrimary"/>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipeContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1">
</android.support.v4.view.ViewPager>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
Then i have each fragment with an identical layout, like this, with an RecycleView :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.RecyclerView
android:id="#+id/cardList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
And finally the layout for each card of the RecycleView (i don't think it matters, but i'll add it anyway)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
card_view:cardCornerRadius="4dp"
android:layout_margin="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/selectableItemBackground">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#color/bkg_card"
android:text="Movie Title"
android:gravity="center_vertical"
android:textColor="#android:color/white"
android:textSize="14dp"/>
<ImageView
android:elevation="5dp"
android:scaleType="fitCenter"
android:layout_width="100dp"
android:layout_height="150dp"
android:id="#+id/imageViewPoster"
android:text="Poster"
android:gravity="center_vertical"
android:layout_below="#id/title"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"/>
<ImageView
android:id="#+id/imageViewFanart"
android:scaleType="fitCenter"
android:layout_alignBottom="#+id/imageViewPoster"
android:layout_toEndOf="#+id/imageViewPoster"
android:layout_width= "235dp"
android:layout_height="122dp"
android:layout_marginRight="5dp"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
Now, i am trying to get the scrolling position of the RecycleView items from the main activity, where the SwipeToRefresh layout is defined. I need to do this to implement this workaround regarding a bug in the SwipeToRefresh layout, where trying to scroll up from the bottom of the list will trigger the refresh call : SwipeRefreshLayout + WebView when scroll position is at top , but as you can see, both solutions require access to the Swipe Container and RecycleView, in the same class or activity.
I tried using something like int scrollY = pager.getChildAt(pager.getCurrentItem()).getScrollY();
Which should theoretically return the position of the child item (in this case, the RecycleView) , but it still returns 0 (added log entries to get real-time events when the scrolling state has change), like if was still returning the position of the ViewPage adapter.
Anybody have an ideea?
As per earlier comment: You could define a simple listener interface that the hosting activity implements and through which the individual fragments can then pass their RecyclerView's scroll position (from their own local OnScrollListener).
This concept of communicating with fragments is described here in more detail with some sample code.
<LinearLayout 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"
tools:context=".MainActivity">
<EditText
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#drawable/location_edittext"
android:id="#+id/locationEditext"
android:textSize="15sp"
android:textColor="#999"
android:paddingLeft="15dp" />
<com.example.ravi_gupta.slider.ViewPagerCustomDuration
android:layout_width="wrap_content"
android:layout_height="0dp"
android:id="#+id/viewPager"
android:scrollbarStyle="outsideOverlay"
android:layout_weight="0.5">
</com.example.ravi_gupta.slider.ViewPagerCustomDuration>
<ListView
android:layout_weight="0.50"
android:layout_below="#+id/viewPager"
android:layout_marginTop="2dp"
android:layout_width="match_parent"
android:layout_height="45dp"
android:id="#+id/shopListview" />
This is my code in activity.main I, all I want is that when I scroll the listview it take all the space in the layout hiding viewpager and editext and when I scroll back it shows both of them, I don't know how this can be possible, Either I should use Relative layout or some Other method
You cannot simply depend on the layout. Modify your code and look at setVisibility method # setVisibility of View.
For example, if that method is set to GONE to EditText UI, then that UI is completely hidden as if it was never shown. And then of course, you should set it to VISIBLE when appropriate.