Android轮播图的实现
这几天看了《Android开发艺术探索》这本书真的是挺不错的,学了自定义View之后打算动手实践一个轮播图控件,网上有很多实现的方法,我最后实现起来跟他们也基本上都是大同小异,主要我也是为了练练动手能力。先来个效果图,图片是在百度搜的正经图片,项目代码的链接放在文章的最后
分析
实现轮播图的方式大体上我看到了三种,一是使用安卓的Gallery控件来实现,二是使用HorizontalScrollView,三是使用ViewPager来实现,Gallery控件现在已经不推荐使用了,在源码中我们也看到了,现在推荐使用的是后面的两种,而我实现的方式选择了第三种ViewPager,整个实现流程可以大致分为一下三个部分:
1.AutoSlideView 也是轮播图控件的实现,这里我的控件继承自ViewGoup的FrameLayout子类,同时需要一个xml的布局文件来定义控件的样式,里面主要包括了ViewPager和下面指示器圆点的容器。
2.Adapter的实现,需要给AutoSlideView中的ViewPager指定适配器,来指定轮播图中需要展示出来的View控件,同时也需要每个具体ItemView的xml布局文件,ViewPager的Adapter和ListView的Adapter使用起来思想上都不会相差太多。
3.SlideInfo 数据类的设计,因为实际的开发中轮播图需要的图片之类的信息是需要从服务器上拉取的,需要对数据进行一次封装。
SlideInfo类的实现
//由于我这个不涉及到具体的业务,所以这个类仅仅只是设置了一个图片的URL
public class SlideInfo {
String image_url ="dd";
public SlideInfo(){}
public SlideInfo(String url){
this.image_url = url;
}
public String getImage_url() {
return image_url;
}
}
Adapter的实现
首先PagerAdapter使用时需要重写四个方法,考虑到如果轮播图实用在不同的界面上,可能会有多种不同的ItemView 如果每次都重写一个PagerAdapter 会造成大量重复代码的编写,可以考虑编写一个抽象的适配器,把获取View单独让子类去实现
AutoSlideViewAdapterBase类
package com.humorousz.myapplication.adapter;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* Created by zhangzhiquan on 2016/7/14.
*/
public abstract class AutoSlideViewAdapterBase extends PagerAdapter {
private List<View> mList;
public AutoSlideViewAdapterBase() {
mList = new ArrayList<>();
}
@Override
public int getCount() {
/**
* 这里需要说明一点,因为我们需要循环滑动
* 但是ViewPager本身并不支持,所以我们需要给
* ViewPager的页面设置成int最大值造成循环滑动
* 的假象,具体可以在网上搜索ViewPager循环滑动
* 可能会有更好的实现方式
*/
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View v;
/**
* 我在实验的时候发现有时候size和position的差值大于一
* 造成越界,所以在这添加从size到实际位置的View
*/
if (mList.size() <= (position % getSize())) {
for(int i=mList.size() ; i<=position%getSize();++i){
mList.add(getView(container,i));
}
}
v = mList.get(position % getSize());
if(v.getParent() != null){
container.removeView(v);
}
container.addView(v);
return v;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mList.get(position % getSize()));
}
/**
*抽象的方法,用于获取实际需要显示的View
*/
public abstract View getView(ViewGroup container,int position);
/**
*用于获取实际ItemView的数量
*/