前言:一直以来都没有写过博客,总是一如既往的做着代码的搬运工,竟然还乐此不疲,最近突然醒悟,既然干了这一行,总得记录一下自己的屌丝岁月吧0.0!不求文章质量多高,只要对自己有提高就很好了。这是第一篇,技术含量不高,算是记录一下吧,方便以后开发类似功能时复用~0.0还是懒啊!!!。。。。
正文: 市场上大部分app都有广告条的功能,自己做过几个应用也都用到了。于是想着以后方便复用,便简单封装了一下,自定义(BannerViewPager)实现轮播,还是很实用的哦!~代码很简单,一看就懂
一:先看一下效果图吧
banner.gif
二:直接贴代码
BannerViewPager.java
public class BannerViewPager extends ViewPager{
private Context mContext;
/**
* 图片集合
*/
private List mImageUrlLists;
/**
* 指示器小点集合
*/
private List mDotList;
private TextView mTvdesc;
private List mDesclist;
private float downX;
private float downY;
/**
* 是否自动滚动(默认不开启)
*/
private boolean isRoll = false;
private boolean flag = false;
//=======================对外提供一下方法======================================================
/**
* 设置是否开启轮播
* @param isRoll (可选择是否调用)
*/
public void setisRoll(boolean isRoll) {
this.isRoll = isRoll;
}
/**
* 设置图片url集合(这个必须要调用 传入)
* @param mImageUrlLists
*/
public void setImageUrlLists(List mImageUrlLists) {
this.mImageUrlLists = mImageUrlLists;
}
/**
* 设置点集合 (可选择是否调用)
* @param mDotList
*/
public void setDotList(List mDotList) {
this.mDotList = mDotList;
}
/**
* 设置图片描述文字(可选择是否调用)
*
* @param tvdesc
* @param titleLists
*/
public void setTitleList(TextView tv, List titleLists) {
this.mTvdesc = tv;
this.mDesclist = titleLists;
if (mTvdesc != null && mDesclist != null
&& mDesclist.size() > 0) {
mTvdesc.setText(mDesclist.get(0));
}
}
/**
* 显示轮播图
*/
public void showBanner() {
// 初始化的操作
if (!flag) {
flag = true;
prepareData();
}
if (isRoll) {
// 发送延时消息 5s
handler.sendEmptyMessageDelayed(100, 5000);
}
}
//======================================end=============================================================
public BannerViewPager(Context context) {
super(context);
this.mContext = context;
}
/**
* 使用handler来达到viewpager的自动切换
*/
public Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
BannerViewPager.this.setCurrentItem(BannerViewPager.this
.getCurrentItem() + 1);
showBanner();
}
};
@SuppressWarnings("deprecation")
private void prepareData() {
ViewPagerScroller viewPagerScroller = new ViewPagerScroller(mContext);
// 初始ViewPager时,使用反射修改滑动速度
viewPagerScroller.initViewPagerScroll(BannerViewPager.this);
BannerViewPager.this.setOnPageChangeListener(new MyOnPageChangeListener());
ViewPagerAdapter adapter = new ViewPagerAdapter(mContext,mImageUrlLists);
BannerViewPager.this.setAdapter(adapter);
// 保证初始化的时候从第一个图片开始
int item = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2
% mImageUrlLists.size();
BannerViewPager.this.setCurrentItem(item);
if (mDotList != null && mDotList.size() > 1) {
mDotList.get(0).setBackgroundResource(R.drawable.dot_focused);
}
}
/**
* 当前的postion
*/
private int currentPosition = 0;
/**
* 上一个postion
*/
private int oldPosition = 0;
public class MyOnPageChangeListener implements OnPageChangeListener {
@Override
public void onPageSelected(int postion) {
postion = postion % mImageUrlLists.size();
currentPosition = postion;
if (mTvdesc != null && mDesclist != null
&& mDesclist.size() > 0) {
mTvdesc.setText(mDesclist.get(postion));
}
//设置点的选中状态
if (mDotList != null) {
mDotList.get(postion).setBackgroundResource(R.drawable.dot_focused);
mDotList.get(oldPosition).setBackgroundResource(R.drawable.dot_normal);
}
oldPosition = postion;
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
}
/**
*重写事件分发 (用户触摸时停止自动滑动效果)
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
//通知父View自己要处理touch事件
getParent().requestDisallowInterceptTouchEvent(true);
downX = ev.getX();
downY = ev.getY();
handler.removeCallbacksAndMessages(null);
break;
case MotionEvent.ACTION_UP:
showBanner();
break;
case MotionEvent.ACTION_MOVE:
float currentX = ev.getX();
float currentY = ev.getY();
if (Math.abs(currentX - downX) > Math.abs(currentY - downY)) {
getParent().requestDisallowInterceptTouchEvent(true);
} else {
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return super.dispatchTouchEvent(ev);
}
@Override
protected void onDetachedFromWindow() {
handler.removeCallbacksAndMessages(null);
super.onDetachedFromWindow();
}
}
ViewPagerAdapter.Java
package com.example.demo01.ui;
import java.util.List;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.demo01.R;
import com.nostra13.universalimageloader.core.ImageLoader;
public class ViewPagerAdapter extends PagerAdapter {
private Context mContext;
private List mImageUrls;
public ViewPagerAdapter(Context context, List urls) {
this.mContext = context;
this.mImageUrls = urls;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = View.inflate(mContext, R.layout.banner_item, null);
final ImageView image = (ImageView) view.findViewById(R.id.image);
position %= mImageUrls.size();
if (position < 0) {
position = mImageUrls.size() + position;
}
String url = mImageUrls.get(position);
ImageLoader.getInstance().displayImage(url, image,ImageLoaderOptions.options);
// 设置监听viewPager的点击事件
image.setTag(position);
image.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int position = (Integer) image.getTag();
// TODO 处理图片的点击事件 一般是跳转到广告的详情界面
Toast.makeText(mContext, "position = " +position, 0).show();
}
});
((ViewPager) container).addView(view);
return view;
}
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
}
重写ViewPagerScroller达到viewpager自动轮播的时候平滑的移动的效果
public class ViewPagerScroller extends Scroller {
private int mScrollDuration = 1000; // 滑动速度
/**
* 设置速度速度
*
* @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);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
super.startScroll(startX, startY, dx, dy, mScrollDuration);
}
/**
* 此构找方法在11以上使用
*/
// public ViewPagerScroller(Context context, Interpolator interpolator,
// boolean flywheel) {
// super(context, interpolator, flywheel);
// // TODO Auto-generated constructor stub
// }
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
super.startScroll(startX, startY, dx, dy, mScrollDuration);
}
/**
* 通过反射的方式修改viewpager的滑动
*
* @param viewPager
*/
public void initViewPagerScroll(ViewPager viewPager) {
try {
//暴力反射
Field mScroller = ViewPager.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);
mScroller.set(viewPager, this);
} catch (Exception e) {
e.printStackTrace();
}
}
}
项目中使用的单位换算工具类DensityUtil.java
public class DensityUtil {
public static int dip2px(Context context, float dpValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
public static int px2dip(Context context, float pxValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}
布局文件如下:
banner_item.xml
drawable文件
dot_focused.xml
dot_normal.xml
使用时把以上代码和布局全部拷入项目即可
使用示例如下:
activity_main.xml
MainActivity.java代码:
public class MainActivity extends Activity {
private List dotList = new ArrayList();;
private ArrayList imageUrls = new ArrayList();
private ArrayList desclist = new ArrayList();
private LinearLayout topPagerLayout;
private LinearLayout dots_ll;
private BannerViewPager mViewPager;
private TextView mTvdesc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
private void initData() {
imageUrls
.add("http://www.sinaimg.cn/dy/slidenews/1_img/2016_42/2841_740089_670674.jpg");
imageUrls
.add("http://n.sinaimg.cn/sinanews/20161019/pj5u-fxwvpat5077743.jpg");
imageUrls
.add("http://n.sinaimg.cn/photo/20161019/fooN-fxwvpaq1734085.jpg");
imageUrls.add("http://n.sinaimg.cn/news/20161019/PFu3-fxwvpaq1755605.jpg");
imageUrls.add("http://n.sinaimg.cn/photo/20161019/muZP-fxwvpar8459655.jpg");
desclist.add("曼谷红灯区一家酒吧关门打烊");
desclist.add("新青年】十八线艺人的经纪人:在圈里混却闻不到星味儿");
desclist.add("如何用乐高拍出电影场景|拍答课堂");
desclist.add("“青年拍北京”北京国际青年旅游季");
desclist.add("跨界青春、观念和时尚,两大轻摄导师如何碰撞");
initDot(imageUrls.size());
showViewPageView();
}
private void initView() {
dots_ll = (LinearLayout) findViewById(R.id.dots_ll);
topPagerLayout = (LinearLayout) findViewById(R.id.viewPager);
mTvdesc = (TextView) findViewById(R.id.tv_titledesc);
}
/**
* 显示广告
*/
public void showViewPageView() {
//初始化控件
mViewPager = new BannerViewPager(this);
mViewPager.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
//设置数据源
mViewPager.setImageUrlLists(imageUrls);
mViewPager.setDotList(dotList);
mViewPager.setTitleList(mTvdesc, desclist);
//设置是否开启自动轮播 (默认不开启)
mViewPager.setisRoll(true);
mViewPager.showBanner();
//添加控件到viewGroup中去
topPagerLayout.removeAllViews();
topPagerLayout.addView(mViewPager);
}
/**
* 初始轮播图小点
*
* @param size
*/
private void initDot(int size) {
dots_ll.removeAllViews();
for (int i = 0; i < size; i++) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
DensityUtil.dip2px(this, 6), DensityUtil.dip2px(this, 6));
params.setMargins(5, 0, 5, 0);
View m = new View(this);
m.setLayoutParams(params);
if (i == 0) {
m.setBackgroundResource(R.drawable.dot_focused);
} else {
m.setBackgroundResource(R.drawable.dot_normal);
}
dotList.add(m);
dots_ll.addView(m);
}
}
}