Android Studio实现TabLayout

通过AS实现TabLayout的效果记录如下:

  1. 完成了TabLayout布局
  2. 完成了Activity向Fragment传输数据
  3. 完成了Fragment监听数据变化实时更新数据

其效果图如下:

首先,先创建一个Activity,创建Java与xml布局文件(此处不做上述UI,只做简单的TabLayout)

DevInformationActivity.java

public class DevInformationActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_devinformation);
        
        //选项卡部分--------------------------------
        //获取选项卡
        TabLayout tabLayout = findViewById(R.id.tab_layout);
        ViewPager viewPager = findViewById(R.id.view_pager);

        adapter = new PageAdapter(getSupportFragmentManager());
        viewPager.setAdapter(adapter);


        // 设置TabLayout的ViewPager
        tabLayout.setupWithViewPager(viewPager);
    }
}

activity_devinformation.xml

<?xml version="1.0" encoding="utf-8"?>
<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:background="@drawable/style_page_background"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="10dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/style_card_round"
            android:orientation="horizontal"
            android:padding="10dp"
            android:layout_marginTop="10dp">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

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

                    app:tabRippleColor="@color/white"

                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintStart_toStartOf="parent"

                    app:tabTextColor="#8c8c8c"
                    app:tabSelectedTextColor="@color/black"
                    app:tabIndicatorFullWidth="true"

                    app:tabIndicator="@drawable/style_tab_line"
                    app:tabIndicatorColor="@color/colorPrimary">
                    <com.google.android.material.tabs.TabItem
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="信息"/>
                    <com.google.android.material.tabs.TabItem
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="设置"/>
                    <com.google.android.material.tabs.TabItem
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="地图"/>
                    <com.google.android.material.tabs.TabItem
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="关于"/>

                </com.google.android.material.tabs.TabLayout>

                <androidx.viewpager.widget.ViewPager
                    android:id="@+id/view_pager"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    app:layout_constraintTop_toBottomOf="@+id/tab_layout">
                </androidx.viewpager.widget.ViewPager>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

上面的代码中有一个样式文件app:tabIndicator="@drawable/style_tab_line"其实现如下

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:width="40dp"
        android:height="5dp"
        android:gravity="center">
        <shape>
            <corners android:radius="5dp" />
            <solid android:color="@color/colorPrimary" />
        </shape>
    </item>
</layer-list>

新建一个新的类

PageAdapter.java

package com.example.pld_mob.util;


import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

import com.example.pld_mob.DeviceAboutActivity;
import com.example.pld_mob.DeviceInfoActivity;
import com.example.pld_mob.DeviceMapActivity;
import com.example.pld_mob.DeviceSetActivity;

public class PageAdapter extends FragmentPagerAdapter {

    private final String[] TAB_TITLES = {"信息", "设置", "地图", "关于"};

    public PageAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                // 使用 fragment_page.xml 布局创建第一个选项卡的内容
                return new DeviceInfoActivity();
            case 1:
                // 使用 fragment_page.xml 布局创建第二个选项卡的内容
                return new DeviceSetActivity();
            case 2:
                // 使用 fragment_page.xml 布局创建第二个选项卡的内容
                return new DeviceMapActivity();
            case 3:
                // 使用 fragment_page.xml 布局创建第二个选项卡的内容
                return new DeviceAboutActivity();
            default:
                return null;
        }
    }
    @Override
    public int getCount() {
        return TAB_TITLES.length;
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return TAB_TITLES[position];
    }
}

这样的话就可以在DevInformationActivity实例化PageAdapter了,但PageAdapter中的DeviceInfoActivity、DeviceSetActivity、DeviceMapActivity、DeviceAboutActivity几个都是继承于Fragment的类,也就是相应的几个TabLayout的子页面,其实现如下(此处只举例一个)(PS:别被类名称误导此处是继承于Fragment,返回的是View视图)

DevInfoActivity.java

public class DeviceInfoActivity extends Fragment {
    Context mContext;
    View view;

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

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // 使用 fragment_page.xml 布局文件来创建视图
        view = inflater.inflate(R.layout.activity_deviceinfo, container, false);

        return view;
    }
}

activity_deviceinfo.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".DeviceInfoActivity">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="信息页面"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

注意,四个页面就创建够四个页面,别缺不然会卡死。

根据以上代码之后应该就可以完成选项卡切换了,之后就是数据传输,其实现过程如下(主要是通过ViewModel实现):

新建如下类ViewModelUtil.java

public class ViewModeUtil extends ViewModel{
    // 数据可以是LiveData, StateFlow, 或者其他任何你想要共享的东西
    private final MutableLiveData<List<String>> DevInfoData = new MutableLiveData<>();

    public void setSharedData(List<String> data) {
        DevInfoData.setValue(data);
    }

    public LiveData<List<String>> getSharedData() {
        return DevInfoData;
    }
}

此处数据传输的是List<String>这样扩展性会更强。

其使用方法如下:

//实例化ViewModelUtil类
ViewModel DevInfoViewModel;

//新建List<String>数据组
List<String> PLD_INF_BUFF;

//在你的按钮回调或者一些回调函数中执行以下代码
PLD_STA_Buff.add(0,"AA");
PLD_STA_Buff.add(1,"BB");
PLD_STA_Buff.add(2,"CC");
PLD_STA_Buff.add(3,"DD");

//将数据更新
DevInfoViewModel.setSharedData(PLD_INF_Buff);

//另外需要单独写一个成员函数
public ViewModeUtil getDevInfoViewModel() {
    return DevInfoViewModel;
}

在子页面中DevInfoActivity.java中获取DevInformationActivity中的DevInfoViewModel其如下:

DevInformationActivity DevInfoActivity;
DevInfoActivity = ((DevInformationActivity) requireActivity());
ViewModeUtil DevInfoViewModel = DevInfoActivity.getDevInfoViewModel();
 // 观察LiveData数据变化
DevInfoViewModel.getSharedData().observe(getViewLifecycleOwner(), Data -> {
    Data.get(0);
    Data.get(0);
    Data.get(0);
    
    //把这些数据打印出来
});

这样就可以获取到数据了,在Activity中设置数据后,Fragment中就会更新数据并进入Observe,在该函数中进行一些数据操作,比如写入TextView等等。

 

posted @ 2024-02-13 20:11  千樊  阅读(498)  评论(0)    收藏  举报