基本操作和一开始的ViewPager实现一个自动轮播的轮播图第二节实现图片无限滑动_菜的一叽的博客-CSDN博客
这一节相同,都是先把适配器的获取长度的地方改成一个足够大的数,然后就是在加载的地方把中间设置为最大值除以2,不同的地方就是咱们自定义适配器的类里设置指示器里的方法里面有用到过适配器获取长度的方法,如果不处理的话会直接报错,因为我们是基于长度设置底部圆点,适配器长度改成一个很大的数,圆点会无限创建。
这里我们解决方法是在获得标题的接口里面添加一个获得集合size的抽象方法,然后在主类初始化的地方就必须实现这个抽象方法从而从主类拿到了集合size给自定义类使用。
然后我们在自定义类的添加指示器的方法内先把for循环里面设定长度的值换成集合的size,再把判断当前页面的值变成当前ViewPager的位置取模集合的size,再把最外层判断当前适配器是否为空的后面加上一句判断当前标题是否为空就完成了
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.widget.Adapter;
import android.widget.LinearLayout;
import android.widget.TextView;
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 PagerAdapter 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);
int getListSize();
}
/**
* 设置数据的方法
*/
public void setData(PagerAdapter adapter,BindTitleLisener lisener){
bindTitleLisener = lisener;
viewPager.setAdapter(adapter);
//设定一个适配器类型的变量给下面的方法使用
viewPager.setCurrentItem(Integer.MAX_VALUE/2 +1);
this.Adapter = adapter;
//可以得到数据的个数,然后根据数据的个数动态的创建圆点,indicater(指示器)
setIndicaterPoint();
}
/**
* 根据适配器的getCount方法的长度来动态的创建指示器
* 同时每次页面切换的时候给当前页面的指示器换色
*/
private void setIndicaterPoint() {
if (Adapter != null&&bindTitleLisener!=null){
int count = bindTitleLisener.getListSize();
linearLayout.removeAllViews();
for (int i = 0; i < count ; i++) {
View view = new View(getContext());
//每次循环添加的时候判断下当前的圆点是否是代表当前页面,如果是就变成红色
if (viewPager.getCurrentItem()%bindTitleLisener.getListSize() == 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 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
* @return
*/
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
//绑定布局
View item = LayoutInflater.from(container.getContext()).inflate(R.layout.item,container,false);
//设置数据
ImageView imageView = item.findViewById(R.id.imageView);
//先把imageview绑定
int realPosition = position % list.size();
imageView.setImageResource(list.get(realPosition).getPicResId());
//然后在imageview中填入集合中的图片数据
if (imageView.getParent() instanceof ViewGroup){
((ViewGroup) imageView.getParent()).removeView(imageView);
}
//不添加这行代码会报错,改子类已经拥有一个父类,这里我们判断如果父类是group就在父类中删除,
// 如果不是就直接添加进pager里面
container.addView(imageView);
return imageView;
}
/**
* 销毁
* 作用是达到循环使用,不会导致溢出
* @param container
* @param position
* @param object
*/
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
//删除数据
container.removeView((View) object);
}
}, new LooperPager.BindTitleLisener() {
@Override
//获得当前位置图片的标题
public String getTitle(int position) {
return list.get(position % list.size()).getTitle();
}
@Override
public int getListSize() {
return list.size();
}
});
}
}
这样就实现了图片的前后无限滑动和指示器的动态创建