有现成的还是用现成的吧 毕竟别人都封装好了
方式一
缺点
自动滑动到最后一张时继续滑动会闪一下, 效果不好, ,阔以设置滑动速度, ,让每次滑动都立刻到下一张
思路
假设有三张图片a, b, c, 当滑动到 c 时, 如果直接使用 viewpager 的setCurrentItem
方法跳到 a 时, c 就无法正常显示; 因此可以在 c 后面加一张 a1, 当滑动到 c 时可以继续滑动, 当滑动到 a1 时使用 setCurrentItem
方法跳到 a 即可. 同理, 为避免上述问题应该在 a 前加一张 c1, 并设置初始位置为1
, 当初次运行程序时向左滑动, 滑动到 c1 使用setCurrentItem
方法跳到 c 即可.
自动轮播实现思路
使用sendEmptyMessageDelayed
方法实现定时发送
直接复制
adapter
private class ViewPagerAdapter extends PagerAdapter{
private List<Integer> imgs;
public ViewPagerAdapter(List<Integer> imgs){
this.imgs = imgs;
}
@Override
public int getCount() {
return imgs.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
// super.destroyItem(container, position, object);
container.removeView((View) object);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
ImageView imageView = new ImageView(MainActivity.this);
imageView.setImageResource(imgs.get(position));
container.addView(imageView);
return imageView;
}
}
设置滑动速度
public class ViewPagerScroller extends Scroller {
private int mScrollDuration = 0; // 滑动速度
/**
* 设置速度速度
* @param duration
*/
public void setScrollDuration(int duration){
this.mScrollDuration = duration;
}
public ViewPagerScroller(Context context) {
super(context);
}
public ViewPagerScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
public ViewPagerScroller(Context context, Interpolator interpolator, boolean flywheel) {
super(context, interpolator, flywheel);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
super.startScroll(startX, startY, dx, dy, mScrollDuration);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
super.startScroll(startX, startY, dx, dy, mScrollDuration);
}
public void initViewPagerScroll(ViewPager viewPager) {
try {
Field mScroller = ViewPager.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);
mScroller.set(viewPager, this);
} catch(Exception e) {
e.printStackTrace();
}
}
}
activity
private ViewPager viewPager;
private List<Integer> imgs = new ArrayList<>();
@SuppressLint("HandlerLeak")
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1){
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
handler.sendEmptyMessageDelayed(1, 2000);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.m_view_pager);
imgs.add(R.drawable.zzz);
imgs.add(R.drawable.kkk);
imgs.add(R.drawable.lll);
imgs.add(R.drawable.zzz);
imgs.add(R.drawable.kkk);
ViewPagerScroller scroller = new ViewPagerScroller(this);
scroller.setScrollDuration(150);//设置滑动时间为150毫秒
scroller.initViewPagerScroll(viewPager);
viewPager.setAdapter(new ViewPagerAdapter(imgs));
viewPager.setCurrentItem(1);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (position == 0){
viewPager.setCurrentItem(imgs.size() - 2);
return;
}
if (position == (imgs.size() - 1)){
viewPager.setCurrentItem(1);
return;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
handler.sendEmptyMessageDelayed(1, 2000);
}
方式二
思路
设置adapter返回一个无限大的值, 当滑动到大于集合/数组数量时进行取余
缺点
,,第一次进入界面开始轮播后无法向左滑动,,不过看CSDN官方软件也是这样的,,(手动狗头)
自动轮播和方式一思路一致
举个栗子
语言为kotlin, 接口为WanAndroid主页轮播
ViewPagerAdapter
class ViewPagerAdapter constructor(
context: Context,
list: ArrayList<BannerData>
): PagerAdapter() {
private var mClick: OnItemClick? = null
private var context: Context? = null
private var bannerData: MutableList<BannerData>? = null
init {
this.context = context
this.bannerData = list
}
fun setClick(mClick: OnItemClick){
this.mClick = mClick
}
override fun isViewFromObject(view: View, `object`: Any): Boolean = view == `object`
override fun getCount(): Int = Int.MAX_VALUE
// override fun getItemPosition(`object`: Any): Int = POSITION_NONE
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(`object` as View?)
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val imgView = ImageView(context)
if (bannerData!!.isNotEmpty()){
val imgUrl = bannerData!![position % bannerData!!.size].imagePath
imgView.setOnClickListener { mClick?.itemClick(position % bannerData!!.size) }
Glide.with(container).load(imgUrl).into(imgView)
}
container.addView(imgView)
return imgView
}
}
页面使用碎片
class HomePage: BaseFragment(), OnItemClick<BannerData> {
private var homeModelImpl = HomeModelImpl()
private val handlerBanner = Config.HOME_BANNER
private var adapter: ViewPagerAdapter? = null
private var handler = Handler{
when (it.what){
handlerBanner -> {
home_banner.currentItem = position + 1
}
}
false
}
private var bannerData = ArrayList<BannerData>()
private var position = 0
override fun layout(): Int = R.layout.main_home_page
override fun initData() {
home_banner.addOnPageChangeListener(pageChangeListener)
homeModelImpl.getBanner(object: CallbackView<BannerBean> {
override fun onSuccess(t: BannerBean) {
bannerData.clear()
bannerData.addAll(t.data)
adapter = ViewPagerAdapter(context!!, bannerData)
adapter!!.setClick(this@HomePage)
home_banner.adapter = adapter
LogUtils.i("Success! adapter is notify data set changed")
handler.sendEmptyMessageDelayed(handlerBanner, 3000)
}
override fun onFail(throwable: Throwable) {
LogUtils.e("Fail: " + throwable.message)
}
override fun onError(code: Int) {
LogUtils.e("Error code = $code")
}
})
}
private var pageChangeListener: ViewPager.OnPageChangeListener = object: ViewPager.OnPageChangeListener{
override fun onPageScrollStateChanged(state: Int) {
if (state == 1){//手指触摸
handler.removeMessages(handlerBanner)
}else if (state == 0){//滑动结束
handler.sendEmptyMessageDelayed(handlerBanner, 3000)
}
}
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int
) {}
override fun onPageSelected(i: Int) {
position = i
// LogUtils.e("Page selected position = $i")
}
}
override fun itemClick(t: BannerData, position: Int) {
LogUtils.i(t.title)
}
override fun onDestroy() {
super.onDestroy()
handler.removeMessages(handlerBanner)
}
}
推荐阅读: ViewPager2: 打造Banner控件