This is the screenshot of one of my fragments (device: Xiaomi Redmi 2)
The fragment is divided into 4 parts:
A ViewPager to display image ads
A ViewPager indicator
A RecyclerView which contains a bunch of CardViews (to display news)
An AHBottomNavigation
And this is its corresponding XML layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="3">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:orientation="vertical"
android:weightSum="1.5">
<!-- for displaying ads -->
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.0" />
<LinearLayout
android:id="#+id/llDots"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_weight="0.5"
android:gravity="center"
android:background="#android:color/black"
android:orientation="horizontal" />
</LinearLayout>
<!-- for displaying news -->
<android.support.v7.widget.RecyclerView
android:id="#+id/news_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.5" />
<!-- bottom navigation -->
<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
I think the height of the ViewPager Indicator and the AHBottomView is right. But the ViewPager height is too much. What I want is the height of the ViewPager to fit the height of the image ads, and the height of the RecyclerView is bigger. I tried reducing the value weightSum (of the top LinearLayout) from 3 to 2.5, turns out the the AHbottomNavigation is not visible anymore.
Change like below
1. Replace xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
>
<!-- for displaying ads -->
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:id="#+id/llDots"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:background="#android:color/black"
android:orientation="horizontal" />
<!-- for displaying news -->
<android.support.v7.widget.RecyclerView
android:id="#+id/news_list"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content"
/>
</LinearLayout>
<!-- bottom navigation -->
<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
2.change view pager with wrap content
You can use the below code.
public class WrapContentViewPager extends ViewPager {
private int mCurrentPagePosition = 0;
public WrapContentViewPager(Context context) {
super(context);
}
public WrapContentViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
try {
View child = getChildAt(mCurrentPagePosition);
if (child != null) {
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
}
} catch (Exception e) {
e.printStackTrace();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void reMeasureCurrentPage(int position) {
mCurrentPagePosition = position;
requestLayout();
}
}
Declare it in xml:
<your.package.name.WrapContentViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</your.package.name.WrapContentViewPager>
And call reMeasureCurrentpage function on page swipe.
final WrapContentViewPager wrapContentViewPager = (WrapContentViewPager) findViewById(R.id.view_pager);
wrapContentViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
wrapContentViewPager.reMeasureCurrentPage(wrapContentViewPager.getCurrentItem());
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
happy coding :)
Related
I got help from links and other links but it didn't help me and my problem was not solved
MY PROBLEM: I have ViewPager with 3 Fragment that 2 of them contain RecycleView with dynamic data!
Now the ViewPage gets the biggest height !!!! I want to set the height of the fragment as the original size!
my code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
style="#style/CardStyle"
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">
<com.duolingo.open.rtlviewpager.RtlViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_marginTop="#dimen/default_margin_double"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tab_layout" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
style="#style/TabbedCard"
android:layout_width="match_parent"
android:layout_height="#dimen/tabbed_card_tab_layout_height"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabGravity="fill"
app:tabMode="scrollable"
app:tabPaddingTop="#dimen/default_margin_half"
app:tabTextAppearance="#style/investTab" />
</androidx.constraintlayout.widget.ConstraintLayout>
and one of my fragment that contains RecyclerView :
<LinearLayout 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="wrap_content"
android:layout_gravity="center"
android:scrollbarStyle="insideOverlay"
android:orientation="vertical"
tools:context=".mvvm.screens.investment.view.fragment.tabs.RequestListFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/account_list"
style="#style/InvestmentRecyclerView"
android:scrollbarStyle="insideOverlay"
tools:listitem="#layout/investment_request_item"
android:paddingBottom="#dimen/default_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="#+id/loading"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="?attr/cardTitle"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="#+id/view_error"
layout="#layout/view_error"
android:visibility="gone" />
<include
android:id="#+id/view_empty"
layout="#layout/no_investment_found"
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
Finally, I Create custom class from ViewPager like this :
public class WrappedHeightTabbedCardViewPager extends NonSwipeableViewPager {
private int currentPagePosition = 0;
public WrappedHeightTabbedCardViewPager(#NonNull Context context) {
super(context);
}
public WrappedHeightTabbedCardViewPager(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
View child = getChildAt(currentPagePosition);
if (child != null) {
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
}
if (heightMeasureSpec != 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void reMeasureCurrentPage(int position) {
currentPagePosition = position;
requestLayout();
}
}
I am trying to add a fragment on Activity which is having a custom view.
private void loadMonitorPage(){
fragmentManager = getFragmentManager();
MonitorFragment monitorFragment = new MonitorFragment();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.MainContentFrameLayout,monitorFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
Here MainContentFrameLayout is the second block I have mentioned in First image.
This is my Fragment Layout xml(fragment_monitor)
<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:background="#color/colorContentApp"
tools:context="fragments.MonitorFragment">
<monitorView.GridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorAccent"
/>
</LinearLayout>
instead of this Custom View is covering the full screen
This is my CustomView Class
public class GridView extends View {
private Paint mgridpaint;
private float mGridViewWidth;
private float mGridViewHeight;
private Canvas mGridCanvas;
public GridView(Context context) {
super(context);
}
public GridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// TODO: consider storing these as member variables to reduce
// allocations per draw cycle.
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int contentWidth = getWidth() - paddingLeft - paddingRight;
int contentHeight = getHeight() - paddingTop - paddingBottom;
mgridpaint = new Paint();
mgridpaint.setColor(Color.rgb(0,255,0));
mGridCanvas = canvas;
mGridViewWidth = contentWidth;
mGridViewHeight = contentHeight;
//drawGrid();
}
}
This is my parent Layout. Second FrameLayout where I am adding this Fragment
<LinearLayout 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"
tools:context="com.mactrical.mindoter.MainActivity"
android:weightSum="10"
android:orientation="vertical"
tools:showIn="#layout/app_bar_main">
<FrameLayout
android:id="#+id/ECGDetailsFrameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:background="#color/colorHeaderApp">
</FrameLayout>
<FrameLayout
android:id="#+id/MainContentFrameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="8">
</FrameLayout>
<FrameLayout
android:id="#+id/ECGFooterFrameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:background="#color/colorFooterApp">
</FrameLayout>
</LinearLayout>
Please help me!!!!! :-(
I figured out the problem
Here in this layout I had to use 0dp for my height instead of wrap_content
<LinearLayout 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"
tools:context="com.mactrical.mindoter.MainActivity"
android:weightSum="10"
android:orientation="vertical"
tools:showIn="#layout/app_bar_main">
<FrameLayout
android:id="#+id/ECGDetailsFrameLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.5"
android:background="#color/colorHeaderApp">
</FrameLayout>
<FrameLayout
android:id="#+id/MainContentFrameLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="8">
</FrameLayout>
<FrameLayout
android:id="#+id/ECGFooterFrameLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:background="#color/colorFooterApp">
</FrameLayout>
</LinearLayout>
I am trying to design this page
but I have design like this ( both fragment are there but the pagertabstrip of unseen page only see when I moved to this page )
Issue Facing
How would I set the width of the PagerTabStrip so that both login and register( highlighted in the first image) is visible in the same page.
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:weightSum="2"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_weight="1.6"
android:gravity="center"
android:id="#+id/logo"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:textSize="25dp"
android:gravity="center"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large"
android:textStyle="bold"
android:text=""
android:visibility="visible"
android:src="#drawable/logo_new"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView8" />
</LinearLayout>
<LinearLayout
android:layout_weight="0.4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v4.view.ViewPager
app:tabMode="fixed"
android:id="#+id/vpPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTabStrip
app:tabMode="fixed"
android:id="#+id/pager_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="4dp"
android:paddingTop="4dp" />
</android.support.v4.view.ViewPager>
</LinearLayout>
</LinearLayout>
Java File
public class Authentication extends AppCompatActivity {
FragmentPagerAdapter adapterViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.authentication);
SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Boolean login_already=app_preferences.getBoolean("login",false);
if (login_already)
{
startActivity(new Intent(Authentication.this,MainActivity.class));
finish();
}
ViewPager vpPager = (ViewPager) findViewById(R.id.vpPager);
adapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
vpPager.setAdapter(adapterViewPager);
// Attach the page change listener inside the activity
vpPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
// This method will be invoked when a new page becomes selected.
#Override
public void onPageSelected(int position) {
Toast.makeText(Authentication.this,
"Selected page position: " + position, Toast.LENGTH_SHORT).show();
}
// This method will be invoked when the current page is scrolled
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Code goes here
}
// Called when the scroll state changes:
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
#Override
public void onPageScrollStateChanged(int state) {
// Code goes here
}
});
}
public static class MyPagerAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 2;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
return Login.newInstance(0, "Login");
case 1: // Fragment # 0 - This will show FirstFragment different title
return Registration.newInstance(1, "Register");
default:
return null;
}
}
// Returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
if (position==0)
return "Login";
else
return "Register";
//return "Page " + position;
}
}
}
That layout xml worked for me...
EDIT: Oh sry i'm using another lib:
https://github.com/jpardogo/PagerSlidingTabStrip
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.astuetz.PagerSlidingTabStrip
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="48dip"
android:textColor="#FFFFFFFF"
app:pstsDividerColor="#FFFFFFFF"
app:pstsDividerPadding="10dp"
app:pstsDividerWidth="1dp"
app:pstsIndicatorColor="#FF33B5E6"
app:pstsIndicatorHeight="5dp"
app:pstsTabPaddingLeftRight="20dip"
app:pstsUnderlineColor="#FF33B5E6">
</com.astuetz.PagerSlidingTabStrip>
<FrameLayout
android:id="#+id/movie_framelayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.view.ViewPager
android:id="#+id/movie_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v4.view.ViewPager>
</FrameLayout>
</LinearLayout>
</FrameLayout>
When you want to display only selected tab and other will hide then set your PagerTabStrip as bellow.
<android.support.v4.view.PagerTabStrip
android:id="#+id/pager_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="4dp"
android:paddingTop="4dp"
app:tabMode="scrollable"
app:tabTextColor="#000000"
app:tabSelectedTextColor="#ff0000"
app:tabIndicatorColor="#ff0000"/>
app:tabTextColor="" is your normal tab text color.
app:tabSelectedTextColor="" is color of your selected tab.
app:tabIndicatorColor="" is your selected tab indicatore color.
So use as per your requirement. For detail that how to use tab layout then check this tutorial.
I'm facing a strange problem. I have a xml with two RecyclerView and a ViewPager with circle page indicator inside a NestedScrollview. I have used layout_weight and weightSum to show widget on screen. One of RecyclerView has horizontal layout which is scrolling horizontally fine. I want to achieve single vertical scrolling but unfortunately it is not working.
I have used "app:layout_behavior="#string/appbar_scrolling_view_behavior" in xml and "recyclerview.setNestedScrollingEnabled(false)" in java code.
here is my fragment_home.xml
<android.support.v4.widget.NestedScrollView 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/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_vertical"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.e2e.qnamo.fragment.HomeFragment">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="10"
android:descendantFocusability="blocksDescendants">
<include
layout="#layout/layout_pager_indicator"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_hot_topic"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:layout_weight="2"
tools:listitem="#layout/hot_topic_row" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_category"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:layout_weight="5"
tools:listitem="#layout/category_row"/>
</LinearLayout>
here is my layout_pager_indicator.xml
<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"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="#+id/bannerViewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="#layout/viewpager_indicator_single_item" />
<com.e2e.qnamo.widget.CirclePageIndicator
android:id="#+id/pager_indicator"
style="#style/CustomCirclePageIndicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_gravity="center|bottom"/>
Seems like every one was busy else where :) Anyway I managed to find solution by myself.
There were three potential problem which causing problem:
Using "weightSum" in parent layout and
ViewPager in layout
ViewPager takes whole screen by default.
I have used "weightSum" to control size of ViewPager and showing other two Recyclerview. To remove "weightSum" I customised ViewPager so that it only takes height of its biggest children. Below are the customised ViewPager code:
public class CustomViewPager extends ViewPager
{
private int mCurrentPagePosition = 0;
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for(int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if(h > height) height = h;
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void reMeasureCurrentPage(int position) {
mCurrentPagePosition = position;
requestLayout();
}
}
Second step I did that I removed "layout_weight" from both of RecyclerView and set it "layout_height" to "wrap_content" and work done.
Below are the updated layout code:
fragment_home.xml
<android.support.v4.widget.NestedScrollView 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/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_vertical"
android:fillViewport="true"
tools:context="com.e2e.qnamo.fragment.HomeFragment">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/main_container_margin"
android:layout_marginTop="#dimen/main_container_margin"
android:layout_marginRight="#dimen/main_container_margin"
android:layout_marginBottom="#dimen/main_container_margin"
android:orientation="vertical">
<include
layout="#layout/layout_pager_indicator"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_hot_topic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/recycler_margin_top"
tools:listitem="#layout/hot_topic_row" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_category"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/recycler_margin_top"
android:layout_marginBottom="10dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:listitem="#layout/category_row"/>
</LinearLayout>
layout_pager_indicator.xml
<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"
android:orientation="vertical">
<com.e2e.qnamo.widget.CustomViewPager
android:id="#+id/bannerViewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="#layout/viewpager_indicator_single_item" />
<com.e2e.qnamo.widget.CirclePageIndicator
android:id="#+id/pager_indicator"
style="#style/CustomCirclePageIndicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_gravity="center|bottom"/>
Thats it!!!
I have a RecyclerView as the only child of SwipeRefreshLayout, I want the RecyclerView wrap_content. When I set both of them "wrap_content", it doesn't work. The RecyclerView with fewer items also match_parent. When i delete SwipeRefreshLayout, the RecyclerView will wrap_content. Can anyone help me? My English is poor, Maybe you cann't understand. Anyone can help me? Thank you very much.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container_v"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00ffff">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff00ff">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
Finally, I work out it. From this Answer
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container_v"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00ffff">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff00ff"/>
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
The key is to use Layout wrap RecyclerView. Beacause of SwipeRefreshLayout use MeasureSpec.EXACTLY mode measure mTarget size when onMeasure():
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mTarget == null) {
ensureTarget();
}
if (mTarget == null) {
return;
}
mTarget.measure(MeasureSpec.makeMeasureSpec(
getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
getMeasuredHeight() - getPaddingTop() - getPaddingBottom(), MeasureSpec.EXACTLY));
......
}
And mTarget is the first child view of SwipeRefreshLayout. So this will cause the mTarget always match parent.
private void ensureTarget() {
// Don't bother getting the parent height if the parent hasn't been laid
// out yet.
if (mTarget == null) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (!child.equals(mCircleView)) {
mTarget = child;
break;
}
}
}
}
FrameLayout is used because it is more lightweight.
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingBottom="10dp"
tools:itemCount="2"
tools:listitem="#layout/item_msg_detail_text_style" />
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>