源码下载地址:
http://download.csdn.net/detail/diudiu666hf/9675265
使用ViewPager实现广告条,轮播图等,一般轮播图有如下几个方面组成,图片,字幕,以及下面的小圆点
<RelativeLayout 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=".MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="180dp">
</android.support.v4.view.ViewPager>
<LinearLayout
android:layout_alignBottom="@id/viewpager"
android:background="#44000000"
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/ad_title"
android:textColor="#ffffff"
android:layout_gravity="center_horizontal"
android:padding="3dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="111"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
android:id="@+id/ll_point_group"></LinearLayout>
</LinearLayout>
</RelativeLayout>
对其中的id初始化完毕后,viewPager的使用其实和ListView的使用基本一致,首先准备数据源,然后新建一个适配器,viewpager继承的是PagerAdapter,使用适配器。
第一、准备数据源,这里需要准备你要轮播的图片以及图片下面的文本
private final int [] imageIds = {R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.d,R.drawable.e,R.drawable.f};
private final String [] imageDetail = {"小蝴蝶", "羽毛", "花和书", "荷花", "小孩和西瓜", "教师"};
<pre class="java" name="code">
imgView = new ArrayList<>();
for (int i = 0;i < imageIds.length;i++) {
ImageView img = new ImageView(this);
img.setBackgroundResource(imageIds[i]);
//添加到集合中
imgView.add(img);
}
第二、新建类myViewPager继承PagerAdapter
public class myViewPager extends PagerAdapter{
//轮播图的总数
@Override
public int getCount() {
return imgView.size();
}
/**
* 相当于getView()
* @param container
* @param position
* @return
*/
@Override
public Object instantiateItem(ViewGroup container, final int position) {
ImageView img = imgView.get(position);
container.addView(img);//添加到viewPager中
return img;
}
/**
* 比较view和object是否是同一实例
* @param view 页面
* @param object instantiateItem返回的结果
* @return
*/
@Override
public boolean isViewFromObject(View view, Object object) {
/*if (view == object) {
return true;
} else {
return false;
}*/
return view == object;
}
/**
* 释放资源
* @param container viewpage
* @param position 要释放的位置
* @param object 要释放的页面
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
第三、使用适配器,做到
viewpager.setAdapter(new myViewPager());
做到这里我们只是有图片,可以拖动,上面的文字以及下面的小圆点还没有进行设置
接着设置下面的小圆点,下面的小圆点是设置在LinearLayout中的,由于每个图片下面都有小圆点,因此我们在之前的加载图片到imgView的for循环里面进行加载圆点
//添加点 ImageView point = new ImageView(this); point.setBackgroundResource(R.drawable.point_select); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(8,8); //由于当前页面的小圆点的颜色是和其他的是不一样,我们在point_select的xml里是通过设置Enable来改变颜色的,首先得先让第一个图的颜色是红色,其余是灰色
if (i == 0) {
point.setEnabled(true);
} else {
point.setEnabled(false);
params.leftMargin = 8;
}
point.setLayoutParams(params);
//添加到线性布局
ll_point_group.addView(point);
下来是设置点的xml文件
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:drawable="@drawable/point_normol"/>
<item android:state_enabled="true" android:drawable="@drawable/point_pressed"/>
</selector>
point_normol的xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <size android:width="8dp" android:height="8dp"/> <solid android:color="#44000000"/> </shape>
point_pressed的xml和其差不多,只是修改了一下颜色为红色而已,这里就不写了
当然目前下面是有圆点了,但是当拖动图片,图片发生改变时,下面的小圆点的颜色并未发生改变
定义一个变量,表示上一位置的变量,private int preposition = 0;//上一页面的位置
需要对viewPager设置监听页面的改变viewpager.addOnPageChangeListener(new MyOnPageChange());
MyOnPageChange类的具体实现
class MyOnPageChange implements ViewPager.OnPageChangeListener {
/**
* 当页面滚动的时候回调这个方法
* @param position 当前页面的位置
* @param positionOffset 滑动页面的百分比
* @param positionOffsetPixels 在屏幕上滑动的像素
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
/**
* 当某个页面被选中的时候回调
* @param position 被选中页面的位置
*/
@Override
public void onPageSelected(int position) {
//设置对应文本信息
ad_title.setText(imageDetail[position]);
//把上一个高亮设置默认-灰色
ll_point_group.getChildAt(preposition).setEnabled(false);
//当前的位置为高亮-红色
ll_point_group.getChildAt(position).setEnabled(true);
preposition = position;
}
/**
* 当页面滚动状态变化时回调这个方法
* 静止->滑动
* 滑动->静止
* 静止->拖拽
* @param state
*/
@Override
public void onPageScrollStateChanged(int state) {
}
}
}
这样的话,文本,点都有了,但是这个广告条目前是不能自动播放的,自动播放我们可以通过handler来实现
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int item = viewpager.getCurrentItem()+1;
viewpager.setCurrentItem(item);
handler.sendEmptyMessageDelayed(0,3000);//延迟3秒,继续播放
}
};
我们不要忘了设置初始发送消息,在onCreate方法里面
handler.sendEmptyMessageDelayed(0, 2000);
运行之后,我们发现虽然可以进行自动播放了的,但是不能让他在播放完最后一个的时候继续向右滑动来播放第一个图片,以及在才开始的时候,不能在第一个图片上向左滑动,来播放最后一张图片,因此需要在适配器中的getCount的返回改成Integer.MAX_VALUE以及将所有的position改成position%imgView.size()但是这样后,我们发现播放最后一张图片的时候是可以向右滑动后进入第一张图片,但是仍然不能使向左滑动第一张图片进入最后一张,这是因为第一张图片前面没有,那么怎么解决呢?
//设置中间位置 int item = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % imgView.size();//要保证是ImageView的整数倍 viewpager.setCurrentItem(item);
但是依然是有问题的,在自动播放的时候,我们滑动了一张照片后,它就不在自动播放了,那么怎么解决呢???我们在自定义的适配器中的instantiateItem方法内设置触摸事
//为图片设置触摸事件 img.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN://按下 handler.removeCallbacksAndMessages(null); break; case MotionEvent.ACTION_UP://起来 handler.sendEmptyMessageDelayed(0,3000); break; case MotionEvent.ACTION_MOVE://移动 break; } return false; } });
但是我们发现仅仅这样是不够的,通过日志文件,我们发现在起来的时候会调用cancel,需要在onPageScrollStateChanged方法里面设置
@Override
public void onPageScrollStateChanged(int state) {
if (state == viewpager.SCROLL_STATE_DRAGGING) {//拖拽状态
isDragging = true;
} else if (state == viewpager.SCROLL_STATE_SETTLING) {//滑动状态
} else if (state == viewpager.SCROLL_STATE_IDLE && isDragging) {//空闲状态
isDragging = false;
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(0,3000);
}
}
最后一个,设置点击事件
img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//int post = (int) img.getTag() % imgView.size();
// Toast.makeText(MainActivity.this,imageDetail[post],Toast.LENGTH_LONG).show();
Toast.makeText(MainActivity.this,imageDetail[position%imgView.size()],Toast.LENGTH_LONG).show();
}
});
但是我们在点击时发现点击后会出现停止运行,这是因为我们在触摸事件的时候返回的是true,已经被消费了,因此需要将true改为false