Java 为什么Android材质设计选项卡布局不起作用?
我正在尝试使用viewpager创建表格布局,但它不起作用。通过Java 为什么Android材质设计选项卡布局不起作用?,java,android,android-studio,gradle,sdk,Java,Android,Android Studio,Gradle,Sdk,我正在尝试使用viewpager创建表格布局,但它不起作用。通过tabLayout.setupWithViewPager(viewPager)加载时在PatientMain活动类中,输出为: 当我使用viewPager.addOnPageChangeListener(新建TabLayout.TabLayoutOnPageChangeListener(TabLayout))在PatientMain活动类中,输出为: 但是没有显示片段,也没有可用的滑动 我照章办事,正如人们所说的那样。我使用了一
tabLayout.setupWithViewPager(viewPager)加载时代码>在PatientMain活动类中,输出为:
当我使用viewPager.addOnPageChangeListener(新建TabLayout.TabLayoutOnPageChangeListener(TabLayout))代码>在PatientMain活动类中,输出为:
但是没有显示片段,也没有可用的滑动
我照章办事,正如人们所说的那样。我使用了一些源代码,比如,。我个人认为代码可能不是问题所在,所使用的sdk版本有问题,但我可能错了。这是我的密码:
主要活动:
package parsa.lop.adjust;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TabHost;
public class PatientMain extends AppCompatActivity {
private TabHost tabHost;
private TabLayout tabLayout;
private ViewPager viewPager;
private ViewPagerAdapter viewPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_patient_main);
tabLayout = (TabLayout)findViewById(R.id.tabLayout);
viewPager = (ViewPager)findViewById(R.id.viewPager);
viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPagerAdapter.addFragment(new MyDietFragment(), "My Diet"); // `new MyDietFragment()` should be in `FragmentPagerAdapter.getItem()`
viewPagerAdapter.addFragment(new MyWorkoutFragment(), "My Workout"); // `new MyWorkoutFragment()` should be in `FragmentPagerAdapter.getItem()`
viewPagerAdapter.addFragment(new StartProgramFragment(), "Start a Program"); // `new StartProgramFragment()` should be in `FragmentPagerAdapter.getItem()`
viewPager.setAdapter(viewPagerAdapter);
final TabLayout.Tab myDietTab = tabLayout.newTab();
final TabLayout.Tab myWorkOutTab = tabLayout.newTab();
final TabLayout.Tab startProgramTab = tabLayout.newTab();
myDietTab.setText("My Diet");
myWorkOutTab.setText("My Workout");
startProgramTab.setText("Start a Program");
tabLayout.addTab(startProgramTab,0);
tabLayout.addTab(myDietTab,1);
tabLayout.addTab(myWorkOutTab,2);
// tabLayout.setupWithViewPager(viewPager);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
}
android:theme="@style/AppTheme.NoActionBar"
ViewPager适配器:
package parsa.lop.adjust;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import java.util.ArrayList;
import java.util.List;
public class ViewPagerAdapter extends FragmentPagerAdapter {
private List<String> fragmentTitleList = new ArrayList<String>();
private List<Fragment> fragmentList = new ArrayList<Fragment>(); // this line can cause crashes
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position); // viewPager fragments should be created here
}
@Override
public int getCount() {
return 0; // this is the bug :p
}
@Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
public void addFragment(Fragment fragment, String title){
fragmentList.add(fragment); // this line can cause crashes
fragmentTitleList.add(title);
}
}
我的主要布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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=".PatientMain">
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/colorPrimary"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</android.support.constraint.ConstraintLayout>
在ViewPagerAdapter中,替换以下内容:
@Override
public int getCount() {
return 0;
}
为此:
@Override
public int getCount() {
return fragmentList.size();
}
您正在将适配器内容的计数设置为0,这与适配器告诉其他组件它没有要显示的项相同
此外,您应该确保由ViewPager承载的片段是在FragmentPagerAdapter.getItem()中创建的,而不是在活动中创建的。在ViewPagerAdapter中,替换以下内容:
@Override
public int getCount() {
return 0;
}
为此:
@Override
public int getCount() {
return fragmentList.size();
}
您正在将适配器内容的计数设置为0,这与适配器告诉其他组件它没有要显示的项相同
此外,您应该确保ViewPager承载的片段是在FragmentPagerAdapter.getItem()中创建的,而不是在活动中创建的。您还应该取消注释:
tabLayout.setupWithViewPager(viewPager);
记住,使用此实现,您的ViewPager将每隔2次滑动距离重新构建其中的片段。我的意思是:如果你有3个碎片,从1开始你在2上滑动到2,它将重新创建第3个碎片,如果从3开始你在2上滑动到1,它将重新创建第一个碎片(无论你是否已经创建了碎片,它都会这样做)。
为了避免此问题(如果您需要不重新创建片段),您应该使用:
viewPager.setOffscreenPageLimit(<num_of_your_pages>)
此外,您使用的代码:
final TabLayout.Tab myDietTab = tabLayout.newTab();
final TabLayout.Tab myWorkOutTab = tabLayout.newTab();
final TabLayout.Tab startProgramTab = tabLayout.newTab();
myDietTab.setText("My Diet");
myWorkOutTab.setText("My Workout");
startProgramTab.setText("Start a Program");
是无用的,因为在将片段添加到viewPager时,您已经定义了片段的标题。所以你应该加上:
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
/** Public Methods **/
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment); // this line can cause crashes
mFragmentTitleList.add(title);
}
对于您的ViewPager,您将通过这种方式为其设置片段和标题。
然后使用:
tabLayout.setupWithViewPager(viewPager)
另外,您不应该使用构造函数实例化片段,而应该使用静态工厂方法(如果您需要将值传递给片段,这很有用)。
静态工厂方法是一种调用构造函数来实例化对象实例的方法,然后它可以对其执行一些操作(在片段的情况下,它将设置一个参数束,将属性传递给片段的onCreate方法,该方法将获取参数并设置自身的属性)。
片段初始化示例:
public static void initInstance(int myVal1, int myVal2){
MyFragment mInstance = new MyFragment();
Bundle args = new Bundle();
args.putInt(<BUNDLE_KEY_MYVAL1>, myVal1);
args.putInt(<BUNDLE_KEY_MYVAL2>, myVal2);
mInstance.setArguments(args);
return mInstance;
}
publicstaticvoidinitinstance(int-myVal1,int-myVal2){
MyFragment MinInstance=新的MyFragment();
Bundle args=新Bundle();
参数putInt(,myVal1);
参数putInt(,myVal2);
mInstance.setArguments(args);
回报率;
}
最后,我建议迁移到androidx,因为支持库将不再更新(:
希望这有帮助:D有一个很好的编码!您还应该取消注释:
tabLayout.setupWithViewPager(viewPager);
记住,在这个实现中,您的ViewPager将每隔2次滑动距离重新构建其中的片段。我的意思是:如果您有3个片段,从1滑动到2对2,它将重新创建第3个片段,如果从3滑动到1对2,它将重新创建第一个片段(无论您是否已经创建了片段,它都将始终执行此操作)。
为了避免此问题(如果您需要不重新创建片段),您应该使用:
viewPager.setOffscreenPageLimit(<num_of_your_pages>)
此外,您使用的代码:
final TabLayout.Tab myDietTab = tabLayout.newTab();
final TabLayout.Tab myWorkOutTab = tabLayout.newTab();
final TabLayout.Tab startProgramTab = tabLayout.newTab();
myDietTab.setText("My Diet");
myWorkOutTab.setText("My Workout");
startProgramTab.setText("Start a Program");
是无用的,因为在将片段添加到viewPager时,您已经定义了片段的标题。因此,您应该添加:
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
/** Public Methods **/
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment); // this line can cause crashes
mFragmentTitleList.add(title);
}
对于您的ViewPager,您将通过这种方式为其设置片段和标题。
然后使用:
tabLayout.setupWithViewPager(viewPager)
另外,您不应该使用构造函数实例化片段,而应该使用静态工厂方法(如果您需要将值传递给片段,这很有用)。
静态工厂方法是一种调用构造函数来实例化对象实例的方法,然后它可以对其执行一些操作(在片段的情况下,它将设置一个参数束,将属性传递给片段的onCreate方法,该方法将获取参数并设置自身的属性)。
片段初始化示例:
public static void initInstance(int myVal1, int myVal2){
MyFragment mInstance = new MyFragment();
Bundle args = new Bundle();
args.putInt(<BUNDLE_KEY_MYVAL1>, myVal1);
args.putInt(<BUNDLE_KEY_MYVAL2>, myVal2);
mInstance.setArguments(args);
return mInstance;
}
publicstaticvoidinitinstance(int-myVal1,int-myVal2){
MyFragment MinInstance=新的MyFragment();
Bundle args=新Bundle();
参数putInt(,myVal1);
参数putInt(,myVal2);
mInstance.setArguments(args);
回报率;
}
最后,我建议迁移到androidx,因为支持库将不再更新(:
希望这是有帮助的:D有一个很好的编码