为什么Android Material Design选项卡布局不起作用?

时间:2019-02-09 03:55:29

标签: java android android-studio gradle sdk

我正在尝试使用viewpager创建一个布局,但它不起作用。由tabLayout.setupWithViewPager(viewPager);在PatientMain主要活动类中加载时,输出为:

enter image description here

当我在PatientMain主要活动类中使用viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));时,输出为:

enter image description here

但该片段未显示,也没有刷卡可用。

我完全按照书上所说的去做。我使用了12等几种来源。我个人认为代码可能不是问题,并且所使用的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");
        viewPagerAdapter.addFragment(new MyWorkoutFragment(), "My Workout");
        viewPagerAdapter.addFragment(new StartProgramFragment(), "Start a Program");
        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));

    }
}

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>();

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return 0;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return fragmentTitleList.get(position);
    }

    public void addFragment(Fragment fragment, String title){
        fragmentList.add(fragment);
        fragmentTitleList.add(title);
    }
}

其中一个片段:

package parsa.lop.adjust;


import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyDietFragment extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.my_diet_view, container, false);
    }
}

我的主要布局:

<?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>

我的片段布局:

<?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="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Tab 1"
        android:textSize="36sp" />

</RelativeLayout>

build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "parsa.lop.adjust"
        minSdkVersion 21
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.android.support:design:27.1.1'
}

2 个答案:

答案 0 :(得分:2)

在您的ViewPagerAdapter中,替换为:

@Override 
public int getCount() { 
    return 0; 
}

与此:

@Override 
public int getCount() {
    return fragmentList.size();
}

您正在将适配器内容的计数设置为0,这与适配器告诉其他组件没有要显示的项目相同。

答案 1 :(得分:0)

您还应该取消注释:

tabLayout.setupWithViewPager(viewPager);

请记住,使用此实现,您的ViewPager将每隔2次滑动距离就在其中重新构建片段。我的意思是:如果您有3个片段,并且从1滑动到2,则2将重新创建第3个片段;如果从3滑动到1,滑动到2,则它将重新创建第1片段(它将始终这样做)是否已创建片段很重要)。 为避免此问题(如果您需要不重新创建片段),应使用:

viewPager.setOffscreenPageLimit(<num_of_your_pages>)

还请记住,每个适配器(例如RecyclerView.Adapter)都使用“ getCount()”或“ getItemCount()”方法来获取要显示的元素数,因此在每个适配器中,您都应重写此方法并返回计数您的价值观。

此外,如果我没有记错的话,在XML文件中实现TabLayout的正确方法是将其包含在带有工具栏的AppBarLayout中。这是因为您通常应该在活动中使用“ NoActionBar”样式。 像这样:

<com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            android:layout_height="56dp"/>

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMode="fixed"
            app:tabGravity="fill"
            style="@style/AppTheme.TabLayout"/>
    </com.google.android.material.appbar.AppBarLayout>

在您的活动清单中

android:theme="@style/AppTheme.NoActionBar"

也是您使用的代码:

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);
        mFragmentTitleList.add(title);
    }

通过这种方式,您可以为ViewPager设置片段和标题。 然后使用:     tabLayout.setupWithViewPager(viewPager);

此外,您不应使用构造函数实例化片段,而应使用静态工厂方法(如果需要将值传递给片段,则非常有用)。 静态工厂方法是一种方法,该方法调用构造函数实例化该对象的实例,然后可以对其执行一些操作(在片段的情况下,它将设置Arguments Bundle以将属性传递给片段的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;
}

最后,我建议迁移到androidx,因为支持库将不再更新(:

希望这对您有帮助:D有一个不错的编码!