android自定义控件之滚动广告条

在一些电子商务网站上经常能够看到一些滚动的广告条,许多软件在首次使用时也有类似的广告条,如图:

android自定义控件之滚动广告条_第1张图片

其实在github上有实现这种效果的控件,不过这东西做起来也是很简单,我们今天就来看看该怎么做。

先来看看布局文件:

?
1
2
3
4
class = "hljs xml" > "match_parent" android:layout_width= "match_parent" tools:context= "com.example.customwidget2.MainActivity" xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http://schemas.android.com/tools" >
 
 

布局文件最上边是一个Viewpager,使用viewpager来实现图片的滚动效果,viewpager下边是一个linearlayout,这个布局文件中有两个东西,一个是textview,这是用来显示下边那一行字的,还有一个linearlayout,这是用来显示字下边的小点,小点的个数我们要根据图片的数量动态添加,所以现在先空着。

MainActivity.java

?
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
147
148
149
150
151
152
153
154
155
156
157
158
159
class = "hljs java" > public class MainActivity extends Activity {
 
     private ViewPager mViewPager;
     // 图片都存放在这里
     private List imageViewlist;
     private ImageView iv;
     private TextView imgDes;
     // 线程开关,当activity销毁后,线程也应该停止运行
     private boolean isStop = false ;
     private int previousPoint = 0 ;
     // 存放小点的布局文件
     private LinearLayout layoutPGroup;
     private String[] imageDescription = { "淮左名都,竹西佳处,解鞍少驻初程。" , "过春风十里。尽荠麦青青。" ,
             "自胡马窥江去后,废池乔木,犹厌言兵。" , "渐黄昏,清角吹寒。都在空城。" , "杜郎俊赏,算而今、重到须惊。" };
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         // 初始化
         init();
         //设置图片自动滚动
         new Thread( new Runnable() {
 
             @Override
             public void run() {
                 //如果activity未销毁则一直执行
                 while (!isStop) {
                     //先休息5秒钟
                     SystemClock.sleep( 5000 );
                     //以下代码发送到主线程中执行
                     runOnUiThread( new Runnable() {
 
                         @Override
                         public void run() {
                             mViewPager.setCurrentItem(mViewPager
                                     .getCurrentItem() + 1 );
                         }
                     });
                 }
             }
         }).start();
     }
 
     private void init() {
         mViewPager = (ViewPager) this .findViewById(R.id.viewpager);
         layoutPGroup = (LinearLayout) this .findViewById(R.id.show_pointer);
         imgDes = (TextView) this .findViewById(R.id.image_description);
         imageViewlist = new ArrayList();
 
         // 先拿到图片id
         int [] ivIDs = new int [] { R.drawable.a, R.drawable.b, R.drawable.c,
                 R.drawable.d, R.drawable.e };
         // 遍历图片id
         for ( int id : ivIDs) {
             // 构造新的图片对象,并根据id给图片设置背景
             iv = new ImageView( this );
             iv.setBackgroundResource(id);
             // 所有的图片存放在imageViewlist中
             imageViewlist.add(iv);
 
             // 构造小点
             View v = new View( this );
             // 设置小点的宽和高
             LayoutParams params = new LayoutParams( 8 , 8 );
             // 设置小点的左边距
             params.leftMargin = 12 ;
             v.setLayoutParams(params);
             // 设置小点是否可用,默认都不可用,当不可用时,小点是透明的,否则是白色的
             v.setEnabled( false );
             // 设置小点的背景,这个背景是使用xml文件画的一个小圆点
             v.setBackgroundResource(R.drawable.pointer_selector);
             // 把小点添加到它的布局文件中
             layoutPGroup.addView(v);
         }
         // 计算应用打开时显示的第一项 Integer.MAX_VALUE /2 - 3=0
         int index = Integer.MAX_VALUE / 2 - 3 ;
         // 给mViewPager设置数据
         mViewPager.setAdapter( new MyPagerAdapter());
         // 给mViewPager设置页面滑动事件
         mViewPager.setOnPageChangeListener( new MyOnPageChangeListener());
 
         // 设置应用打开时显示的第一项,index的值为0
         // 使用这种方式得到的0,和直接写0有什么区别呢?
         // 直接写0,应用打开后不能直接向右滑动,因为viewpager中存image位置不能为负值,只能先向左滑动
         // 这种方式得到的0,可以实现应用一打开,就可以向右滑动
         mViewPager.setCurrentItem(index);
     }
 
     private class MyOnPageChangeListener implements OnPageChangeListener {
 
         // 开始
         @Override
         public void onPageScrollStateChanged( int arg0) {
         }
 
         // 正在进行时
         @Override
         public void onPageScrolled( int arg0, float arg1, int arg2) {
         }
 
         // 结束
         @Override
         public void onPageSelected( int position) {
             // 当页面滑动结束时,先对页面位置取模
             position = position % imageViewlist.size();
             // 设置textview的文本内容
             imgDes.setText(imageDescription[position]);
             // 将上一个点的可用性设置为false
             layoutPGroup.getChildAt(previousPoint).setEnabled( false );
             // 把当前点的可用性设置为true
             layoutPGroup.getChildAt(position).setEnabled( true );
             // 把当前位置值赋值给previousPoint
             previousPoint = position;
         }
     }
 
     private class MyPagerAdapter extends PagerAdapter {
 
         /**
          * 返回图片总数,Integer.MAX_VALUE的值为 2147483647这个数有21亿,也就是说我们的viewpager
          * 理论上在每次使用应用的时候可以滑动21亿次,当然,实际上是没人要去这么做的,我们这样做是为了实现实现viewpager循环滑动的效果
          * 即当滑动到viewpager的最后一页时,继续滑动就可以回到第一页
          *
          */
         @Override
         public int getCount() {
             return Integer.MAX_VALUE;
         }
 
         @Override
         public boolean isViewFromObject(View arg0, Object arg1) {
             return arg0 == arg1;
         }
 
         // 当某一页滑出去的时候,将其销毁
         @Override
         public void destroyItem(ViewGroup container, int position, Object object) {
             container.removeView(imageViewlist.get(position
                     % imageViewlist.size()));
         }
 
         // 向容器中添加图片,由于我们要实现循环滑动的效果,所以要对position取模
         @Override
         public Object instantiateItem(ViewGroup container, int position) {
             container
                     .addView(imageViewlist.get(position % imageViewlist.size()));
             return imageViewlist.get(position % imageViewlist.size());
         }
     }
 
     // 当activity销毁时,让线程停止
     @Override
     protected void onDestroy() {
         isStop = true ;
         super .onDestroy();
     }
 
}

代码中的注释已经说的很详细了,我就不再赘述了。


你可能感兴趣的:(android自定义控件之滚动广告条)