前言:
各位同学大家好,有段时间没有给各位更新文章了。在这里给大家拜个晚年,新年快乐,虎年大吉。今天要分享的是viewpager2的使用 废话不多说我们正式开始。
官方使用指南
使用 ViewPager2 创建包含标签的滑动视图
滑动视图允许您通过水平手指手势或滑动在同级屏幕(例如标签页)之间进行导航。此导航模式也称为“水平分页”。本主题介绍了如何创建具有滑动视图(以便在标签页之间切换)的标签页布局,以及如何显示标题条而不是标签页。
官方地址: https://developer.android.google.cn/guide/navigation/navigation-swipe-view-2?hl=zh_cn#java
有兴趣的同学可以自己Android 官网看看
从官方介绍我们可以知道 viewpager2 算是原来的viewpager 的加强版 支持了纵向的滑动 能更好的帮助开发实现类似抖音这类直播的 竖屏视频的滑动效果 。
需要用到的三方库
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
-
横向滑动效果
具体实现:
<?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=".HorizontalActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/horizontal_viewpager2"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.viewpager2.widget.ViewPager2>
</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
/**
*
*
* 创建人: xuqing
* 创建时间:2022年2月8日11:24:58
* 类说明: viewpager2 实现横向滑动
*
*/
public class HorizontalActivity extends AppCompatActivity {
private ViewPager2 viewPager2;
private VerticalVpAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_horizontal);
viewPager2=findViewById(R.id.horizontal_viewpager2);
adapter=new VerticalVpAdapter(HorizontalActivity.this);
viewPager2.setAdapter(adapter);
}
}
布局非常简单就一个viewpager2
适配器
package com.example.myapplication;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class VerticalVpAdapter extends RecyclerView.Adapter<VerticalVpAdapter.VerticalVpViewHolder> {
private List<Integer> backgrounds;
private Context mContext;
VerticalVpAdapter(Context context) {
mContext = context;
if (backgrounds == null) {
backgrounds = new ArrayList<>();
backgrounds.add(android.R.color.holo_blue_bright);
backgrounds.add(android.R.color.holo_red_dark);
backgrounds.add(android.R.color.holo_green_dark);
backgrounds.add(android.R.color.holo_orange_light);
backgrounds.add(android.R.color.holo_purple);
}
}
@NonNull
@Override
public VerticalVpViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new VerticalVpViewHolder(LayoutInflater.from(mContext).inflate((R.layout.item_h_v), parent, false));
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull VerticalVpViewHolder holder, int position) {
holder.mTextView.setText("第 " + (position + 1) + " 界面");
holder.mLinearLayout.setBackgroundResource(backgrounds.get(position));
}
@Override
public int getItemCount() {
if (backgrounds == null) {
return 0;
}
return backgrounds.size();
}
class VerticalVpViewHolder extends RecyclerView.ViewHolder {
LinearLayout mLinearLayout;
TextView mTextView;
VerticalVpViewHolder(@NonNull View itemView) {
super(itemView);
mLinearLayout = itemView.findViewById(R.id.ll_h_v);
mTextView = itemView.findViewById(R.id.tv_hv);
}
}
}
和 recylerview的适配器写法很类似 不用我们程序员再去处理viewhodler的复用
-
竖向滑动效果
竖向滑动其实跟横向滑动写法差不多 就是在主布局多了一个 android:orientation="vertical" 纵向的属性 这个默认是 横向的 如果你不设置就默认横向滑动
<?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=".VerticalActivity"
<androidx.viewpager2.widget.ViewPager2
android:orientation="vertical"
android:id="@+id/horizontal_viewpager2"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.viewpager2.widget.ViewPager2>
</androidx.constraintlayout.widget.ConstraintLayout>
-
横向图片滑动效果
布局
<?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=".HorizontalImageActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/image_viewpager2"
android:layout_width="match_parent"
android:layout_height="match_parent"></androidx.viewpager2.widget.ViewPager2>
</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
public class HorizontalImageActivity extends AppCompatActivity {
private int[]image={R.drawable.image1,R.drawable.image2,R.drawable.image3,R.drawable.image4,R.drawable.image5};
private ImageslideAdapter imageslideAdapter;
private List<Integer> data=new ArrayList<>();
private ViewPager2 viewPager2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_horizontal_image);
for (int i = 0; i <image.length; i++) {
data.add(image[i]);
}
viewPager2=findViewById(R.id.image_viewpager2);
imageslideAdapter=new ImageslideAdapter(data, HorizontalImageActivity.this);
viewPager2.setAdapter(imageslideAdapter);
}
}
适配器
package com.example.myapplication;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
/***
*
*
* 创建人:xuqing
* 创建时间:2022年2月8日12:28:21
* 类说明:图片滑动
*
*
*/
public class ImageslideAdapter extends RecyclerView.Adapter<ImageslideAdapter.ImageslideViewHolder> {
private List<Integer> imageViews;
private Context context;
public ImageslideAdapter(List<Integer> imageViews, Context context) {
this.imageViews = imageViews;
this.context = context;
}
@NonNull
@Override
public ImageslideViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ImageslideAdapter.ImageslideViewHolder(LayoutInflater.from(context).inflate((R.layout.image_item), parent, false));
}
@Override
public void onBindViewHolder(@NonNull ImageslideViewHolder holder, int position) {
holder.imageView.setImageResource(imageViews.get(position));
}
@Override
public int getItemCount() {
return imageViews.size();
}
class ImageslideViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
ImageslideViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.item_image);
}
}
}
图片滑动其实跟普通布局效果差不多 这边只是item 子布局里面放了一个imgaeview 然后我在实例化的时候传入了图片id的集合 这边可以选择网络图片也可以本地 我方便演示就直接用了本地 其实我们通过接口请求返回的也是可以的
-
纵向图片滑动同理
<?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=".VerticaimageActivity">
<androidx.viewpager2.widget.ViewPager2
android:orientation="vertical"
android:id="@+id/image_viewpager2"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.viewpager2.widget.ViewPager2>
</androidx.constraintlayout.widget.ConstraintLayout>
我们只需要在主布局容器里面加上 android:orientation="vertical" 属性即可
-
ViewPager 2 与 TabLayout 混用
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tb_vp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorFullWidth="false"
app:tabMode="scrollable"
app:tabIndicatorColor="#0371DD"
app:tabRippleColor="@android:color/transparent"
app:tabSelectedTextColor="#0371DD"
app:tabTextColor="#111111" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp_tb"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
package com.example.myapplication.withTab;
import android.graphics.Color;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import com.example.myapplication.R;
import com.google.android.material.tabs.TabLayout;
public class TabActivity extends AppCompatActivity {
private ViewPager2 vpTab;
private TabLayout tabVp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab);
TabAdapter adapter = new TabAdapter(this);
vpTab = findViewById(R.id.vp_tb);
tabVp = findViewById(R.id.tb_vp);
vpTab.setAdapter(adapter);
tabVp.setTabTextColors(Color.parseColor("#111111"), Color.parseColor("#0371DD"));
adapter.addColor(android.R.color.darker_gray);
adapter.addColor(android.R.color.holo_red_dark);
adapter.addColor(android.R.color.holo_green_dark);
adapter.addColor(android.R.color.holo_blue_dark);
adapter.addColor(android.R.color.holo_purple);
adapter.addColor(android.R.color.holo_orange_dark);
tabVp.addTab(tabVp.newTab().setText("第一个界面"));
tabVp.addTab(tabVp.newTab().setText("第二个界面"));
tabVp.addTab(tabVp.newTab().setText("第三个界面"));
tabVp.addTab(tabVp.newTab().setText("第四个界面"));
tabVp.addTab(tabVp.newTab().setText("第五个界面"));
tabVp.addTab(tabVp.newTab().setText("第六个界面"));
tabVp.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
vpTab.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
vpTab.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
tabVp.setScrollPosition(position, 0, false);
}
});
}
}
通过 调用 addOnTabSelectedListener 和 registerOnPageChangeCallback 两个方法来监听 点击和滑动动作
ViewPager 2 与 RadioButton 混用
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".withRadioGroup.RgActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp_rg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/rg_vp" />
<RadioGroup
android:id="@+id/rg_vp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_home"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:checked="true"
android:drawableTop="@drawable/selector_home"
android:drawablePadding="5dp"
android:gravity="center"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="@string/home"
android:textSize="16sp" />
<RadioButton
android:id="@+id/rb_msg"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:drawableTop="@drawable/selector_msg"
android:drawablePadding="5dp"
android:gravity="center"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="@string/msg"
android:textSize="16sp" />
<RadioButton
android:id="@+id/rg_my"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:drawableTop="@drawable/selector_my"
android:drawablePadding="5dp"
android:gravity="center"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="@string/my"
android:textSize="16sp" />
</RadioGroup>
</RelativeLayout>
activity 逻辑
package com.example.myapplication.withRadioGroup;
import android.os.Bundle;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import com.example.myapplication.R;
public class RgActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {
private ViewPager2 vpRg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rg);
RgAdapter adapter = new RgAdapter(this);
RadioGroup rgVp = findViewById(R.id.rg_vp);
vpRg = findViewById(R.id.vp_rg);
rgVp.setOnCheckedChangeListener(this);
vpRg.setAdapter(adapter);
adapter.addFragment(new HomeFragment());
adapter.addFragment(new MessageFragment());
adapter.addFragment(new MyFragment());
vpRg.setCurrentItem(0);
vpRg.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
switch (position) {
case 0:
((RadioButton) findViewById(R.id.rb_home)).setChecked(true);
break;
case 1:
((RadioButton) findViewById(R.id.rb_msg)).setChecked(true);
break;
case 2:
((RadioButton) findViewById(R.id.rg_my)).setChecked(true);
break;
}
}
});
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.rb_home:
vpRg.setCurrentItem(0);
break;
case R.id.rb_msg:
vpRg.setCurrentItem(1);
break;
case R.id.rg_my:
vpRg.setCurrentItem(2);
break;
}
}
}
通过调用 registerOnPageChangeCallback 来监听 滑动的时候我们来处理 RadioButton 选中的情况
适配器
package com.example.myapplication.withRadioGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.ArrayList;
import java.util.List;
public class RgAdapter extends FragmentStateAdapter {
private List<Class> fragments;
public RgAdapter(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
if (fragments == null) {
fragments = new ArrayList<>();
}
}
public void addFragment(Fragment fragment) {
if (fragments != null) {
fragments.add(fragment.getClass());
}
}
@NonNull
@Override
public Fragment createFragment(int position) {
try {
return (Fragment) fragments.get(position).newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return null;
}
@Override
public int getItemCount() {
return fragments.size();
}
}
这里的适配我们要继承FragmentStateAdapter 才能实现
最后总结:
viewpager2 对比viewpager 功能要强大很多 如果我们开发新的app项目我强烈建议直接使用viewpager2 因为viewpager支持功能 viewpager2 都是支持 我们也更好保证代码统一性 。viewpager2 支持了纵向滑动 让我们可以实现类似抖音等小视频app的部分效果。有兴趣的同学可以下载代码好好研究下或者去看看官方文档 都是可以的 最后祝愿各位网友和同学 2022年心想事成 往事如意 我要继续工作了 ,希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。各位同学如果觉得文章还不错 ,麻烦给关注和star,小弟在这里谢过啦!