打造Android一体化轮播广告条
在文章打造Android一体式轮播广告条中,我们已经学习了打造Android一体式轮播广告条的制作,在上篇文章中我们已经通过一种方法实现了广告条的无线循环。主要做的目的就是让ViewPager和指示器进行封装,方便我们使用,不需要多次进行指示器的控制。看过最后的效果图我们发现上篇的原理中,从最后一张图切换到第一张的时候,效果显得很突兀。所以我们尝试使用第二种思路进行。
第二种思路:通过给PageCount设置一个很大的数,来回实现效果。我们先来看看我们实现的原理:
根据上图,就是利用切换的循环倒置。让ViewPager走不到尽头,所以就实现了一种“假”循环的现象。本次的开发还是以上篇博客中的代码为基础进行开发,只在实现原理的位置进行了修改。
在这次的原理中,我们新增了两个成员变量:
/** * 设定的总循环个数 */ private int pageCount; /** * 设定的总页面数 */ private int numberPages;
这两个用于记录我们的页面信息,通常我们会设定一个很大的数作为总循环个数,但是注意,总循环数要是总页面的整数倍,不然循环判断的逻辑就要修改,所以此处,我也不指定,我直接赋值为总页面数的二倍。见代码:
/** * 设置图片的地址,从网络加载图片 * @param imageUrls */ public void addImageUrls(List<Bitmap> imageUrls) { this.imageUrls.addAll(imageUrls); numberPages = this.imageUrls.size(); pageCount = 2 * numberPages; createImageView(imageUrls); }
看过上篇文章的朋友会发现,我们上篇文章中是传入url地址,直接在内部进行加载图片,这次由于在内部循环,会导致ViewPager内部缓存的ImageView与需要添加的重复,导致报错(一个ImageView已经属于一个Container,需要进行删除)。所以为了方便,我将参数改为了Bitmap,然后在内部进行生成ImageView。
@Override public Object instantiateItem(ViewGroup container, int position) { position %= numberPages; ImageView imageView = null; imageView = new ImageView(context); imageView.setScaleType(ScaleType.FIT_XY); imageView.setBackgroundDrawable(new BitmapDrawable(imageUrls.get(position))); imageView.setTag(position); imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { if(viewPagerClick != null){ viewPagerClick.viewPagerOnClick(view); } } }); container.addView(imageView); return imageView; }
这次的切换逻辑不是在onPageSelected中进行处理,而是在finishUpdate中进行切换。
@Override public void finishUpdate(ViewGroup container) { if(numberPages == 1)return; int location = viewPager.getCurrentItem(); if(location == pageCount - 1){//为最后一张的时候,转换到顶部 location = numberPages -1; viewPager.setCurrentItem(location,false); }else if(location == 0){//为第一张的时候,切换到中间 location = numberPages; viewPager.setCurrentItem(location,false); } }其次一点就是通过Handler发送消息实现循环的处理。 private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { int currentPosition = viewPager.getCurrentItem(); currentPosition = (currentPosition + 1) % pageCount; if (currentPosition == pageCount - 1) { viewPager.setCurrentItem(numberPages - 1, false); } else { viewPager.setCurrentItem(currentPosition); } mHandler.sendEmptyMessageDelayed(0, 3000); } };
至此,基本的逻辑都已经实现完成。具体的代码就不贴了。相比较上篇介绍的,我们这次又新增了几个自定义属性,
<attr name="indicatorBigSize" format="dimension"/> <!-- 指示器选中时大小 --> <attr name="indicatorBackgroud" format="reference"/> <!-- 指示器背景色 --> <attr name="indicatorMarginBottom" format="dimension"/> <!-- 指示器距离底部 -->
我们介绍一个使用实例,看下布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:viewpager="http://schemas.android.com/apk/res/com.dsw.viewindicator" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.lcwang.androidviews.MainActivity" > <com.lcwang.androidviews.ViewPagerBarnner android:id="@+id/viewPager" android:layout_height="160dp" android:layout_width="match_parent" viewpager:indicatorSize="8dp" viewpager:indicatorInterval="10dp" viewpager:containerHeight="15dp" viewpager:indicatorMarginBottom="0dp" viewpager:indicatorBackgroud="@drawable/head_sbox" viewpager:indicatorDrawable="@drawable/indicator_backgroud" /> <com.lcwang.androidviews.first.ViewPagerBarnner android:id="@+id/viewPagerFirst" android:layout_height="160dp" android:layout_width="match_parent" android:layout_marginTop="20dp" viewpager:indicatorSize="8dp" viewpager:indicatorInterval="10dp" viewpager:containerHeight="15dp" viewpager:indicatorBackgroud="@drawable/head_sbox" viewpager:indicatorMarginBottom="0dp" viewpager:indicatorDrawable="@drawable/indicator_backgroud" /> </LinearLayout>
MainActivity中的逻辑:
public class MainActivity extends Activity { private List<Bitmap> url; private List<String> urlString; private ViewPagerBarnner viewPagerBarnner; private com.lcwang.androidviews.first.ViewPagerBarnner viewPagerBarnner1; private LinearLayout linear_layout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPagerBarnner = (ViewPagerBarnner) findViewById(R.id.viewPager); viewPagerBarnner1 = (com.lcwang.androidviews.first.ViewPagerBarnner) findViewById(R.id.viewPagerFirst); url = new ArrayList<Bitmap>(); url.add(BitmapFactory.decodeResource(getResources(), R.drawable.first)); url.add(BitmapFactory.decodeResource(getResources(), R.drawable.second)); url.add(BitmapFactory.decodeResource(getResources(), R.drawable.third)); url.add(BitmapFactory.decodeResource(getResources(), R.drawable.four)); url.add(BitmapFactory.decodeResource(getResources(), R.drawable.five)); url.add(BitmapFactory.decodeResource(getResources(), R.drawable.six)); viewPagerBarnner.addImageUrls(url); viewPagerBarnner.setViewPagerClick(new ViewPagerClick() { @Override public void viewPagerOnClick(View view) { Toast.makeText(MainActivity.this, "click:" + view.getTag().toString(), Toast.LENGTH_SHORT).show(); } }); urlString = new ArrayList<String>(); urlString.add("drawable://" + R.drawable.first); urlString.add("drawable://" + R.drawable.second); urlString.add("drawable://" + R.drawable.third); urlString.add("drawable://" + R.drawable.four); urlString.add("drawable://" + R.drawable.five); urlString.add("drawable://" + R.drawable.six); viewPagerBarnner1.addImageUrls(urlString); viewPagerBarnner1.setViewPagerClick(new com.lcwang.androidviews.first.ViewPagerBarnner.ViewPagerClick() { @Override public void viewPagerOnClick(View view) { Toast.makeText(MainActivity.this, "click:" + view.getTag().toString(), Toast.LENGTH_SHORT).show(); } }); } }
这样就算完成了,看下效果图:
后期想撸一ViewPager的库,所以暂时不放出来源码了。
github源码
更多相关文章
- Android加壳(加固)原理以及实现
- 教你快速高效接入SDK——iOS多渠道自动打包工具核心原理
- Android中apk加固完善篇之内存加载dex方案实现原理(不落地方式加
- Android Handler消息队列的实现原理
- Android——AIDL基础实现demo以及原理探究
- Android实训案例(一)——计算器的运算逻辑