ViewPager2 + TabLayout + TabItem
在写Android项目的时候通常会有编写底部导航栏,然后在利用碎片来到指定的部分 以前经常使用的是ViewPager 而现在有了ViewPager2,在写项目的时候觉得也需要提升一下自己的新技术,就开始把ViewPager开始着手换成ViewPager2
Viewpager + TabLayout + TabItem
首先我们先来看代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#FFF"
android:minHeight="?attr/actionBarSize"
app:tabIndicatorColor="#00000000"
app:tabRippleColor="#00000000"
app:tabSelectedTextColor="#FFCCCC"
app:tabTextColor="#929299">
<com.google.android.material.tabs.TabItem
android:id="@+id/item_chat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:icon="@drawable/fragment_home"
android:text="首页" />
<com.google.android.material.tabs.TabItem
android:id="@+id/item_find"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:icon="@drawable/fragment_shopping"
android:text="购物车" />
<com.google.android.material.tabs.TabItem
android:id="@+id/item_person"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:icon="@drawable/fragment_person"
android:text="我的" />
</com.google.android.material.tabs.TabLayout>
</RelativeLayout>
可以看到上面代码,我们使用TabLayout然后里面的TabItem直接设置了一个背景图和文字,外面和ViewPager并列
private TabLayout tabLayout;
private ViewPager viewPager;
final String[] titleArray = new String[]{"首页", "购物车", "我的"};
public List<Fragment> fragmentList;
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
viewPager = (ViewPager) findViewById(R.id.view_pager);
fragment.add(new FragmentOne());
fragment.add(new FragmentTwo());
FragmentAdapter adapter = new
FragmentAdapter(getSupportFragmentManager(), titleArray, fragmentList);
viewPager.setAdapter(adapter);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
tabLayout.setScrollPosition(position, positionOffset, true);
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
其实好像最后的tablayout和viewlayout的这个重写函数不用也可以达到效果(可以试试)
Viewpager和Viewpager2区别
ViewPager2相比于ViewPager 还可以设置上下滑动,原本的ViewPager只能左右滑动,这对于有时候有需求又可以进行更改 并且ViewPager2使用我们熟悉的RecyclerView就可以实现左右或者上下滑动(具体可以去谷歌的关于ViewPager2的代码,这里就不过多介绍了)
ViewPager2
ViewPager2 + RecyclerView
首先我们讲一下和RecyclerView一起的使用
<?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="match_parent"
tools:context=".ViewPager2.ViewPager"
android:orientation="vertical">
<androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/viewPager2"
android:orientation="vertical"/>
</LinearLayout>
public class ViewPager extends AppCompatActivity {
private ViewPager2 viewPager2;
private List<String> list = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_pager2);
viewPager2 = (ViewPager2) findViewById(R.id.viewPager2);
list.add("黝黑");
list.add("漆黑");
list.add("油烟墨");
list.add("墨染");
list.add("濡雨");
list.add("阑夜");
list.add("鹤羽");
list.add("青衣");
list.add("瓦青");
list.add("元青");
list.add("百草霜");
viewPager2.setAdapter(new recyclerAdapter(this, list, viewPager2));
viewPager2.setCurrentItem(1);
}
}
布局和活动都很简单,就是设置一个名字 然后设置适配器 setCurrentItem 可以设置从第几页开始
适配器也很简单,就是我们熟知的RecyclerView适配器
public class recyclerAdapter extends RecyclerView.Adapter<recyclerAdapter.ViewHolder> {
private List<String> mData;
private ViewPager2 viewPager2;
private Context context;
private int[] colorArray = new int[]{R.color.黝黑, R.color.漆黑, R.color.油烟墨,
R.color.墨染, R.color.濡雨, R.color.阑夜,
R.color.鹤羽, R.color.青衣, R.color.瓦青,
R.color.元青, R.color.百草霜
};
public recyclerAdapter(Context context, List<String> mData, ViewPager2 viewPager2) {
this.mData = mData;
this.context = context;
this.viewPager2 = viewPager2;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
final ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
String animal = mData.get(position);
holder.textView.setText(animal);
holder.relativeLayout.setBackgroundResource(colorArray[position]);
}
@Override
public int getItemCount() {
return mData.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
AppCompatTextView textView;
RelativeLayout relativeLayout;
public ViewHolder(@NonNull View itemView) {
super(itemView);
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.container);
textView = (AppCompatTextView) itemView.findViewById(R.id.tvTitle);
}
}
}
想上下滑动就在布局ViewPager2属性那设置android:orientation="vertical" 在活动里面设置也是一样的
ViewPager2 + TabLayout + TabItem
最后来讲讲关于ViewPager2和TabLayout的一起使用
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:orientation="vertical"
tools:context=".MainActivity"
android:background="@color/white">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/home_viewPager2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/home_tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#FFF"
android:minHeight="?attr/actionBarSize"
app:tabIndicatorColor="#00000000"
app:tabRippleColor="#00000000"
app:tabSelectedTextColor="#FFCCCC"
app:tabTextColor="#929299">
<com.google.android.material.tabs.TabItem
android:id="@+id/item_chat"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.google.android.material.tabs.TabItem
android:id="@+id/item_find"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.google.android.material.tabs.TabItem
android:id="@+id/item_person"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</com.google.android.material.tabs.TabLayout>
</RelativeLayout>
在布局里面呢,可以看到在TabItem 我就没有设置文字和图片 这些设置我都在活动里进行设置
private TabLayout tabLayout;
private ViewPager2 viewPager2;
private List<Fragment> fragmentList = new ArrayList<>();
final String[] titleArray = new String[]{"首页", "购物车", "我的"};
final int[] titleItem = new int[]{R.drawable.fragment_home,R.drawable.fragment_shopping,R.drawable.fragment_person};
tabLayout = (TabLayout) findViewById(R.id.home_tabLayout);
viewPager2 = (ViewPager2) findViewById(R.id.home_viewPager2);
fragmentList.add(new HomeFragment());
fragmentList.add(new ShoppingFragment());
fragmentList.add(new PersonFragment());
viewPager2.setAdapter(new FragmentAdapter(getSupportFragmentManager(), getLifecycle(), fragmentList));
viewPager2.setOffscreenPageLimit(3);
开始还是熟悉的找到实例和创建碎片,不同于ViewPager的是 图片我们在活动里面定义,并且数组的类型使用的是int,可以改成别的类型试试,他会报错,放过去会提示你需要的是int类型的 这次的碎片的适配器呢 我们换了一个继承,这也是官方文档中说明的ViewPager2 使用的碎片适配器换成继承FragmentStateAdapter
public class FragmentAdapter extends FragmentStateAdapter {
List<Fragment> fragmentList = new ArrayList<>();
public FragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle,List<Fragment> fragmentList) {
super(fragmentManager, lifecycle);
this.fragmentList = fragmentList;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return fragmentList.get(position);
}
@Override
public int getItemCount() {
return fragmentList.size();
}
}
可以看到代码量少了很多,一个函数就是创建碎片,一个就是返回有多少个碎片的,是不是更加的清晰明了 并且代码量少了很多呢
最后就是ViewPager2 和 TabLayout的绑定了,ViewPager2是要我们自己进行和TabLayout的绑定的 在这里如果你在布局当中的TabItem写了图片和文字 在这里绑定时候其实是会被覆盖的,所以我在布局中没有写文字和图片,全部在活动中来写了
TabLayoutMediator tab = new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText(titleArray[position]);
tab.setIcon(titleItem[position]);
}
});
tab.attach();
setText就是标题,用我们上面定义的一个字符串数组,setIcon就是设置图片,用我们上面定义的一个整形的数组(具体的drawable我举例一个)
就是写一个点击和不点击时候的图片不一样
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/home" android:state_selected="false"/>
<item android:drawable="@drawable/home_select" android:state_selected="true"/>
</selector>
使用碎片时也可以更改为上下滑动,具体更改和使用RecyclerView一样
在从ViewPager改成ViewPager2后发现代码量其实少了很多,并且还可以上下滑动其实还是很不错的,并且碎片的适配器也更为简单了 其实要想更加简便在RecyclerView那 适配器还可以更改为那个流行的BaseQuicklyAdapter 这个适配器也是非常快速和好用的
具体ViewPager2的使用目前就到这,也许还有我没有使用到的地方,日后可以慢慢探索
|