代码写到这里我们发现代码结构看起来非常混乱,需要在主页面操作的地方很多,如果要改一项数据的话需要主页面和自定义类改好几个地方,我们的思路是尽可能的减少需要在主页面的操作,我们把能封装进自定义类的操作全都封装进自定义类。
因为我们在主页面操作自定义类的方法是setData
我们首先在自定义类创建一个继承pageradapter的静态抽象类适配器来代替setData方法内的适配器,然后把setData里面的自定义适配器的代码挪到这个类中,然后我们需要在主类中得到什么数据就用抽象方来强制获得,然后再在自定义类中操作。
首先是自定义类
package com.example.viewpager.views;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.example.viewpager.R;
public class LooperPager extends LinearLayout {
private ViewPager viewPager;
private TextView textView;
private LinearLayout linearLayout;
private BindTitleLisener bindTitleLisener = null;//标题,先设为空
private nInnerAdapter Adapter = null;//适配器类型的变量
public LooperPager(Context context) {
this(context,null);
}
public LooperPager(Context context, @Nullable AttributeSet attrs) {
this(context,attrs,0);
}
/**
* java必须有一个声明super的构造器,而且必须在开头,所以其他构造器声明的this,、
* 所以无论使用其他哪个构造器都必须要调用该构造器
* @param context
* @param attrs
* @param defStyleAttr
*/
public LooperPager(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//自定义布局绑定当前类,this:当前类,ture:确定绑定
LayoutInflater.from(context).inflate(R.layout.looper_pager,this,true);
inti();
}
/**
*
*/
private void inti() {
intiView();
initEven();
}
/**
* 对页面进行滑动监听的方法
*/
private void initEven() {
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
//切换的回调方法
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
//切换停止的回调方法
public void onPageSelected(int position) {
//当页面切换停止后获得标题
//如果标题不是空的,就设定标题为当前停止的页面标题里的数据
if (bindTitleLisener != null){
textView.setText(bindTitleLisener.getTitle(position));
}
//每次页面切换给指示器动态的添加焦点
setIndicaterPoint();
}
@Override
//状态改变的回调方法
public void onPageScrollStateChanged(int state) {
}
});
}
/**
* 获得标题的接口,
* 里面有一个获得标题的抽象方法
* 一个获取集合长度的抽象方法
*/
public interface BindTitleLisener{
String getTitle(int position);
}
/**
* 设置数据的方法
*/
public void setData(nInnerAdapter adapter,BindTitleLisener lisener){
bindTitleLisener = lisener;
viewPager.setAdapter(adapter);
//设定一个适配器类型的变量给下面的方法使用
viewPager.setCurrentItem(Integer.MAX_VALUE/2 +1);
this.Adapter = adapter;
//可以得到数据的个数,然后根据数据的个数动态的创建圆点,indicater(指示器)
setIndicaterPoint();
}
public abstract static class nInnerAdapter extends PagerAdapter{
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
/**
* 销毁
* 作用是达到循环使用,不会导致溢出
* @param container
* @param position
* @param object
*/
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
//删除数据
container.removeView((View) object);
}
/**
* 初始化
* @param container
* @param position
* @return
*/
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
int realPosition = position % getDataSize();
//绑定抽象方法得到的布局
View itemView = getSubView(container, realPosition);
//把绑定的布局添加到适配器
container.addView(itemView);
return itemView;
}
/**
* 抽象方法用来强制获得一个int类型的数据,
* 也就是需要填入集合的长度
* @return
*/
protected abstract int getDataSize();
/**
* 抽象方法用来强制获得一个view数据
* 抽象类调用时必须全部实现内部的抽象方法
* @param container
* @param position
* @return
*/
public abstract View getSubView(ViewGroup container, int position);
}
/**
* 根据适配器的getCount方法的长度来动态的创建指示器
* 同时每次页面切换的时候给当前页面的指示器换色
*/
private void setIndicaterPoint() {
if (Adapter != null&&bindTitleLisener!=null){
int count = Adapter.getDataSize();
linearLayout.removeAllViews();
for (int i = 0; i < count ; i++) {
View view = new View(getContext());
//每次循环添加的时候判断下当前的圆点是否是代表当前页面,如果是就变成红色
if (viewPager.getCurrentItem()%Adapter.getDataSize() == i){
//设置颜色(Color.parseColor("#ff0000")设置颜色字符串为红色)
view.setBackgroundColor(Color.parseColor("#ff0000"));
}else{
//设置颜色(Color.parseColor("#ffffff")设置颜色字符串为白色)
view.setBackgroundColor(Color.parseColor("#ffffff"));
}
//设置指示器大小
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams
(SizeUtil.dip2px(getContext(),5),SizeUtil.dip2px(getContext(),5));
view.setLayoutParams(layoutParams);
//设置指示器之间的间距
layoutParams.setMargins(SizeUtil.dip2px(getContext(),10),0,SizeUtil.dip2px(getContext(),10),0);
//添加到容器里
linearLayout.addView(view);
}
}
}
/**
* 加载view的方法
*/
private void intiView() {
viewPager = findViewById(R.id.viewPager);
textView = findViewById(R.id.looper_title_tv);
linearLayout = findViewById(R.id.looper_point_container_lv);
}
}
然后是主类
package com.example.viewpager;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerAdapter;
import com.example.viewpager.views.LooperPager;
import com.example.viewpager.views.PagerItem;
import java.util.ArrayList;
import java.util.List;
public class supper_MainActivity extends AppCompatActivity {
private LooperPager looperPager;
private List<PagerItem> list = new ArrayList<>();
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.supper_activity_main);
intiData();//这里数据填充要写在加载组件上面,如果写在下面,需要在方法内部写上刷新数据的方法
intiView();//加载组件的方法
}
/**
* 填充数据
*/
private void intiData(){
list.add(new PagerItem("第一张图片",R.mipmap.img1));
list.add(new PagerItem("第二张图片",R.mipmap.mig2));
list.add(new PagerItem("第三张图片",R.mipmap.mig3));
list.add(new PagerItem("第四张图片",R.mipmap.mig4));
}
private void intiView() {
//绑定布局
looperPager = findViewById(R.id.Looperpager);
//设置数据
looperPager.setData(new LooperPager.nInnerAdapter() {
@Override
protected int getDataSize() {
return list.size();
}
@Override
public View getSubView(ViewGroup container, int position) {
ImageView imageView = new ImageView(container.getContext());
imageView.setImageResource(list.get(position).getPicResId());
return imageView;
}
} , new LooperPager.BindTitleLisener() {
@Override
//获得当前位置图片的标题
public String getTitle(int position) {
return list.get(position % list.size()).getTitle();
}
});
}
}
改完之后就发现我们的主页面简洁了很多,只需要操作时填入一个view数据一个集合长度就能得到一个可用的适配器