ViewPage2
介绍
ViewPage2主要为了解决ViewPage的各种问题而出现的。ViewPage2是基于RecyclerView构建的。所以,我们就可以在Adapter中将RecyclerView.Adapter和ViewPager2一起使用。而且,自带懒加载功能。
实现步骤
- 定义一个ViewPager2
- 创建一个适配器Adapter
代码实现
首先ViewPage2是需要我们单独引用依赖的。
implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0' // ViewPager 2 需要使用 RecycleView 的 adapter
// MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Student> studentList = genData();
ViewPager2 viewPager2 = findViewById(R.id.view_pager2);
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(studentList);
viewPager2.setAdapter(viewPagerAdapter);
}
private List<Student> genData() {
List<Student> studentList = new ArrayList<>();
for(int i=1;i<11;i++){
Student student = new Student();
student.setId(i+" ");
student.setCodeSN("模拟数据");
student.setName("第"+i+"行:");
studentList.add(student);
}
return studentList;
}
}
<!--activity_main.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="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#868686"
/>
</LinearLayout>
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class ViewPagerAdapter extends RecyclerView.Adapter<ViewPagerAdapter.MyViewHolder> {
private List<Student> studentList;
public ViewPagerAdapter(List<Student> studentList) {
this.studentList = studentList;
}
/**
* 创建view
*
* @param parent
* @param viewType
* @return
*/
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.base_student_layout, parent,false));
}
/**
* 适配view的内容
*
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.tv_one.setText(studentList.get(position).getId());
holder.tv_two.setText(studentList.get(position).getName());
holder.tv_three.setText(studentList.get(position).getCodeSN());
}
/**
* 返回有多少个view
*
* @return
*/
@Override
public int getItemCount() {
return studentList==null?0:studentList.size();
}
/**
* 优化方法:
* 解析xml的,这边解析的是base_student_layout
*/
public class MyViewHolder extends RecyclerView.ViewHolder{
private TextView tv_one;
private TextView tv_two;
private TextView tv_three;
ConstraintLayout constraintLayout;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tv_one = itemView.findViewById(R.id.tv_one);
tv_two = itemView.findViewById(R.id.tv_two);
tv_three = itemView.findViewById(R.id.tv_three);
constraintLayout = itemView.findViewById(R.id.base_student_layout);
}
}
}
public class Student {
private String id;
private String name;
private String codeSN;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCodeSN() {
return codeSN;
}
public void setCodeSN(String codeSN) {
this.codeSN = codeSN;
}
}
<!-- base_student_layout.xml -->
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/base_student_layout">
<TextView
android:id="@+id/tv_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
app:layout_constraintEnd_toStartOf="@id/tv_two"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<TextView
android:id="@+id/tv_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<TextView
android:id="@+id/tv_three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
app:layout_constraintStart_toEndOf="@id/tv_two"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
tab联动实现(viewPager+fragment)
// MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private ViewPager2 viewPager2;
private LinearLayout lGroup,lEmail,lCar,lBike;
private ImageView iGroup,iEmail,iCar,iBike,iCurrent; //iCurrent保存当前的
private TextView tGroup,tEmail,tCar,tBike; //
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initPager();
initTabView();
}
private void initTabView(){
lGroup = findViewById(R.id.tag_group);
lGroup.setOnClickListener(this);
lEmail = findViewById(R.id.tag_email);
lEmail.setOnClickListener(this);
lCar = findViewById(R.id.tag_car);
lCar.setOnClickListener(this);
lBike = findViewById(R.id.tag_bike);
lBike.setOnClickListener(this);
iGroup = findViewById(R.id.tag_group_draw);
iEmail = findViewById(R.id.tag_email_draw);
iCar = findViewById(R.id.tag_car_draw);
iBike = findViewById(R.id.tag_bike_draw);
iGroup.setSelected(true);
iCurrent = iGroup;
}
private void initPager() {
viewPager2 = findViewById(R.id.id_view_pager2);
ArrayList<Fragment> fragments = new ArrayList<>();
fragments.add(BlankFragment.newInstance("分组"));
fragments.add(BlankFragment.newInstance("邮箱"));
fragments.add(BlankFragment.newInstance("汽车"));
fragments.add(BlankFragment.newInstance("小电驴"));
MyFragmentPageAdapter pageAdapter = new MyFragmentPageAdapter(getSupportFragmentManager(),getLifecycle(),fragments);
viewPager2.setAdapter(pageAdapter);
// viewPager2给我们提供滑动的监听接口
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
// 滚动动画
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
// 页面选择,可以修改对应按钮
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
changeTab(position);
}
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
}
private void changeTab(int position) {
iCurrent.setSelected(false);
switch (position){
// 判断ID,onClick调用
case R.id.tag_group:
viewPager2.setCurrentItem(0);
// 判断位置
case 0:
iGroup.setSelected(true);
iCurrent = iGroup;
break;
case R.id.tag_email:
viewPager2.setCurrentItem(1);
case 1:
iEmail.setSelected(true);
iCurrent = iEmail;
break;
case R.id.tag_car:
viewPager2.setCurrentItem(2);
case 2:
iCar.setSelected(true);
iCurrent = iCar;
break;
case R.id.tag_bike:
viewPager2.setCurrentItem(3);
case 3:
iBike.setSelected(true);
iCurrent = iBike;
break;
}
}
@Override
public void onClick(View view) {
changeTab(view.getId());
}
}
// BlankFragment.java
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class BlankFragment extends Fragment {
private static final String ARG_TEXT = "param1";
private String mTextStr;
private View rootView;
public BlankFragment() {
}
public static BlankFragment newInstance(String param1) {
BlankFragment fragment = new BlankFragment();
Bundle args = new Bundle();
args.putString(ARG_TEXT, param1);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mTextStr = getArguments().getString(ARG_TEXT);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(rootView==null){
rootView= inflater.inflate(R.layout.fragment_blank, container, false);
}
initView();
return rootView;
}
private void initView() {
TextView textView = rootView.findViewById(R.id.first_fragment);
textView.setText(mTextStr);
}
}
//MyFragmentPageAdapter.java
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.ArrayList;
import java.util.List;
/**
* FragmentStatePagerAdapter :
* 在每次切换页面的时候,是将fragment进行回收,适合页面较多的fragment使用,这样就不会消耗更多的内存。
* FragmentPagerAdapter:
* 在每次切换页面的时候,是将fragment进行分离,适合页面较少的fragment使用以保存一些内存,对系统内存不会有多大影响。
*/
public class MyFragmentPageAdapter extends FragmentStateAdapter {
private List<Fragment> fragmentList = new ArrayList<>();
public MyFragmentPageAdapter(@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==null?0:fragmentList.size();
}
}
<!-- activity_main.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="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<!--
为什么这边高度设置0dp?
因为ViewPager2设置0dp后,可以自动设置高度。
当有tab页后,viewPage2就会吧这块内容高度扣除,然后填充剩下的区块
如果没有tab,默认填充整个页面。
注意:这边要搭配layout_weight使用,否则失效
-->
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/id_view_pager2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<include layout="@layout/bottom_tab_layout"></include>
</LinearLayout>
<!-- bottom_tab_layout.xml -->
<?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="50dp"
android:orientation="horizontal"
android:background="#E0E0E0">
<LinearLayout
android:id="@+id/tag_group"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/tag_group_draw"
android:layout_width="32dp"
android:layout_height="32dp"
android:gravity="center"
android:background="@drawable/ic_baseline_group_24"
android:backgroundTint="@color/black"
/>
<TextView
android:id="@+id/tag_group_content"
android:layout_width="32dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="分组"/>
</LinearLayout>
<LinearLayout
android:id="@+id/tag_email"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/tag_email_draw"
android:layout_width="32dp"
android:layout_height="32dp"
android:gravity="center"
android:background="@drawable/ic_baseline_forward_to_inbox_24"
android:backgroundTint="@color/black" />
<TextView
android:id="@+id/tag_email_content"
android:layout_width="32dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="邮件"/>
</LinearLayout>
<LinearLayout
android:id="@+id/tag_car"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/tag_car_draw"
android:layout_width="32dp"
android:layout_height="32dp"
android:gravity="center"
android:background="@drawable/ic_baseline_electric_car_24"
android:backgroundTint="@color/black" />
<TextView
android:id="@+id/tag_car_content"
android:layout_width="32dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="汽车"/>
</LinearLayout>
<LinearLayout
android:id="@+id/tag_bike"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/tag_bike_draw"
android:layout_width="32dp"
android:layout_height="32dp"
android:gravity="center"
android:background="@drawable/ic_baseline_electric_bike_24"
android:backgroundTint="@color/black" />
<TextView
android:id="@+id/tag_bike_content"
android:layout_width="32dp"
android:layout_height="wrap_content"
android:text="电车"/>
</LinearLayout>
</LinearLayout>
<!--fragment_blank.xml -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".BlankFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/first_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="36sp"
android:textColor="@color/black"
android:gravity="center"/>
</FrameLayout>