TabLayout 根本不会填充 ViewPager
TabLayout don't get populated with ViewPager at all
我尝试用 ViewPager
填充 TabLayout
但不幸的是它没有被填充。
我按照本教程取得联系:TabLayout
的 TabLayout and ViewPager in your Android App. The tutorial uses the old Support Library v4. My project is based on AndroidX and i want to stay with it. The official documentation 说我需要在 ViewPager
中创建 TabLayout
但这根本不起作用.所以我创建了以下 XML 布局文件:
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primaryColor"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabTextColor="@color/primaryTextColor" />
</androidx.viewpager.widget.ViewPager>
</LinearLayout>
我使用以下行设置 ViewPager 以将 TabLayout
与 ViewPager
连接:
public class MyActivity extends AppCompatActivity {
...
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_layout);
...
// tab layout
ViewPager viewPager = findViewById(R.id.viewpager);
MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(this, getSupportFragmentManager());
viewPager.setAdapter(adapter);
TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
...
}
...
}
我的适配器是FragmentPagerAdapter
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
private Context context;
public MyFragmentPagerAdapter(Context context, FragmentManager fm) {
super(fm);
this.context = context;
}
@Override
public Fragment getItem(int position) {
if (position == 0) {
return new MyFragment1();
} else {
return new MyFragment2();
}
}
@Override
public int getCount() {
return 2;
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return context.getString(R.string.building);
case 1:
return context.getString(R.string.buff);
default:
return null;
}
}
}
我的一个 Fragment
看起来像这样:
public class MyFragment1 extends Fragment {
public MyFragment () {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_building, container, false);
}
}
这是一张图片:
Empty ViewPager
问题
那么为什么 TabLayout
根本没有填充?我正在与 Android Studio 合作,设计经理只向我展示了一个空的 TabLayout
和 ViewPager
。我想,它会预编译 TabLayout
但它只是空的...
请帮助我,因为我一直停留在这个话题上。我真的很想像这样编写代码以获得滑动选项卡和其他东西的好处。
非常感谢!
- 将您的
TabLayout
放入您的 ViewPager
中,如下所示。
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabBackground="@color/colorPrimaryDark"
app:tabGravity="fill"
app:tabIndicatorColor="@color/colorPrimaryLight"
app:tabMaxWidth="0dp"
app:tabMode="scrollable"
app:tabRippleColor="@color/colorPrimaryLight"
app:tabSelectedTextColor="@color/colorPrimaryLight"
app:tabTextColor="@android:color/white" />
</androidx.viewpager.widget.ViewPager>
确保 TabLayout
的 android:layout_height
设置为 wrap_content
。
当你将 TabLayout 放在 ViewPager 中时,你不需要保留以下行:
TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
代码中的其他所有内容都是正确的。
此外,现在我看到了您的代码,TabLayout
的 layout_height
设置为 match_parent
,因此 TabLayout
占用了整个 space 在你的屏幕中,没有给 ViewPager
高度,同样,在你的 XML 中,没有容器来容纳你的 ViewPager
和 TabLayout
(比如 LinearLayout
, FrameLayout
等).
这是我的一个项目的示例。创建并填充 ViewPager
,类似这样:
<androidx.viewpager.widget.ViewPager
android:id="@+id/loginViewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/loginTitle">
<com.google.android.material.tabs.TabLayout
android:id="@+id/loginTabContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
app:tabIndicatorColor="@color/colorPrimary"
app:tabRippleColor="@color/colorPrimary"
app:tabSelectedTextColor="@color/colorPrimaryDark"
app:tabTextAppearance="@style/TabLayoutTheme">
<com.google.android.material.tabs.TabItem android:text="first tab" />
<com.google.android.material.tabs.TabItem android:text="second tab" />
</com.google.android.material.tabs.TabLayout>
</androidx.viewpager.widget.ViewPager>
然后在您的 activity 中创建一个 FragmentStatePagerAdapter
来决定每个页面中 return 的内容。我的代码在 kotlin 中,但 java 版本是相同的:
private inner class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
override fun getCount(): Int = NUM_PAGES
override fun getItem(position: Int): Fragment = when (position) {
1 -> FirstFragment()
0 -> SecondFragment()
else -> FirstFragment()
}
override fun getPageTitle(position: Int): CharSequence? {
return when (position) {
0 -> "First Title"
1 -> "Second Title"
else -> "First Title"
}
}
}
最后在你的 Activity:
val pagerAdapter = ScreenSlidePagerAdapter(supportFragmentManager)
loginViewPager.adapter = pagerAdapter
<android.support.design.widget.CoordinatorLayout 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.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:tabGravity="fill"
style="@style/Base.Widget.Design.TabLayout"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
viewPager = (ViewPager)rootView. findViewById(R.id.viewpager);
ViewPagerAdapter adapter = new ViewPagerAdapter(getFragmentManager());
adapter.addFragment(new FragAllONE(), "ONE");
adapter.addFragment(new FragAllTWO(), "TWO");
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(1);
viewPager.setCurrentItem(0);
viewPager.addOnPageChangeListener(this);
tabLayout = (TabLayout)rootView. findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
private class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position)
}
@Override
public int getCount() {
return mFragmentList.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Object object = super.instantiateItem(container, position);
if (object instanceof Fragment) {
Fragment fragment = (Fragment) object;
String tag = fragment.getTag();
}
return object;
}
public void restoreState(Parcelable state, ClassLoader loader) {
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
我在另一个线程 上找到了解决方案。我正在使用 Android 数据绑定,因此 TabLayout
未分配给 ViewPager
。所以我的代码是正确的,但不符合数据绑定。
尽管如此,还是感谢您在这里发帖!
我尝试用 ViewPager
填充 TabLayout
但不幸的是它没有被填充。
我按照本教程取得联系:TabLayout
的 TabLayout and ViewPager in your Android App. The tutorial uses the old Support Library v4. My project is based on AndroidX and i want to stay with it. The official documentation 说我需要在 ViewPager
中创建 TabLayout
但这根本不起作用.所以我创建了以下 XML 布局文件:
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primaryColor"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabTextColor="@color/primaryTextColor" />
</androidx.viewpager.widget.ViewPager>
</LinearLayout>
我使用以下行设置 ViewPager 以将 TabLayout
与 ViewPager
连接:
public class MyActivity extends AppCompatActivity {
...
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_layout);
...
// tab layout
ViewPager viewPager = findViewById(R.id.viewpager);
MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(this, getSupportFragmentManager());
viewPager.setAdapter(adapter);
TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
...
}
...
}
我的适配器是FragmentPagerAdapter
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
private Context context;
public MyFragmentPagerAdapter(Context context, FragmentManager fm) {
super(fm);
this.context = context;
}
@Override
public Fragment getItem(int position) {
if (position == 0) {
return new MyFragment1();
} else {
return new MyFragment2();
}
}
@Override
public int getCount() {
return 2;
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return context.getString(R.string.building);
case 1:
return context.getString(R.string.buff);
default:
return null;
}
}
}
我的一个 Fragment
看起来像这样:
public class MyFragment1 extends Fragment {
public MyFragment () {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_building, container, false);
}
}
这是一张图片:
Empty ViewPager
问题
那么为什么 TabLayout
根本没有填充?我正在与 Android Studio 合作,设计经理只向我展示了一个空的 TabLayout
和 ViewPager
。我想,它会预编译 TabLayout
但它只是空的...
请帮助我,因为我一直停留在这个话题上。我真的很想像这样编写代码以获得滑动选项卡和其他东西的好处。
非常感谢!
- 将您的
TabLayout
放入您的ViewPager
中,如下所示。
<androidx.viewpager.widget.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.tabs.TabLayout xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabBackground="@color/colorPrimaryDark" app:tabGravity="fill" app:tabIndicatorColor="@color/colorPrimaryLight" app:tabMaxWidth="0dp" app:tabMode="scrollable" app:tabRippleColor="@color/colorPrimaryLight" app:tabSelectedTextColor="@color/colorPrimaryLight" app:tabTextColor="@android:color/white" /> </androidx.viewpager.widget.ViewPager>
确保 TabLayout
的 android:layout_height
设置为 wrap_content
。
当你将 TabLayout 放在 ViewPager 中时,你不需要保留以下行:
TabLayout tabLayout = findViewById(R.id.tab_layout); tabLayout.setupWithViewPager(viewPager);
代码中的其他所有内容都是正确的。
此外,现在我看到了您的代码,
TabLayout
的layout_height
设置为match_parent
,因此TabLayout
占用了整个 space 在你的屏幕中,没有给ViewPager
高度,同样,在你的 XML 中,没有容器来容纳你的ViewPager
和TabLayout
(比如LinearLayout
,FrameLayout
等).
这是我的一个项目的示例。创建并填充 ViewPager
,类似这样:
<androidx.viewpager.widget.ViewPager
android:id="@+id/loginViewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/loginTitle">
<com.google.android.material.tabs.TabLayout
android:id="@+id/loginTabContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
app:tabIndicatorColor="@color/colorPrimary"
app:tabRippleColor="@color/colorPrimary"
app:tabSelectedTextColor="@color/colorPrimaryDark"
app:tabTextAppearance="@style/TabLayoutTheme">
<com.google.android.material.tabs.TabItem android:text="first tab" />
<com.google.android.material.tabs.TabItem android:text="second tab" />
</com.google.android.material.tabs.TabLayout>
</androidx.viewpager.widget.ViewPager>
然后在您的 activity 中创建一个 FragmentStatePagerAdapter
来决定每个页面中 return 的内容。我的代码在 kotlin 中,但 java 版本是相同的:
private inner class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
override fun getCount(): Int = NUM_PAGES
override fun getItem(position: Int): Fragment = when (position) {
1 -> FirstFragment()
0 -> SecondFragment()
else -> FirstFragment()
}
override fun getPageTitle(position: Int): CharSequence? {
return when (position) {
0 -> "First Title"
1 -> "Second Title"
else -> "First Title"
}
}
}
最后在你的 Activity:
val pagerAdapter = ScreenSlidePagerAdapter(supportFragmentManager)
loginViewPager.adapter = pagerAdapter
<android.support.design.widget.CoordinatorLayout 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.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:tabGravity="fill"
style="@style/Base.Widget.Design.TabLayout"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
viewPager = (ViewPager)rootView. findViewById(R.id.viewpager);
ViewPagerAdapter adapter = new ViewPagerAdapter(getFragmentManager());
adapter.addFragment(new FragAllONE(), "ONE");
adapter.addFragment(new FragAllTWO(), "TWO");
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(1);
viewPager.setCurrentItem(0);
viewPager.addOnPageChangeListener(this);
tabLayout = (TabLayout)rootView. findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
private class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position)
}
@Override
public int getCount() {
return mFragmentList.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Object object = super.instantiateItem(container, position);
if (object instanceof Fragment) {
Fragment fragment = (Fragment) object;
String tag = fragment.getTag();
}
return object;
}
public void restoreState(Parcelable state, ClassLoader loader) {
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
我在另一个线程 TabLayout
未分配给 ViewPager
。所以我的代码是正确的,但不符合数据绑定。
尽管如此,还是感谢您在这里发帖!