今天又看到了广告轮播图的效果,自己也就写下来,作为一个笔记吧,俗话说,好记性不如烂笔头,也可以供大家参考一下,如果有错误请大家指出来,一起学习交流。
我个人归纳了一下实现轮播效果有以下几个步骤:
一、给ViewPager准备好数据源
二、ViewPager设置Adapter
三、实现ViewPager自动轮播
四、ViewPager设置OnPageChangeListener
五、设置轮播图的触摸事件和点击事件
六、滑动事件和OnPageChangeListener 他们之前的冲突
OK,接下来我们实现第一步
一、给ViewPager准备好数据源
//这里的图片和文字大家可以自行准备
//图片就是轮播的图片
private int images[]={R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.d,R.drawable.e};
//这个轮播图下面的文字
private String titles[] = {"计算机网络","C程序教程","软件项目管理","JavaScript基础教程","Android开发艺术探索"};
for (int i = 0; i < images.length; i++) {
ImageView imageView = new ImageView(this);
imageView.setBackgroundResource(images[i]);
imageViews.add(imageView);
ImageView point = new ImageView(this);
//这里是将dp转化为像素,以便更好的适应各种屏幕
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(DisplayUtils.dp2px(this, 8), DisplayUtils.dp2px(this, 8));
//这个是文字下面的点(被选中的为红色),这个可以叫美工
//做好图片,这里我就没有图片,使用的选择器,代码我后面也会贴出
point.setBackgroundResource(R.drawable.point_selector);
if (i == 0) {
point.setEnabled(true); //显示红色
} else {
point.setEnabled(false);//显示灰色
lp.leftMargin = DisplayUtils.dp2px(this, 8);
}
point.setLayoutParams(lp);
ll_point.addView(point);
}
数据准备好了 让我们来实现第二步给ViewPager设置Adapter
mViewPager.setAdapter(new MyPagerAdapter());
class MyPagerAdapter extends PagerAdapter {
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = imageViews.get(position);
container.addView(imageView);
return imageView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container, position, object);
container.removeView((View) object);
}
@Override
public int getCount() {
return imageViews.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
ok ,也就是这样的简单,当然你也可以使用匿名内部类,这个我觉得看个人的喜欢就好,然后我们接下来我们来实现第三步,图片的无限自动轮播,其实很简单,使用Handler,
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int item = mViewPager.getCurrentItem() + 1;
mViewPager.setCurrentItem(item);
mHandler.sendEmptyMessageDelayed(0, 3000);
}
};
只要在MyPagerAdapter 改几行代码就可以了,改一下getCount()方法
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
和instantiateItem(ViewGroup container,int positon)方法
@Override
public Object instantiateItem(ViewGroup container, int position) {
//求余
int relPosition = position % images.length;
ImageView imageView = imageViews.get(relPosition);
container.addView(imageView);
return imageView;
}
接下来实现第四步,给ViewPager设置OnPageChangeListener
class MyOnPagerChangeListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
int relPosition = position % images.length;
mTitle.setText(titles[relPosition]);
ll_point.getChildAt(prePosition).setEnabled(false);//上一个设置为灰色
ll_point.getChildAt(relPosition).setEnabled(true);//当前的设置为红色
prePosition = relPosition;
}
/**
* 静止--> 滑动
* 滑动-->静止
* 静止-->拖拽
*
* @param state
*/
@Override
public void onPageScrollStateChanged(int state) {}
}
我们有时候会有这样的需求,就是当我们手指点在图片上的时候,图片停止自动轮播,当我们手放开的时候,图片又自动轮播起来,这个其实也很简单,只要改一下instantiateItem(ViewGroup container, int position) 方法就ok,接下来我就实现以下这样的效果
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = imageViews.get(position);
container.addView(imageView);
imageView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
L.i("action down .. ");
mHandler.removeCallbacksAndMessages(null);//移除所有的消息
break;
case MotionEvent.ACTION_UP:
L.i("action up .. ");
mHandler.removeCallbacksAndMessages(null);//移除所有的消息
mHandler.sendEmptyMessageDelayed(0, 3000);
break;
}
return false;//若返回为true 则无法实现点击事件
}
});
imageView.setTag(relPosition);//这样可以拿到点击的位置
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = (int) imageView.getTag();
Toast.makeText(MyBannerActivity.this, "you click the imageview position is :" + position, Toast.LENGTH_SHORT).show();
}
});
return imageView;
}
哈哈哈,终于完成了,但是你会发现,这个滑动事件和那个ontouch之间会有冲突,当你点住轮播图,往右(左)拖一定的距离,然后你释放,发现ACTION_UP效果并没有实现,图片不会自动轮播了,这样子用户的体验就不是很好了,接下来,我们来解决这个问题
这就是图片轮播的最后一步,只要onPageScrollStateChanged(int state)这个方法就可以了,我们用一个boolean的值来判断用户是否拖拽,初始值为false.
private boolean isDragging = false;
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE && isDragging) {
isDragging = false;
mHandler.removeCallbacksAndMessages(null);
mHandler.sendEmptyMessageDelayed(0, 3000);
} else if (state == ViewPager.SCROLL_STATE_DRAGGING) {
isDragging = true;
mHandler.removeCallbacksAndMessages(null);
}
}
接下来我贴出完整的代码
布局文件 activity_banner.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/vp_banner"
android:layout_width="match_parent"
android:layout_height="180dp">
</android.support.v4.view.ViewPager>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/vp_banner"
android:gravity="center"
android:background="#44000000"
>
<TextView
android:id="@+id/tv_title"
android:text="加勒比海盗5"
android:textColor="#ffffff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<LinearLayout
android:gravity="center"
android:id="@+id/ll_point"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
</LinearLayout>
</RelativeLayout>
选择器
point_selector.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_nor"/>
<item android:state_enabled="true" android:drawable="@drawable/point_heightlight"/>
</selector>
point_nor.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<size android:height="8dp"
android:width="8dp"/>
<solid android:color="#44000000"/>
</shape>
point_heightlight.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<size android:height="8dp"
android:width="8dp"/>
<solid android:color="#FF0000"/>
</shape>
MyBannerActivity.java
/**
* author WuGuofei on 2017/6/4.
*/
public class MyBannerActivity extends AppCompatActivity {
private ViewPager mViewPager;
private LinearLayout ll_point;
private TextView mTitle;
private List<ImageView> imageViews;
private int images[] = {R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e};
private String titles[] = {"计算机网络", "C程序教程", "软件项目管理", "JavaScript基础教程", "Android开发艺术探索"};
private int prePosition = 0;
private boolean isDragging = false;//是否拖拽
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int item = mViewPager.getCurrentItem() + 1;
mViewPager.setCurrentItem(item);
mHandler.sendEmptyMessageDelayed(0, 3000);
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_banner);
mViewPager = (ViewPager) findViewById(R.id.vp_banner);
ll_point = (LinearLayout) findViewById(R.id.ll_point);
mTitle = (TextView) findViewById(R.id.tv_title);
imageViews = new ArrayList<>();
for (int i = 0; i < images.length; i++) {
ImageView imageView = new ImageView(this);
imageView.setBackgroundResource(images[i]);
imageViews.add(imageView);
ImageView point = new ImageView(this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(DisplayUtils.dp2px(this, 8), DisplayUtils.dp2px(this, 8));
point.setBackgroundResource(R.drawable.point_selector);
if (i == 0) {
point.setEnabled(true); //显示红色
} else {
point.setEnabled(false);//显示灰色
lp.leftMargin = 16;
}
point.setLayoutParams(lp);
ll_point.addView(point);
}
mViewPager.setAdapter(new MyPagerAdapter());
mViewPager.addOnPageChangeListener(new MyOnPagerChangeListener());
int item = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % images.length;//为了是images的倍数,在中间的位置
mViewPager.setCurrentItem(item);
mTitle.setText(titles[prePosition]);
//发消息 实现自动轮播
mHandler.sendEmptyMessageDelayed(0, 3000);
}
class MyOnPagerChangeListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
int relPosition = position % images.length;
mTitle.setText(titles[relPosition]);
ll_point.getChildAt(prePosition).setEnabled(false);//上一个设置为灰色
ll_point.getChildAt(relPosition).setEnabled(true);//当前的设置为红色
prePosition = relPosition;
}
/**
* 静止--> 滑动
* 滑动-->静止
* 静止-->拖拽
*
* @param state
*/
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE && isDragging) {
isDragging = false;
mHandler.removeCallbacksAndMessages(null);
mHandler.sendEmptyMessageDelayed(0, 3000);
} else if (state == ViewPager.SCROLL_STATE_DRAGGING) {
isDragging = true;
mHandler.removeCallbacksAndMessages(null);
} else if (state == ViewPager.SCROLL_STATE_SETTLING) {
}
}
}
class MyPagerAdapter extends PagerAdapter {
@Override
public Object instantiateItem(ViewGroup container, int position) {
int relPosition = position % images.length;
final ImageView imageView = imageViews.get(relPosition);
container.addView(imageView);
imageView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
L.i("action down .. ");
mHandler.removeCallbacksAndMessages(null);//移除所有的消息
break;
case MotionEvent.ACTION_UP:
L.i("action up .. ");
mHandler.removeCallbacksAndMessages(null);//移除所有的消息
mHandler.sendEmptyMessageDelayed(0, 3000);
break;
}
return false;//若返回为true 则无法实现点击事件
}
});
imageView.setTag(relPosition);//这样可以拿到点击的位置
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = (int) imageView.getTag();
Toast.makeText(MyBannerActivity.this, "you click the imageview position is :" + position, Toast.LENGTH_SHORT).show();
}
});
return imageView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container, position, object);
container.removeView((View) object);
}
@Override
public int getCount() {
//return imageViews.size();
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
}
步骤就写到这里了,今天第一次写这个文章,写的条理不够好,望大家多多包涵,以后能力提升,一定对文章做出修改