I am trying to achieve something like following
I am trying to build an activity joining 3 fragments. Top fragment contains a search bar (EditText), middle fragment has a Banner Slider (ViewPager), and the bottom fragment contains a GridView loaded with n number of items dynamically. I want to make the middle & bottom fragments scrollable vertically while the top one being fixed. But the Grid view is scrolling within itself while the height is set to wrap_content.
If the GridView is given a fixed height, it is working as expected. But I cannot give it a fixed height as its content is dynamically loaded.
Home Activity:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:background="#color/colorLightGray"
tools:context=".HomeActivity">
<ScrollView
android:id="#+id/scrollableContents"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:padding="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="#+id/fragmentContainerSearchBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
<FrameLayout
android:id="#+id/fragmentContainerSlider"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
<FrameLayout
android:id="#+id/fragmentContainerPopularItems"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
SearchBarFragment:
<?xml version="1.0" encoding="utf-8"?>
<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=".fragments.HomeSearchBarFragment">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="2dp"
android:paddingVertical="2dp"
android:focusable="true"
android:focusableInTouchMode="true">
<EditText
android:id="#+id/etSearchBoxHome"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="40dp"
android:drawableRight="#drawable/ic_search_24dp"
android:drawablePadding="5dp"
android:background="#drawable/et_search_home"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:layout_marginTop="0dp"
android:clickable="true"
android:cursorVisible="true"
android:focusable="true"
android:textSize="14dp"
android:hint="#string/home_searchbox_hint"/>
</RelativeLayout>
</FrameLayout>
Banner Slider Fragment:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="2dp"
tools:context=".fragments.HomePromoSliderFragment">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="2dp"
card_view:cardBackgroundColor="#color/colorWhite"
card_view:cardCornerRadius="3dp">
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</android.support.v7.widget.CardView>
</RelativeLayout>
Popular Items Fragment:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".fragments.HomePopularItemsFragment">
<GridView
android:id="#+id/gvPopularItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="150dp"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="columnWidth">
</GridView>
</RelativeLayout>
You can take nestedScrollView outside of ViewPager and Gridview.
Set the recycler View to setNestedScrollingEnable(false).
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
<GridView
android:layout_width="match_parent"
android:layout_height="match_parent">
</GridView>
</android.support.v4.widget.NestedScrollView>
Try using `Constraint Layout` for whole layout, `autocomplete text view` for search bar, `viewpager` for banners, recycler view for showing the loaded items.
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<AutoCompleteTextView
android:id="#+id/search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"/>
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent">
</android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
** Set the margins as per the UI
Set your layout manager as Gridlayout manager for recycler view as below:
recyclerview.layoutManager = GridLayoutManager(this, 2, OrientationHelper.VERTICAL, false)
Hope it will work fine. Let me know if you find any issues.
Related
I have a layout which is have title textview and recylerview below it.
It all works good. But I am trying to make the whole thing scrollable. Meaning that if I scroll down the rcylerview when new items are added, I want the title textview to scroll up (disappears) as if it is part of the recylerview
Here is my xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
android:text="Near me"
android:textColor="#color/White"
android:textSize="21sp"
android:textStyle="bold" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipeContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvVideos"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
I know that I can fake it so item 1 of the recylerview has a different layout which is the title text but I am hoping there is a better option so I don't have to deal with edge cases of number of items and manipulating positions
you need to wrap both the textview and recycler view in a NestedScrollView
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Textview"
android:layout_marginTop="10dp"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
I hope this helps...Cheers
I have an activity layout with 2 FrameLayout:
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context="de.sioned.multivoc.AddWordActivity"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<include layout="#layout/toolbar_layout"/>
<ScrollView
android:id="#+id/scLeft"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/paneLeft"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/paneLeftTop"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/paneLeftBottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/paneLeftTop"/>
</RelativeLayout>
</ScrollView>
</android.support.design.widget.CoordinatorLayout>
The 2nd FrameLayout paneLeftBottom will at some point contain the following fragment:
<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:orientation="vertical">
<RelativeLayout
android:id="#+id/lyTop"
android:layout_width="match_parent"
android:layout_height="wrap_content">
...some static fields...
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/lyTop">
<ListView
android:id="#+id/lvResult"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"/>
</RelativeLayout>
In this configuration the ListView is only shown with a height of one of it's rows instead several rows utilizing the available space. The ListView works fine but only one row at a time is displayed.
The same ListView fragment works fine when I put it into a 2-pane landscape layout. How can I make the ListView use the available space ?
Edit:
Found a partial solution by switching to a LinearLayout within the ScrollView. Only problem left is, that the bottom Framelayout overlays a bit of the top FrameLayout when I load the said fragment into it. But that is acceptable in this case as it is only temporary to select some data.
<ScrollView
android:id="#+id/scLeft"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
>
<LinearLayout
android:id="#+id/paneLeft"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/paneLeftTop"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/paneLeftBottom"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</ScrollView>
This right here
android:layout_width="match_parent"
android:layout_height="match_parent"
Should be
android:layout_width="match_parent"
android:layout_height="wrap_content"
Here is my xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:baselineAligned="false"
android:orientation="horizontal">
<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"
android:dividerHeight="10dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/content_main">
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/DrawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="7dp">
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="#+id/tool_bar"
layout="#layout/tool_bar"></include>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="#ffffff"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<android.support.v7.widget.RecyclerView
android:id="#+id/threadRecyclerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
</RelativeLayout>
</LinearLayout>
The main reason I did this design was to try to display the
<android.support.v7.widget.RecyclerView
android:id="#+id/threadRecyclerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
properly. However, when it is not being displayed at all. Before adding the two relativelayouts, I have one relative layout and the recyclerview did display, but it match_parent for every item of the list and was not able to fix it. How can I display my view properly?
The problem probably has to do with the layout_height="wrap_content" on your RecyclerView. You need to use setAutoMeasureEnabled(true) for wrap_content to work properly with a RecyclerView.
Here's an example:
RecyclerView threadRecyclerView = (RecyclerView)findViewById(R.id.threadRecyclerView);
threadRecyclerView.getLayoutManager().setAutoMeasureEnabled(true);
And your your XML should look something like this:
<android.support.v7.widget.RecyclerView
android:id="#+id/threadRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
app:layoutManager="LinearLayoutManager"/>
Hope that helps. :)
Note that setAutoMeasureEnabled only works properly for Android Support Library +23.2
I'm an activity that holds a gridview with movie posters and some overlay text with the movie title.
I made an extra layout for tablets that also displays details about the selected movie in the same activity.
The problem is that when I use the tablet in landscape mode, for some reason the first row of elements expands vertically, occupying all the available space.
Here's a picture so you know what the problem is:
http://postimg.org/image/rgwakvlq3/
This is my layout file for tablets:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="#+id/container"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity" tools:ignore="MergeRootFrame">
<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"
tools:context="com.example.madelenko.movierating.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<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:baselineAligned="false"
android:divider="?android:attr/dividerHorizontal"
android:orientation="horizontal"
tools:context="com.example.madelenko.movierating.MainActivity">
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:numColumns="#integer/column_count"
android:gravity="center"
android:verticalSpacing="#dimen/grid_vert_spacing"
android:stretchMode="columnWidth"/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:id="#+id/movie_detail_container"/>
</LinearLayout>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
</FrameLayout>
And this is the relative layout that contains the elements in each movie poster:
<?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="wrap_content"
android:id="#+id/grid_element_parent">
<!-- View to be populated with a movie poster-->
<ImageView
android:id="#+id/image_thumbnail"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!--View to be populated with the movie's title and rating-->
<TextView
android:layout_width="#integer/image_width"
android:layout_height="#dimen/text_overlay_height"
android:background="#00000000"
android:textColor="#00000000"
android:gravity="center"
android:layout_centerHorizontal="true"
android:id="#+id/overlay_text"/>
</RelativeLayout>
The correct UI should look like this:
http://postimg.org/image/939s90085/
(But with 3 cols instead of 2)
How can I fix this?
Thank you very much.
Add this line to your ImageView:
android:adjustViewBounds="true"
I have two fragments, each with its own respective RecyclerView list.
The RecyclerView from each of the fragments may contain many items. So, scrolling will mostly be necessary.
My problem is, how do I combine and display these two fragments into one screen using ScrollView, but at the same time, making the scrolling of the RecyclerViews behave as normally (non-sticky, follows the entire screen's scroll).
Thanks.
EDIT:
My layout file
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.easyuni.courserecommender.ResultsActivity">
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_below="#+id/toolbar">
<FrameLayout
android:id="#+id/fragment_container_results_career"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<View
android:id="#+id/divider"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_below="#+id/fragment_container_results_career"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="#color/divider" />
<FrameLayout
android:id="#+id/fragment_container_results_courses"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemIconTint="#333"
app:itemTextColor="#333" />
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
Screenshot:
(Notice the RecyclerView at the top and bottom scrolls individually)
https://drive.google.com/file/d/0B-glHmJbVcwiVU41WVRHU3g2bkE/view
You can do like this one -
In your activity's layout file, you should have two framelayout for containing your two fragment.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/first_fragment_container"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
</FrameLayout>
<FrameLayout
android:id="#+id/second_fragment_container"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
</FrameLayout>
</LinearLayout>
Then in your Activity's onCreate() method, you can use FragmentManager class to add Fragment to the FrameLayout.
getSupportFragmentManager().beginTransaction().add(R.id.first_fragment_container, new YourFirstFragment()).commit();
getSupportFragmentManager().beginTransaction().add(R.id.second_fragment_container, new YourSecondFragment()).commit();