Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View

  • 原文出处:http://www.it165.net/pro/html/201406/16227.html#

  • 最近开发中需要做一个类似京东首页那样的广告轮播效果,于是采用ViewPager自己自定义了一个轮播图效果的View。

    主要原理就是利用定时任务器定时切换ViewPager的页面。

    效果图如下:

    \

    \

    \

    主页面布局实现如下:

    01. <?xml version="1.0" encoding="utf-8"?>
    02.  
    03. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    04. android:layout_width="match_parent"
    05. android:layout_height="match_parent">
    06.  
    07. <android.support.v4.view.ViewPager
    08. android:id="@+id/viewPager"
    09. android:layout_width="match_parent"
    10. android:layout_height="match_parent" />
    11.  
    12. <LinearLayout
    13. android:layout_width="match_parent"
    14. android:layout_height="wrap_content"
    15. android:layout_alignParentBottom="true"
    16. android:padding="5dp"
    17. android:gravity="center"
    18. android:orientation="horizontal">
    19.  
    20. <View
    21. android:id="@+id/v_dot1"
    22. android:layout_width="8dp"
    23. android:layout_height="8dp"
    24. android:background="@drawable/dot_black" />
    25.  
    26. <View
    27. android:id="@+id/v_dot2"
    28. android:layout_width="8dp"
    29. android:layout_height="8dp"
    30. android:layout_marginLeft="5dp"
    31. android:background="@drawable/dot_white" />
    32.  
    33. <View
    34. android:id="@+id/v_dot3"
    35. android:layout_width="8dp"
    36. android:layout_height="8dp"
    37. android:layout_marginLeft="5dp"
    38. android:background="@drawable/dot_white" />
    39.  
    40. <View
    41. android:id="@+id/v_dot4"
    42. android:layout_width="8dp"
    43. android:layout_height="8dp"
    44. android:layout_marginLeft="5dp"
    45. android:background="@drawable/dot_white" />
    46.  
    47. <View
    48. android:id="@+id/v_dot5"
    49. android:layout_width="8dp"
    50. android:layout_height="8dp"
    51. android:layout_marginLeft="5dp"
    52. android:background="@drawable/dot_white" />
    53.  
    54. </LinearLayout>
    55. </RelativeLayout>

    轮播效果视图类代码实现如下:

    001. package com.czm.customview;
    002.  
    003. import java.util.ArrayList;
    004. import java.util.List;
    005. import java.util.concurrent.Executors;
    006. import java.util.concurrent.ScheduledExecutorService;
    007. import java.util.concurrent.TimeUnit;
    008.  
    009. import android.content.Context;
    010. import android.graphics.drawable.Drawable;
    011. import android.os.Handler;
    012. import android.os.Message;
    013. import android.os.Parcelable;
    014. import android.support.v4.view.PagerAdapter;
    015. import android.support.v4.view.ViewPager;
    016. import android.support.v4.view.ViewPager.OnPageChangeListener;
    017. import android.util.AttributeSet;
    018. import android.view.LayoutInflater;
    019. import android.view.View;
    020. import android.widget.FrameLayout;
    021. import android.widget.ImageView;
    022. import android.widget.ImageView.ScaleType;
    023.  
    024.  
    025. /**
    026. * ViewPager实现的轮播图广告自定义视图,如京东首页的广告轮播图效果;
    027. * 既支持自动轮播页面也支持手势滑动切换页面
    028. * @author caizhiming
    029. *
    030. */
    031.  
    032. public class SlideShowView extends FrameLayout {
    033.  
    034. //轮播图图片数量
    035. private final static int IMAGE_COUNT = 5;
    036. //自动轮播的时间间隔
    037. private final static int TIME_INTERVAL = 5;
    038. //自动轮播启用开关
    039. private final static boolean isAutoPlay = true;
    040.  
    041. //自定义轮播图的资源ID
    042. private int[] imagesResIds;
    043. //放轮播图片的ImageView 的list
    044. private List<ImageView> imageViewsList;
    045. //放圆点的View的list
    046. private List<View> dotViewsList;
    047.  
    048. private ViewPager viewPager;
    049. //当前轮播页
    050. private int currentItem  = 0;
    051. //定时任务
    052. private ScheduledExecutorService scheduledExecutorService;
    053. //Handler
    054. private Handler handler = new Handler(){
    055.  
    056. @Override
    057. public void handleMessage(Message msg) {
    058. // TODO Auto-generated method stub
    059. super.handleMessage(msg);
    060. viewPager.setCurrentItem(currentItem);
    061. }
    062.  
    063. };
    064.  
    065. public SlideShowView(Context context) {
    066. this(context,null);
    067. // TODO Auto-generated constructor stub
    068. }
    069. public SlideShowView(Context context, AttributeSet attrs) {
    070. this(context, attrs, 0);
    071. // TODO Auto-generated constructor stub
    072. }
    073. public SlideShowView(Context context, AttributeSet attrs, int defStyle) {
    074. super(context, attrs, defStyle);
    075. // TODO Auto-generated constructor stub
    076. initData();
    077. initUI(context);
    078. if(isAutoPlay){
    079. startPlay();
    080. }
    081.  
    082. }
    083. /**
    084. * 开始轮播图切换
    085. */
    086. private void startPlay(){
    087. scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
    088. scheduledExecutorService.scheduleAtFixedRate(new SlideShowTask(), 14, TimeUnit.SECONDS);
    089. }
    090. /**
    091. * 停止轮播图切换
    092. */
    093. private void stopPlay(){
    094. scheduledExecutorService.shutdown();
    095. }
    096. /**
    097. * 初始化相关Data
    098. */
    099. private void initData(){
    100. imagesResIds = new int[]{
    101. R.drawable.pic1,
    102. R.drawable.pic2,
    103. R.drawable.pic3,
    104. R.drawable.pic4,
    105. R.drawable.pic5,
    106.  
    107. };
    108. imageViewsList = new ArrayList<ImageView>();
    109. dotViewsList = new ArrayList<View>();
    110.  
    111. }
    112. /**
    113. * 初始化Views等UI
    114. */
    115. private void initUI(Context context){
    116. LayoutInflater.from(context).inflate(R.layout.layout_slideshow, thistrue);
    117. for(int imageID : imagesResIds){
    118. ImageView view =  new ImageView(context);
    119. view.setImageResource(imageID);
    120. view.setScaleType(ScaleType.FIT_XY);
    121. imageViewsList.add(view);
    122. }
    123. dotViewsList.add(findViewById(R.id.v_dot1));
    124. dotViewsList.add(findViewById(R.id.v_dot2));
    125. dotViewsList.add(findViewById(R.id.v_dot3));
    126. dotViewsList.add(findViewById(R.id.v_dot4));
    127. dotViewsList.add(findViewById(R.id.v_dot5));
    128.  
    129. viewPager = (ViewPager) findViewById(R.id.viewPager);
    130. viewPager.setFocusable(true);
    131.  
    132. viewPager.setAdapter(new MyPagerAdapter());
    133. viewPager.setOnPageChangeListener(new MyPageChangeListener());
    134. }
    135.  
    136. /**
    137. * 填充ViewPager的页面适配器
    138. * @author caizhiming
    139. */
    140. private class MyPagerAdapter  extends PagerAdapter{
    141.  
    142. @Override
    143. public void destroyItem(View container, int position, Object object) {
    144. // TODO Auto-generated method stub
    145. //((ViewPag.er)container).removeView((View)object);
    146. ((ViewPager)container).removeView(imageViewsList.get(position));
    147. }
    148.  
    149. @Override
    150. public Object instantiateItem(View container, int position) {
    151. // TODO Auto-generated method stub
    152. ((ViewPager)container).addView(imageViewsList.get(position));
    153. return imageViewsList.get(position);
    154. }
    155.  
    156. @Override
    157. public int getCount() {
    158. // TODO Auto-generated method stub
    159. return imageViewsList.size();
    160. }
    161.  
    162. @Override
    163. public boolean isViewFromObject(View arg0, Object arg1) {
    164. // TODO Auto-generated method stub
    165. return arg0 == arg1;
    166. }
    167. @Override
    168. public void restoreState(Parcelable arg0, ClassLoader arg1) {
    169. // TODO Auto-generated method stub
    170.  
    171. }
    172.  
    173. @Override
    174. public Parcelable saveState() {
    175. // TODO Auto-generated method stub
    176. return null;
    177. }
    178.  
    179. @Override
    180. public void startUpdate(View arg0) {
    181. // TODO Auto-generated method stub
    182.  
    183. }
    184.  
    185. @Override
    186. public void finishUpdate(View arg0) {
    187. // TODO Auto-generated method stub
    188.  
    189. }
    190.  
    191. }
    192. /**
    193. * ViewPager的监听器
    194. * 当ViewPager中页面的状态发生改变时调用
    195. * @author caizhiming
    196. */
    197. private class MyPageChangeListener implements OnPageChangeListener{
    198.  
    199. boolean isAutoPlay = false;
    200.  
    201. @Override
    202. public void onPageScrollStateChanged(int arg0) {
    203. // TODO Auto-generated method stub
    204. switch (arg0) {
    205. case 1:// 手势滑动,空闲中
    206. isAutoPlay = false;
    207. break;
    208. case 2:// 界面切换中
    209. isAutoPlay = true;
    210. break;
    211. case 0:// 滑动结束,即切换完毕或者加载完毕
    212. // 当前为最后一张,此时从右向左滑,则切换到第一张
    213. if (viewPager.getCurrentItem() == viewPager.getAdapter().getCount() - 1 && !isAutoPlay) {
    214. viewPager.setCurrentItem(0);
    215. }
    216. // 当前为第一张,此时从左向右滑,则切换到最后一张
    217. else if (viewPager.getCurrentItem() == 0 && !isAutoPlay) {
    218. viewPager.setCurrentItem(viewPager.getAdapter().getCount() - 1);
    219. }
    220. break;
    221. }
    222. }
    223.  
    224. @Override
    225. public void onPageScrolled(int arg0, float arg1, int arg2) {
    226. // TODO Auto-generated method stub
    227.  
    228. }
    229.  
    230. @Override
    231. public void onPageSelected(int pos) {
    232. // TODO Auto-generated method stub
    233.  
    234. currentItem = pos;
    235. for(int i=0;i < dotViewsList.size();i++){
    236. if(i == pos){
    237. ((View)dotViewsList.get(pos)).setBackgroundResource(R.drawable.dot_black);
    238. }else {
    239. ((View)dotViewsList.get(i)).setBackgroundResource(R.drawable.dot_white);
    240. }
    241. }
    242. }
    243.  
    244. }
    245.  
    246. /**
    247. *执行轮播图切换任务
    248. *@author caizhiming
    249. */
    250. private class SlideShowTask implements Runnable{
    251.  
    252. @Override
    253. public void run() {
    254. // TODO Auto-generated method stub
    255. synchronized (viewPager) {
    256. currentItem = (currentItem+1)%imageViewsList.size();
    257. handler.obtainMessage().sendToTarget();
    258. }
    259. }
    260.  
    261. }
    262. /**
    263. * 销毁ImageView资源,回收内存
    264. * @author caizhiming
    265. */
    266. private void destoryBitmaps() {
    267.  
    268. for (int i = 0; i < IMAGE_COUNT; i++) {
    269. ImageView imageView = imageViewsList.get(i);
    270. Drawable drawable = imageView.getDrawable();
    271. if (drawable != null) {
    272. //解除drawable对view的引用
    273. drawable.setCallback(null);
    274. }
    275. }
    276. }
    277.  
    278. }

    如何引用上面自定义的轮播图效果视图View呢?其实很引用普通的View类似,实现如下:

    1. <com.czm.customview.SlideShowView
    2. android:id="@+id/slideshowView"
    3. android:layout_width="335dp"
    4. android:layout_height="120dp"
    5. android:layout_centerHorizontal="true"
    6. />
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值