android 轮播图

布局文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
< 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" >
 
     < android.support.v4.view.ViewPager
         android:id = "@+id/viewpager"
         android:layout_width = "match_parent"
         android:layout_height = "150dp" />
 
     < LinearLayout
         android:layout_width = "match_parent"
         android:layout_height = "wrap_content"
         android:layout_alignBottom = "@id/viewpager"
         android:background = "#33000000"
         android:orientation = "vertical"
         android:padding = "5dp" >
 
         < TextView
             android:id = "@+id/tv_bannertext"
             android:layout_width = "wrap_content"
             android:layout_height = "wrap_content"
             android:layout_gravity = "center_horizontal"
             android:padding = "5dp"
             android:text = "我是第一个广告语"
             android:textColor = "@android:color/white" />
 
         < LinearLayout
             android:id = "@+id/points"
             android:layout_width = "match_parent"
             android:layout_height = "wrap_content"
             android:gravity = "center_horizontal"
             android:orientation = "horizontal" >
         </ LinearLayout >
     </ LinearLayout >
 
</ RelativeLayout >

然后是小圆圈的样式,这里有2个xml,一个是选择状态,一个是空白状态


小圆圈正常状态

1
2
3
4
5
6
7
8
9
<? xml version = "1.0" encoding = "utf-8" ?>
< shape xmlns:android = "http://schemas.android.com/apk/res/android"
     android:shape = "oval" >
 
     < corners android:radius = "0.5dp" />
 
     < solid android:color = "#55000000" />
 
</ shape >



小圆圈选中状态

1
2
3
4
5
6
7
8
9
<? xml version = "1.0" encoding = "utf-8" ?>
< shape xmlns:android = "http://schemas.android.com/apk/res/android"
     android:shape = "oval" >
 
     < corners android:radius = "0.5dp" />
 
     < solid android:color = "#AAFFFFFF" />
 
</ shape >


小圆圈背景效果

 

1
2
3
4
5
6
7
<? xml version = "1.0" encoding = "utf-8" ?>
< selector xmlns:android = "http://schemas.android.com/apk/res/android" >
 
     < item android:drawable = "@drawable/point_bg_enable" android:state_enabled = "true" ></ item >
     < item android:drawable = "@drawable/point_bg_normal" android:state_enabled = "false" ></ item >
 
</ selector >


2、ViewPager适配器

既然我们使用到了VierPager,那么必须要给它设置一个适配器来装载我们所要展示的广告图,这里需要注意的是getCount()这个方法,正常情况下,我们让它返回的是数据源的长度大小,但这里我们需要实现"无限循环"的效果,这么我们可以返回一个比较大的是比如:Integer.MAX_VALUE,这个数值可是20亿,用户再怎么滑到也不会滑到上亿次级别的吧。然后避免出现空指针异常,我们在下面addView和removeView的时候就不能再直接使用position去索引资源了,我们应该取余item的总数量,这样索引位置就不会超过资源数据的数量,例如1%777=1,1%999=1。

对于ViewPager不熟悉的朋友可以看下我之前写过的一篇文章《安卓开发笔记——ViewPager组件(仿微信引导界面)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.lcw.rabbit.banner;
 
import java.util.List;
 
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
/**
  * ViewPager适配器
  * @author Rabbit_Lee
  *
  */
public class BannerAdapter extends PagerAdapter {
 
     //数据源
     private List<ImageView> mList;
 
     public BannerAdapter(List<ImageView> list) {
         this .mList = list;
     }
 
     @Override
     public int getCount() {
         //取超大的数,实现无线循环效果
         return Integer.MAX_VALUE;
     }
 
     @Override
     public boolean isViewFromObject(View arg0, Object arg1) {
         return arg0 == arg1;
     }
 
     @Override
     public Object instantiateItem(ViewGroup container, int position) {
         container.addView(mList. get (position%mList.size()));
         return mList. get (position%mList.size());
     }
 
     @Override
     public void destroyItem(ViewGroup container, int position, Object object ) {
         container.removeView(mList. get (position%mList.size()));
     }
 
}


3、主代码

首先先说下小圆圈点的实现,这里有2种方式,一种是直接在广告图上"画死",这种方法耗时耗力而且维护起来很不灵活,所以我们使用第二种方式动态生成,根据广告图的资源长度在给定的LinearLayout里去添加圆圈点View。然后我们需要给它一个pointIndex标志位,用它来记录当前所在的页面位置,初始为0,再每次滑动的时候根据这个标志位来切换小圆圈的状态。

 

再来说下我们最开始的页面位置,我们不可以设置为0(第一页),如果我们设置为0,那么便不能向左滑动了。由于我们在适配器的getCount返回了Integer.MAX_VALUE ,我们可以取它的中间点来作为起始点,用setCurrentItem来出发VierPager的监听器里的onPageSelected的方法,那么左右就都可以滑动了。

 

最后就是定时器SystemClock了,我们这里开辟了一条新的线程通过while永true来达到这个效果,让其每隔2秒执行一次设置当前页面的动作,每次只需要简单设置页面+1即可,最后要留意的是我们需要给这个定时器设定一个开关,在我们切换退出该页面的时候要停止掉定时器的操作,也就是去重写我们的onDestroy方法,这里把开关关掉即可。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package com.lcw.rabbit.banner;
 
import java.util.ArrayList;
import java.util.List;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
 
public class MainActivity extends Activity {
 
     // 声明控件
     private ViewPager mViewPager;
     private List<ImageView> mlist;
     private TextView mTextView;
     private LinearLayout mLinearLayout;
 
     // 广告图素材
     private int [] bannerImages = { R.drawable.image1, R.drawable.image2, R.drawable.image3, R.drawable.image4 };
     // 广告语
     private String[] bannerTexts = { "因为专业 所以卓越" , "坚持创新 行业领跑" , "诚信 专业 双赢" , "精细 和谐 大气 开放" };
 
     // ViewPager适配器与监听器
     private BannerAdapter mAdapter;
     private BannerListener bannerListener;
 
     // 圆圈标志位
     private int pointIndex = 0;
     // 线程标志
     private boolean isStop = false ;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         initView();
         initData();
         initAction();
 
         // 开启新线程,2秒一次更新Banner
         new Thread( new Runnable() {
 
             @Override
             public void run() {
                 while (!isStop) {
                     SystemClock.sleep(2000);
                     runOnUiThread( new Runnable() {
 
                         @Override
                         public void run() {
                             mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
                         }
                     });
                 }
             }
         }).start();
     }
 
     /**
      * 初始化事件
      */
     private void initAction() {
         bannerListener = new BannerListener();
         mViewPager.setOnPageChangeListener(bannerListener);
         //取中间数来作为起始位置
         int index = (Integer.MAX_VALUE / 2) - (Integer.MAX_VALUE / 2 % mlist.size());
         //用来出发监听器
         mViewPager.setCurrentItem(index);
         mLinearLayout.getChildAt(pointIndex).setEnabled( true );
     }
 
     /**
      * 初始化数据
      */
     private void initData() {
         mlist = new ArrayList<ImageView>();
         View view;
         LayoutParams params ;
         for ( int i = 0; i < bannerImages.length; i++) {
             // 设置广告图
             ImageView imageView = new ImageView(MainActivity. this );
             imageView.setLayoutParams( new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
             imageView.setBackgroundResource(bannerImages[i]);
             mlist.add(imageView);
             // 设置圆圈点
             view = new View(MainActivity. this );
             params = new LayoutParams(5, 5);
             params .leftMargin = 10;
             view.setBackgroundResource(R.drawable.point_background);
             view.setLayoutParams( params );
             view.setEnabled( false );
 
             mLinearLayout.addView(view);
         }
         mAdapter = new BannerAdapter(mlist);
         mViewPager.setAdapter(mAdapter);
     }
 
     /**
      * 初始化View操作
      */
     private void initView() {
         mViewPager = (ViewPager) findViewById(R.id.viewpager);
         mTextView = (TextView) findViewById(R.id.tv_bannertext);
         mLinearLayout = (LinearLayout) findViewById(R.id.points);
     }
 
     //实现VierPager监听器接口
     class BannerListener implements OnPageChangeListener {
 
         @Override
         public void onPageScrollStateChanged( int arg0) {
         }
 
         @Override
         public void onPageScrolled( int arg0, float arg1, int arg2) {
         }
 
         @Override
         public void onPageSelected( int position) {
             int newPosition = position % bannerImages.length;
             mTextView.setText(bannerTexts[newPosition]);
             mLinearLayout.getChildAt(newPosition).setEnabled( true );
             mLinearLayout.getChildAt(pointIndex).setEnabled( false );
             // 更新标志位
             pointIndex = newPosition;
 
         }
 
     }
 
     @Override
     protected void onDestroy() {
         // 关闭定时器
         isStop = true ;
         super.onDestroy();
     }
 
}


好了,到这里代码就结束了,很简单的一个小Demo,这里只是起到抛砖引玉的作用,在我们真正的应用这种广告图不可能直接存放在我们的资源文件里面的,肯定是通过网络去获取的,然后这里就要涉及到了图片的缓存等知识点,关于图片的缓存策略可以看下我之前写过的一篇博文:《安卓开发笔记——关于图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)》。

如果大家有更好的实现方法或者有什么疑问的地方,可以在文章评论给我留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值