Android Viewpagger2+Fragment实现UI切换效果

先看效果

 简单分析一下,顶部是一个RadioGroup,主要是用来切换当前显示的数据类型,可以点击“列表”、“表格”两个RadioButton实现切换类型,也可以通过左右滑动页面,再加上本来两个Fragment中展示的RecyclerView,构成了本文中将要讲解的UI效果,文末附带demo源码

1.gradle文件中引用Viewpagger2

implementation 'androidx.viewpager2:viewpager2:1.0.0'

2.代码结构,如下图

1)adapter包中为抽象出来的一个公共适配器,后续代码中会展示相关使用;

2)DataBean为列表中展示的数据实体,只有一个string对象,如下;

public class DataBean {
    public String index;

    public DataBean(String index) {
        this.index = index;
    }
}

3)MainActivity为主界面、ListFragment与GridFragment分别为两个fragment;

4)布局文件顾名思义,item_list与item_grid分别为列表和网格列表的子项布局;

关键代码展示:

1.activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal">

        <RadioGroup
            android:id="@+id/radioGroup"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:orientation="horizontal">

            <RadioButton
                android:id="@+id/rbList"
                style="@style/RadioButtonCheckText"
                android:text="列表" />

            <View
                android:layout_width="1dp"
                android:layout_height="match_parent"
                android:background="#ababab" />

            <RadioButton
                android:id="@+id/rbGrid"
                style="@style/RadioButtonCheckText"
                android:text="表格" />

        </RadioGroup>

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#ababab" />

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPagger"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

2.fragment_list、fragment_grid页面的布局是类似的,只展示一个

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

3.item_list、item_grid的布局也类似,只展示一个

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:focusable="true"
    android:orientation="vertical">

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:gravity="center"
        android:text="表格1"
        android:textColor="@drawable/item_click_text_color_selector" />

</LinearLayout>
注:item_click_text_color_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#4ba2ff" android:state_pressed="true" />
    <item android:color="#333333" android:state_pressed="false" />
</selector>

4.ListFragment、GridFragment代码相似,只展示一个

public class ListFragment extends Fragment {
    private FragmentListBinding binding;
    private CommonAdapter<DataBean> commonAdapter;
    private List<DataBean> lists = new ArrayList<>();

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = FragmentListBinding.inflate(LayoutInflater.from(getActivity()));
        lists.clear();
        for (int i = 0; i < 20; i++) {
            lists.add(new DataBean("列表" + i));
        }
        initAdapter();
        return binding.getRoot();
    }

    private void initAdapter() {
        binding.recycler.setLayoutManager(new LinearLayoutManager(getActivity()));
        commonAdapter = new CommonAdapter<DataBean>(getActivity(),
                R.layout.item_list, lists) {
            @Override
            public void convert(CommonViewHolder holder, DataBean bean, int position) {
                holder.setText(R.id.text, bean.index);
                holder.setOnClickListener(R.id.text, view -> {
                    Toast.makeText(getActivity(), "点击了:" + bean.index, Toast.LENGTH_SHORT).show();
                });
            }

            @Override
            public void footConvert(CommonViewHolder holder, int size) {
            }
        };
        binding.recycler.setAdapter(commonAdapter);
        binding.recycler.setItemAnimator(new DefaultItemAnimator());
    }

}

5.MainActivity

public class MainActivity extends AppCompatActivity {
    private ActivityMainBinding binding;
    private FragmentStateAdapter mFragmentAdapter;
    private ViewPager2.OnPageChangeCallback mOnPageChangeCallback = new MyOnPageChangeCallback();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        mFragmentAdapter = new PageAdapter(this);
        binding.viewPagger.setAdapter(mFragmentAdapter);

        binding.radioGroup.setOnCheckedChangeListener((group, checkedId) -> {
            if (checkedId == R.id.rbList) {
                binding.viewPagger.setCurrentItem(0);
            } else if (checkedId == R.id.rbGrid) {
                binding.viewPagger.setCurrentItem(1);
            }
        });
        binding.radioGroup.check(R.id.rbList);
    }

    @Override
    protected void onStart() {
        super.onStart();
        binding.viewPagger.registerOnPageChangeCallback(mOnPageChangeCallback);
    }

    @Override
    protected void onStop() {
        super.onStop();
        binding.viewPagger.unregisterOnPageChangeCallback(mOnPageChangeCallback);
    }

    class PageAdapter extends FragmentStateAdapter {

        public PageAdapter(@NonNull FragmentActivity fragmentActivity) {
            super(fragmentActivity);
        }

        @NonNull
        @Override
        public Fragment createFragment(int position) {
            Fragment listFragment = new ListFragment();
            Fragment gridFragment = new GridFragment();
            if (0 == position) {
                return listFragment;
            } else {
                return gridFragment;
            }
        }

        @Override
        public int getItemCount() {
            return 2;
        }
    }

    class MyOnPageChangeCallback extends ViewPager2.OnPageChangeCallback {
        @Override
        public void onPageSelected(int position) {
            switch (position) {
                case 0:
                    binding.radioGroup.check(R.id.rbList);
                    break;
                case 1:
                    binding.radioGroup.check(R.id.rbGrid);
                    break;
                default:
                    break;
            }
        }
    }

}

关键代码:

class PageAdapter extends FragmentStateAdapter {

    public PageAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        Fragment listFragment = new ListFragment();
        Fragment gridFragment = new GridFragment();
        if (0 == position) {
            return listFragment;
        } else {
            return gridFragment;
        }
    }

    @Override
    public int getItemCount() {
        return 2;
    }
}

Viewpagger与fragment通过继承FragmentStateAdapter来实现,通过重写createFragment方法,将对应的Fragment引用返回给Viewpagger。

demo源码

猜你喜欢

转载自blog.csdn.net/weixin_53324308/article/details/130867333
今日推荐