美文网首页
TableLayout+ViewPager+Fragment实现

TableLayout+ViewPager+Fragment实现

作者: 雷涛赛文 | 来源:发表于2020-09-03 16:25 被阅读0次

      当前很多主流应用界面都是这样设计的,上面有许多tab,水平滑动会切换tab,tab下的页面也随之发生改变,典型的有今日头条,简书,知乎等。是如何实现的呢?前段时间研究了一下发现TabLayout可以完成这一职责,TabLayout提供了一个水平的布局用来展示Tabs,TabLayout一般都是配合Viewpager使用的,Viewpager里的Fragment随着顶部的Tab一起联动,将实现方式记录一下。
      使用AndroidStudio4.0.1实现

      1.在项目app下的Module中添加依赖
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.0'
      2.布局文件
<?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=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tableLayout"
        android:layout_width="412dp"
        android:layout_height="76dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:tabMode="scrollable"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
    </com.google.android.material.tabs.TabLayout>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="395dp"
        android:layout_height="644dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tableLayout" />

</androidx.constraintlayout.widget.ConstraintLayout>
      3.主界面实现
public class MainActivity extends AppCompatActivity {

    private TabLayout mTabLayout;
    private ViewPager mViewPager;
    private FragmentsAdapter mFragmentsAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        mViewPager = findViewById(R.id.viewPager);
        mTabLayout = findViewById(R.id.tableLayout);
        //构造fragment adapter
        mFragmentsAdapter = new FragmentsAdapter(getSupportFragmentManager());
        //将adapter加载到viewpager里面
        mViewPager.setAdapter(mFragmentsAdapter);
        //设置预加载数量,提高显示效果体验
        mViewPager.setOffscreenPageLimit(2);
        //tablayout与viewpager联动
        mTabLayout.setupWithViewPager(mViewPager);
    }
}
        3.1 FragmentPagerAdapter
//
//Source code recreated from a .class file by IntelliJ IDEA
//(powered by Fernflower decompiler)
//
public abstract class FragmentPagerAdapter extends PagerAdapter {
    private final FragmentManager mFragmentManager;
    private FragmentTransaction mCurTransaction = null;
    private Fragment mCurrentPrimaryItem = null;

    protected FragmentPagerAdapter(FragmentManager fm) {
        this.mFragmentManager = fm;
    }

    private static String makeFragmentName(int viewId, long id) {
        return "android:switcher:" + viewId + ":" + id;
    }

    protected abstract Fragment getItem(int var1);

    public void startUpdate(ViewGroup container) {
        if (container.getId() == -1) {
            throw new IllegalStateException("ViewPager with adapter " + this + " requires a view id");
        }
    }

    @SuppressLint("CommitTransaction")
    public Object instantiateItem(ViewGroup container, int position) {
        if (this.mCurTransaction == null) {
            this.mCurTransaction = this.mFragmentManager.beginTransaction();
        }

        long itemId = this.getItemId(position);
        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = this.mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            this.mCurTransaction.attach(fragment);
        } else {
            fragment = this.getItem(position);
            this.mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId));
        }

        if (fragment != this.mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
            fragment.setUserVisibleHint(false);
        }

        return fragment;
    }

    @SuppressLint("CommitTransaction")
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (this.mCurTransaction == null) {
            this.mCurTransaction = this.mFragmentManager.beginTransaction();
        }

        this.mCurTransaction.detach((Fragment) object);
    }

    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        Fragment fragment = (Fragment) object;
        if (fragment != this.mCurrentPrimaryItem) {
            if (this.mCurrentPrimaryItem != null) {
                this.mCurrentPrimaryItem.setMenuVisibility(false);
                this.mCurrentPrimaryItem.setUserVisibleHint(false);
            }

            fragment.setMenuVisibility(true);
            fragment.setUserVisibleHint(true);
            this.mCurrentPrimaryItem = fragment;
        }

    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    public void finishUpdate(ViewGroup container) {
        if (this.mCurTransaction != null) {
            this.mCurTransaction.commitNowAllowingStateLoss();
            this.mCurTransaction = null;
        }

    }

    public boolean isViewFromObject(View view, Object object) {
        return ((Fragment) object).getView() == view;
    }

    public Parcelable saveState() {
        return null;
    }

    public void restoreState(Parcelable state, ClassLoader loader) {
    }

    private long getItemId(int position) {
        return (long) position;
    }
}
        3.2 FragmentAdapter 继承上述class,实现一些抽象方法
public class FragmentsAdapter extends FragmentPagerAdapter{

    public FragmentsAdapter(FragmentManager fm) {
        super(fm);
    }
    //返回tab对应的fragment
    @Override
    public Fragment getItem(int position) {
        return FragmentsManager.getFragment(position);
    }
    //tab的数量
    @Override
    public int getCount() {
        return FragmentsManager.getCount();
    }
    //tab对应的title,在setupWithViewPager(mViewPager)里面使用
    /**for (int i = 0; i < adapterCount; i++) {
        addTab(newTab().setText(pagerAdapter.getPageTitle(i)), false);
      }*/
    @Override
    public CharSequence getPageTitle(int position) {
        return FragmentsManager.getTitle(position);
    }
}
        3.3 FragmentsManager 管理fragment,供FragmentsAdapter调用
public class FragmentsManager {
     //输入tab对应的title
    private static List<String> DEFAULT_LIST = new ArrayList<>();
    static {
        DEFAULT_LIST.add("网格");
        DEFAULT_LIST.add("网页");
        DEFAULT_LIST.add("数据绑定");
        DEFAULT_LIST.add("xml解析");
        DEFAULT_LIST.add("画廊");
        DEFAULT_LIST.add("自定义View");
        DEFAULT_LIST.add("约束布局");
        DEFAULT_LIST.add("JNI学习");
        DEFAULT_LIST.add("Kotlin");
        DEFAULT_LIST.add("Animator");
    }
    //tab对于的Fragment
    public static Fragment getFragment(int position) {
        switch (position) {
            case 0:
                return new MenuFragment();
            case 1:
                return new MouseFragment();
            case 2:
                return new KeyboardFragment();
            case 3:
                return new RemoteControlFragment();
            case 4:
                return new GalleryFragment();
            case 5:
                return new SelfDeterminedFragment();
            case 6:
                return new ConstraintFragment();
            case 7:
                return new JniFragment();
            case 8:
                return new KotlinFragment();
            case 9:
                return new AnimatorFragment();
            default:
                return null;
        }
    }
    //tab的数量
    public static int getCount() {
        return DEFAULT_LIST.size();
    }

    @Override
    public boolean equals(@Nullable Object obj) {
        return super.equals(obj);
    }
    //tab的title
    public static String getTitle(int index) {
        return DEFAULT_LIST.get(index);
    }
}
      4.实现对应布局的Fragment,代码就不贴了
      5.效果
1.jpg
2.jpg

相关文章

网友评论

      本文标题:TableLayout+ViewPager+Fragment实现

      本文链接:https://www.haomeiwen.com/subject/bnfosktx.html