Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题

自制页面效果图 :

 

\

 

.

 

一. ViewPager适配页面问题

 

1. ViewPager出现的问题

 

ViewPager占满全屏问题 : ViewPager在XML中定义了android:layout_height 和 android:layout_width 之后, 不论这两个属性的值是 fill_parent 还是 wrap_content, 都会出现ViewPager占满全屏的问题;

 

不使用固定值定义宽高: 为了使ViewPager能适配各种类型的手机, 如果给ViewPager定义了高度和宽度, 与各种手机的界面兼容性肯定要大大的降低, 因此出现了下面的解决方案;

 

2. 解决方案

 

代码中添加组件 : 不在XML界面定义该组件, 可以在布局文件中,定义一个LinearLayout容器, 然后在代码中动态添加ViewPager;

好处 : 这样的好处是可以在代码中获取屏幕的宽高, 我们可以根据比例设定ViewPager的大小, 这样就解决了屏幕适配的问题;

 

3. 代码实现

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//从布局文件中获取ViewPager父容器
pagerLayout = (LinearLayout) findViewById(R.id.view_pager_content);
//创建ViewPager
adViewPager = new ViewPager( this );
 
//获取屏幕像素相关信息
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
 
//根据屏幕信息设置ViewPager广告容器的宽高
adViewPager.setLayoutParams( new LayoutParams(dm.widthPixels, dm.heightPixels * 2 / 5 ));
 
//将ViewPager容器设置到布局文件父容器中
pagerLayout.addView(adViewPager);


 

 

二. ViewPager广告栏基本解决方案

 

1. ViewPager适配器PagerAdapter

 

自定义PagerAdapter类 : 我们需要自定义一个类, 去继承PageAdapter, 至少实现下面四个方法 :

 

destroyItem(View container, int position, Object object) :

作用 :删除container中指定位置position的页面;

参数 : container 就是容器, 这里指的是ViewPager对象, position就是删除的页面索引;

 

int getCount() :

作用 :获取ViewPager页面的个数;

返回值 : ViewPager页面个数;

 

Object instantiateItem(View container, int position) :

作用 :在给定的位置创建页面, PageAdapter负责向指定的position位置添加View页面;

参数 : container容器就是ViewPager, position指的是ViewPager的索引;

返回值 : 返回代表新的一页的对象;

 

boolean isViewFromObject(View view, Object object) :

作用 :决定instantiateItem()方法返回的Object对象是不是需要显示的页面关联, 这个方法必须要有;

参数 : view 要关联的页面, object instantiateItem()方法返回的对象;

返回值 : 是否要关联显示页面与 instantiateItem()返回值;

 

为PageAdapter关联数据源 : 可以将一个数组或者集合与PageAdapter关联,集合的索引与ViewPager的索引对应, destroyItem()方法中删除集合中对应索引的元素对象, instantiateItem 添加对应索引的元素对象;

 

PageAdapter 代码示例 :

 

?
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
private final class AdvAdapter extends PagerAdapter { 
     private List<view> views = null
 
     /**
      * 初始化数据源, 即View数组
      */
     public AdvAdapter(List<view> views) { 
         this .views = views; 
    
     
     /**
      * 从ViewPager中删除集合中对应索引的View对象
      */
     @Override 
     public void destroyItem(View container, int position, Object object) { 
         ((ViewPager) container).removeView(views.get(position)); 
    
 
     /**
      * 获取ViewPager的个数
      */
     @Override 
     public int getCount() { 
         return views.size(); 
    
 
     /**
      * 从View集合中获取对应索引的元素, 并添加到ViewPager中
      */
     @Override 
     public Object instantiateItem(View container, int position) { 
         ((ViewPager) container).addView(views.get(position), 0 ); 
         return views.get(position); 
    
 
     /**
      * 是否将显示的ViewPager页面与instantiateItem返回的对象进行关联
      * 这个方法是必须实现的
      */
     @Override 
     public boolean isViewFromObject(View view, Object object) { 
         return view == object; 
    
}</view></view>

创建PageAdapter代码  :

 

 

 

?
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
private void initPageAdapter() {
     pageViews = new ArrayList<view>();
     
     ImageView img1 = new ImageView( this ); 
     img1.setBackgroundResource(R.drawable.view_add_1); 
     pageViews.add(img1); 
     
     ImageView img2 = new ImageView( this ); 
     img2.setBackgroundResource(R.drawable.view_add_2); 
     pageViews.add(img2);
     
     ImageView img3 = new ImageView( this ); 
     img3.setBackgroundResource(R.drawable.view_add_3); 
     pageViews.add(img3);
     
     ImageView img4 = new ImageView( this ); 
     img4.setBackgroundResource(R.drawable.view_add_4); 
     pageViews.add(img4);
     
     ImageView img5 = new ImageView( this ); 
     img5.setBackgroundResource(R.drawable.view_add_5); 
     pageViews.add(img5);
     
     ImageView img6 = new ImageView( this ); 
     img6.setBackgroundResource(R.drawable.view_add_6); 
     pageViews.add(img6); 
     
     adapter = new AdPageAdapter(pageViews);
}</view>

 

2. 小圆点导航策略

 

圆点存放策略 : 所有的小圆点都放在一个ViewGroup中, 有两种圆点, 一种是当前显示的, 一种是没激活的, 这里我们将一组圆点分别放入ImageView中, 并且将这些ImageView组装起来放到ViewGroup中即可;

 

圆点导航初始化 : 最初默认显示第一个页面, 第一个圆点激活, 根据ViewPager个数初始化圆点的个数, 组装圆点的时候, 第一个圆点状态激活;

代码如下 :

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void initCirclePoint(){
     ViewGroup group = (ViewGroup) findViewById(R.id.viewGroup);
     imageViews = new ImageView[pageViews.size()]; 
     //广告栏的小圆点图标
     for ( int i = 0 ; i < pageViews.size(); i++) { 
         //创建一个ImageView, 并设置宽高. 将该对象放入到数组中
         imageView = new ImageView( this ); 
         imageView.setLayoutParams( new LayoutParams( 20 , 20 )); 
         imageViews[i] = imageView; 
         
         //初始值, 默认第0个选中
         if (i == 0 ) { 
             imageViews[i] 
                     .setBackgroundResource(R.drawable.point_focused); 
         } else
             imageViews[i] 
                     .setBackgroundResource(R.drawable.point_unfocused); 
        
         //将小圆点放入到布局中
         group.addView(imageViews[i]); 
     }
}


 

ViewPager页面改变时圆点导航随之改变 : 获取ViewPager当前显示页面索引,重新组装ViewGroup中的圆点排列顺序, 这个方法在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
/**
  *  ViewPager 页面改变监听器
  */
private final class AdPageChangeListener implements OnPageChangeListener { 
     
     /**
      * 页面滚动状态发生改变的时候触发
      */
     @Override 
     public void onPageScrollStateChanged( int arg0) { 
    
 
     /**
      * 页面滚动的时候触发
      */
     @Override 
     public void onPageScrolled( int arg0, float arg1, int arg2) { 
    
 
     /**
      * 页面选中的时候触发
      */
     @Override 
     public void onPageSelected( int arg0) { 
         //获取当前显示的页面是哪个页面
         atomicInteger.getAndSet(arg0); 
         //重新设置原点布局集合
         for ( int i = 0 ; i < imageViews.length; i++) { 
             imageViews[arg0] 
                     .setBackgroundResource(R.drawable.point_focused); 
             if (arg0 != i) { 
                 imageViews[i] 
                         .setBackgroundResource(R.drawable.point_unfocused); 
            
        
    
}


 

3. 自动翻页导航策略

 

线程中处理自动翻页 : 启动一个线程, 获取当前页面显示索引, 计算出下一个显示位置, 显示下一个页面;

.

相关代码 :

线程代码 :

 

?
1
2
3
4
5
6
7
8
9
10
11
new Thread( new Runnable() { 
     @Override 
     public void run() { 
         while ( true ) { 
             if (isContinue) { 
                 viewHandler.sendEmptyMessage(atomicInteger.get()); 
                 atomicOption(); 
            
        
    
}).start();

handler代码 :

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private void atomicOption() { 
     atomicInteger.incrementAndGet(); 
     if (atomicInteger.get() > imageViews.length - 1 ) { 
         atomicInteger.getAndAdd(- 5 ); 
    
     try
         Thread.sleep( 3000 ); 
     } catch (InterruptedException e) { 
           
    
}
 
/*
  * 每隔固定时间切换广告栏图片
  */
private final Handler viewHandler = new Handler() { 
 
     @Override 
     public void handleMessage(Message msg) { 
         adViewPager.setCurrentItem(msg.what); 
         super .handleMessage(msg); 
    
 
};


 

三. 程序所有代码 和 资源文件

 

XML布局文件 :

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--?xml version= 1.0 encoding=utf- 8 ?-->
<linearlayout android:layout_height= "match_parent" android:layout_width= "match_parent" android:orientation= "vertical" xmlns:android= "http://schemas.android.com/apk/res/android" >
     
     <relativelayout android:layout_height= "fill_parent" android:layout_weight= "5" android:layout_width= "fill_parent" android:orientation= "vertical"
         
         <linearlayout android:id= "@+id/view_pager_content" android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:orientation= "vertical/" >
          
         <linearlayout android:gravity= "right" android:id= "@+id/viewGroup" android:layout_below= "@id/view_pager_content" android:layout_height= "wrap_content" android:layout_margintop= "-25px" android:layout_width= "fill_parent" android:orientation= "horizontal"
         </linearlayout> 
     </linearlayout></relativelayout>
     
     <linearlayout android:background= "#BBFFBB" android:layout_height= "fill_parent" android:layout_weight= "2" android:layout_width= "fill_parent" android:orientation= "vertical" >
     </linearlayout>
     
</linearlayout>


 

主Activity源码 :

 

?
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
package shuliang.han.myviewpager;
 
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
 
public class MainActivity extends Activity {
 
     private ViewPager adViewPager;
     private LinearLayout pagerLayout;
     private List<view> pageViews;
     private ImageView[] imageViews;
     private ImageView imageView; 
     private AdPageAdapter adapter;
     private AtomicInteger atomicInteger = new AtomicInteger( 0 ); 
     private boolean isContinue = true ;
     
     
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         
         initViewPager();
     }
 
     private void initViewPager() {
 
         //从布局文件中获取ViewPager父容器
         pagerLayout = (LinearLayout) findViewById(R.id.view_pager_content);
         //创建ViewPager
         adViewPager = new ViewPager( this );
         
         //获取屏幕像素相关信息
         DisplayMetrics dm = new DisplayMetrics();
         getWindowManager().getDefaultDisplay().getMetrics(dm);
         
         //根据屏幕信息设置ViewPager广告容器的宽高
         adViewPager.setLayoutParams( new LayoutParams(dm.widthPixels, dm.heightPixels * 2 / 5 ));
         
         //将ViewPager容器设置到布局文件父容器中
         pagerLayout.addView(adViewPager);
         
         initPageAdapter();
         
         initCirclePoint();
         
         adViewPager.setAdapter(adapter);
         adViewPager.setOnPageChangeListener( new AdPageChangeListener());
         
         new Thread( new Runnable() { 
             @Override 
             public void run() { 
                 while ( true ) { 
                     if (isContinue) { 
                         viewHandler.sendEmptyMessage(atomicInteger.get()); 
                         atomicOption(); 
                    
                
            
         }).start(); 
     }
     
     
     private void atomicOption() { 
         atomicInteger.incrementAndGet(); 
         if (atomicInteger.get() > imageViews.length - 1 ) { 
             atomicInteger.getAndAdd(- 5 ); 
        
         try
             Thread.sleep( 3000 ); 
         } catch (InterruptedException e) { 
               
        
     }
     
     /*
      * 每隔固定时间切换广告栏图片
      */
     private final Handler viewHandler = new Handler() { 
   
         @Override 
         public void handleMessage(Message msg) { 
             adViewPager.setCurrentItem(msg.what); 
             super .handleMessage(msg); 
        
   
     };
     
     private void initPageAdapter() {
         pageViews = new ArrayList<view>();
         
         ImageView img1 = new ImageView( this ); 
         img1.setBackgroundResource(R.drawable.view_add_1); 
         pageViews.add(img1); 
         
         ImageView img2 = new ImageView( this ); 
         img2.setBackgroundResource(R.drawable.view_add_2); 
         pageViews.add(img2);
         
         ImageView img3 = new ImageView( this ); 
         img3.setBackgroundResource(R.drawable.view_add_3); 
         pageViews.add(img3);
         
         ImageView img4 = new ImageView( this ); 
         img4.setBackgroundResource(R.drawable.view_add_4); 
         pageViews.add(img4);
         
         ImageView img5 = new ImageView( this ); 
         img5.setBackgroundResource(R.drawable.view_add_5); 
         pageViews.add(img5);
         
         ImageView img6 = new ImageView( this ); 
         img6.setBackgroundResource(R.drawable.view_add_6); 
         pageViews.add(img6); 
         
         adapter = new AdPageAdapter(pageViews);
     }
     
     private void initCirclePoint(){
         ViewGroup group = (ViewGroup) findViewById(R.id.viewGroup);
         imageViews = new ImageView[pageViews.size()]; 
         //广告栏的小圆点图标
         for ( int i = 0 ; i < pageViews.size(); i++) { 
             //创建一个ImageView, 并设置宽高. 将该对象放入到数组中
             imageView = new ImageView( this ); 
             imageView.setLayoutParams( new LayoutParams( 10 , 10 )); 
             imageViews[i] = imageView; 
             
             //初始值, 默认第0个选中
             if (i == 0 ) { 
                 imageViews[i] 
                         .setBackgroundResource(R.drawable.point_focused); 
             } else
                 imageViews[i] 
                         .setBackgroundResource(R.drawable.point_unfocused); 
            
             //将小圆点放入到布局中
             group.addView(imageViews[i]); 
         }
     }
     
     /**
      *  ViewPager 页面改变监听器
      */
     private final class AdPageChangeListener implements OnPageChangeListener { 
         
         /**
          * 页面滚动状态发生改变的时候触发
          */
         @Override 
         public void onPageScrollStateChanged( int arg0) { 
        
   
         /**
          * 页面滚动的时候触发
          */
         @Override 
         public void onPageScrolled( int arg0, float arg1, int arg2) { 
        
   
         /**
          * 页面选中的时候触发
          */
         @Override 
         public void onPageSelected( int arg0) { 
             //获取当前显示的页面是哪个页面
             atomicInteger.getAndSet(arg0); 
             //重新设置原点布局集合
             for ( int i = 0 ; i < imageViews.length; i++) { 
                 imageViews[arg0] 
                         .setBackgroundResource(R.drawable.point_focused); 
                 if (arg0 != i) { 
                     imageViews[i] 
                             .setBackgroundResource(R.drawable.point_unfocused); 
                
            
        
     }
     
     
     private final class AdPageAdapter extends PagerAdapter { 
         private List<view> views = null
   
         /**
          * 初始化数据源, 即View数组
          */
         public AdPageAdapter(List<view> views) { 
             this .views = views; 
        
         
         /**
          * 从ViewPager中删除集合中对应索引的View对象
          */
         @Override 
         public void destroyItem(View container, int position, Object object) { 
             ((ViewPager) container).removeView(views.get(position)); 
        
   
         /**
          * 获取ViewPager的个数
          */
         @Override 
         public int getCount() { 
             return views.size(); 
        
   
         /**
          * 从View集合中获取对应索引的元素, 并添加到ViewPager中
          */
         @Override 
         public Object instantiateItem(View container, int position) { 
             ((ViewPager) container).addView(views.get(position), 0 ); 
             return views.get(position); 
        
   
         /**
          * 是否将显示的ViewPager页面与instantiateItem返回的对象进行关联
          * 这个方法是必须实现的
          */
         @Override 
         public boolean isViewFromObject(View view, Object object) { 
             return view == object; 
        
     }
}
</view></view></view></view>


 

效果图 :

\

 

源码下载地址 : http://download.csdn.net/detail/han1202012/6835401

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值