[英]Adnroid ViewPager2 wrap content of asynchronous fragment child
I got a ViewPager2 widget inside a scrollview which i want to set the height similar to the content of the current shown fragment.我在滚动视图中有一个 ViewPager2 小部件,我想将其设置为类似于当前显示片段的内容的高度。 The fragments hold either a gridview or a listview which height is set to wrap_content.
片段包含 gridview 或高度设置为 wrap_content 的列表视图。
The problem is that the gridview gets filled with content after the fragment view was created so the viewpager gets a child height of "0".问题是 gridview 在创建片段视图后被内容填充,因此 viewpager 的子高度为“0”。 Also the height of every fragment can be different to the others.
每个片段的高度也可以与其他片段不同。
If I set the gridview height to eg 500dp everything works fine.如果我将 gridview 高度设置为例如 500dp 一切正常。
Is there some sort of listener to detect when the gridview is filled with content / the height of the gridview changed to set the viewpager heigth similar to the height of the fragment?是否有某种侦听器可以检测 gridview 何时充满内容/ gridview 的高度已更改为将 viewpager 高度设置为类似于片段的高度?
I already tried the solutions described here我已经尝试过这里描述的解决方案
How to wrap height of Android ViewPager2 to height of current item? 如何将 Android ViewPager2 的高度包装到当前项目的高度? and
和
ViewPager2 with differing item heights and WRAP_CONTENT 具有不同项目高度和 WRAP_CONTENT 的 ViewPager2
Layouts:布局:
ViewPager:浏览器:
<RelativeLayout>
<androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/viewPagerID"
android:background="@color/light_blue">
</androidx.viewpager2.widget.ViewPager2>
</RelativeLayout>
ScrollView:滚动视图:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/top_navigation_view_bar"
android:id="@+id/center"
android:layout_above="@id/bottom_navigation_view_bar">
<include layout="@layout/layout_viewpager"> </include>
</ScrollView>
Test Fragment:测试片段:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black">
<GridView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/black"
android:id="@+id/grid_fragment_0"
android:verticalSpacing="2dp"
android:horizontalSpacing="2dp"
android:stretchMode="columnWidth"
android:gravity="top"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp">
</GridView>
</RelativeLayout>
Set up the ViewPager设置 ViewPager
Function in the activity活动中的Function
private void setUpFragmentsTest(){
String[] fragment_names = {"Fragment0", "Fragment1", "Fragment2"};
mViewPager2 = (ViewPager2) findViewById(R.id.viewPagerID);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
SectionsPagerAdapterNew sectionsPagerAdapterNew = new SectionsPagerAdapterNew(this);
sectionsPagerAdapterNew.addFragment(new Fragment0());
sectionsPagerAdapterNew.addFragment(new Fragment1());
sectionsPagerAdapterNew.addFragment(new Fragment2());
mViewPager2.setAdapter(sectionsPagerAdapterNew);
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
tabLayout, mViewPager2, (tab, position) -> {
tab.setText(fragment_names[position]);
});
tabLayoutMediator.attach();
}
Section pager adapter class:部分寻呼机适配器class:
public class SectionsPagerAdapterNew extends FragmentStateAdapter {
private static final String TAG = "SectionsPagerAdapter";
private final List<Fragment> mFragmentList = new ArrayList<>();
public SectionsPagerAdapterNew(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
public SectionsPagerAdapterNew(@NonNull Fragment fragment) {
super(fragment);
}
public SectionsPagerAdapterNew(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
@NonNull
@Override
public Fragment createFragment(int position) {
return mFragmentList.get(position);
}
@Override
public int getItemCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment){
mFragmentList.add(fragment);
}
}
So I gave up with setting the ViewPager2 height within the xml layout.所以我放弃了在 xml 布局中设置 ViewPager2 的高度。 In my case I just need the ViewPager to cover the free area which isn't used by any navigation.
在我的情况下,我只需要 ViewPager 来覆盖任何导航都不使用的空闲区域。 Therefore I calculated the height pixels of the viewpager depending on the display size and ratio to fit between the top header / TabLayout and the bottom navigation (you will see in the code below).
因此,我根据显示大小和比例计算了 viewpager 的高度像素,以适应顶部 header / TabLayout 和底部导航(您将在下面的代码中看到)。
Changes:变化:
ViewPager2 Widget: ViewPager2 小部件:
<RelativeLayout>
<androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/viewPagerID"
android:background="@color/light_blue">
</androidx.viewpager2.widget.ViewPager2>
</RelativeLayout>
Function inside the activity: Function 里面的活动:
private void setUpFragmentsTest(){
//SET UP THE VIEWPAGER THAT HOLDS THE PROFILE CONTENT FRAGMENTS
String[] fragment_names = {"Fragment0", "Fragment1", "Fragment2"};
mViewPager2 = (ViewPager2) findViewById(R.id.activity_profile_viewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.activity_profile_tab_layout);
SectionsPagerAdapterNew sectionsPagerAdapterNew = new SectionsPagerAdapterNew(this);
sectionsPagerAdapterNew.addFragment(new Fragment0());
sectionsPagerAdapterNew.addFragment(new Fragment1());
sectionsPagerAdapterNew.addFragment(new Fragment2());
//SET THE VIEWPAGER HEIGHT RELATIVE TO THE DISPLAY METRICS & DISPLAY RATIO
//GET THE METRICS & DISPLAY RATIO USED BY THE DIFFERENT NAVIGATION BARS
ViewGroup.LayoutParams tabLayoutLayoutParams = tabLayout.getLayoutParams();
ViewGroup.LayoutParams navigationViewLayoutParams = findViewById(R.id.bottom_navigation_view_bar).getLayoutParams();
Resources resources = ProfileActivity.this.getResources();
int androidTopBarID = resources.getIdentifier("status_bar_height", "dimen", "android");
float androidTopBarHeight = resources.getDimensionPixelSize(androidTopBarID);
//SETTING THE ACTUAL VIEWPAGER HEIGHT
float pixelsUsedByNavigation = tabLayoutLayoutParams.height + (2* navigationViewLayoutParams.height);
//2* navigationViewLayoutParams.height because I'm using a top and bottom navigation bar, if there is just 1 don't double that value
ViewGroup.LayoutParams viewPagerLayoutParams = mViewPager2.getLayoutParams();
DisplayMetrics displayMetrics = ProfileActivity.this.getResources().getDisplayMetrics();
float viewpagerHeight;
float ratio = ((float)displayMetrics.heightPixels / (float)displayMetrics.widthPixels);
if(ratio > 1.667){
//LONG DISPLAY RATIO
viewpagerHeight = displayMetrics.heightPixels - pixelsUsedByNavigation;
}
else {
//NOT LONG DISPLAY RATIO
viewpagerHeight = displayMetrics.heightPixels - pixelsUsedByNavigation - androidTopBarHeight;
}
viewPagerLayoutParams.height = Math.round(viewpagerHeight);
mViewPager2.setLayoutParams(viewPagerLayoutParams);
mViewPager2.setAdapter(sectionsPagerAdapterNew);
//SET UP THE TAB LAYOUT TO DISPLAY AND HIGHLIGHT THE CURRENT FRAGMENT NAME
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
tabLayout, mViewPager2, (tab, position) -> {
tab.setText(fragment_names[position]);
});
tabLayoutMediator.attach();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.