码迷,mamicode.com
首页 > 其他好文 > 详细

开源项目:滑动广告栏

时间:2015-01-30 19:04:42      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

  最近在开发一款android APP,项目中采用了推送广告的方案,即在手机屏幕上方空出一块区域,加载来自服务器的广告图片,形成banner广告的效果。

  开发过程中,百度出了好多种解决方案,其中以ViewPager的方案和重写Gallery的方案居多,学生党的我比较倾向于后者。在编写定制Gallery的过程中参考了ZAKER 5.0.4源代码中的ScrollGallery类(反编译得到的),优化了Gallery向两边滑动到头自动跳转的问题,详细的代码如下:  

 1 package org.warnier.zhang.support.v1.widget;
 2 
 3 import java.util.Timer;
 4 
 5 import android.content.Context;
 6 import android.util.AttributeSet;
 7 import android.view.MotionEvent;
 8 import android.widget.Gallery;
 9 
10 public class AdsGallery extends Gallery {
11 
12     public Context context;
13 
14     public AdsGallery(Context context) {
15         super(context);
16         this.context = context;
17     }
18 
19     public AdsGallery(Context context, AttributeSet attrs) {
20         super(context, attrs);
21         this.context = context;
22     }
23 
24     public AdsGallery(Context context, AttributeSet attrs, int defStyleAttr) {
25         super(context, attrs, defStyleAttr);
26         this.context = context;
27     }
28 
29     public AdsGallery(Context context, AttributeSet attrs, int defStyleAttr,
30             int defStyleRes) {
31         super(context, attrs, defStyleAttr, defStyleRes);
32         this.context = context;
33     }
34 
35     @Override
36     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
37             float velocityY) {
38         if (isScrollingLeft(e1, e2)) {
39             playPrevious();
40         }
41         for (;;) {
42             playNext();
43             return true;
44         }
45     }
46 
47     private boolean isScrollingLeft(MotionEvent paramMotionEvent1,
48             MotionEvent paramMotionEvent2) {
49         return paramMotionEvent2.getX() > paramMotionEvent1.getX();
50     }
51 
52     public boolean playNext() {
53         int i = getSelectedItemPosition();
54         int j = computeHorizontalScrollRange();
55         if ((j > 0) && (i < j - 1)) {
56             onKeyDown(22, null);
57             return true;
58         }
59         return false;
60     }
61 
62     public boolean playPrevious() {
63         int i = getSelectedItemPosition();
64         if ((computeHorizontalScrollRange() > 0) && (i > 0)) {
65             onKeyDown(21, null);
66             return true;
67         }
68         return false;
69     }
70 }

  滑动广告栏核心类有AdsGallery 和 AdsAdapter,核心类只是优化了滑动体验效果。在org.warnier.zhang.sample包的Demo中,AdsAdapter直接加载了本地的图片,在实际的APP中需要打开新的网络线程从服务器上读取图片资源。滑动广告栏具体功能的实现在org.warnier.zhang.sample包的MainActivity中。在MainActivity的onCreate()方法中初始化AdsGallery ,显示当前广告获得焦点的布局,和计时器;利用Timer和Handler之间进行线程间通信,在Handler中更新AdsGallery当前项。详细的代码如下:

 1 package org.warnier.zhang.sample;
 2 
 3 import java.util.Timer;
 4 import java.util.TimerTask;
 5 
 6 import org.warnier.zhang.support.v1.widget.AdsAdapter;
 7 import org.warnier.zhang.support.v1.widget.AdsGallery;
 8 
 9 import android.util.Log;
10 import android.view.View;
11 import android.widget.ImageView;
12 import android.widget.LinearLayout;
13 import android.app.Activity;
14 import android.graphics.Color;
15 import android.os.Bundle;
16 import android.os.Handler;
17 import android.os.Message;
18 
19 public class MainActivity extends Activity {
20 
21     private AdsGallery adsGallery;
22     private LinearLayout linearLayout;
23     private int delay = 2500;
24     private int period = 2500;
25 
26     @Override
27     protected void onCreate(Bundle savedInstanceState) {
28         super.onCreate(savedInstanceState);
29         setContentView(R.layout.activity_main);
30         // 初始化广告栏控件;
31         adsGallery = (AdsGallery) this.findViewById(R.id.myAdsGallery);
32         adsGallery.setAdapter(new AdsAdapter(this));
33 
34         // 初始化广告焦点指示器;
35         linearLayout = (LinearLayout) this.findViewById(R.id.myAdsIndicator);
36         linearLayout.setBackgroundColor(Color.argb(200, 135, 135, 152));
37         for (int i = 0; i < 4; i++) {
38             ImageView imageView = new ImageView(this);
39             if (i == 0) {
40                 imageView.setBackgroundResource(R.drawable.feature_point_cur);
41             } else
42                 imageView.setBackgroundResource(R.drawable.feature_point);
43             linearLayout.addView(imageView);
44         }
45 
46         // 初始化计时器和计时器任务;
47         new Timer().schedule(new TimerTask() {
48 
49             @Override
50             public void run() {
51                 int position = adsGallery.getSelectedItemPosition() + 1;
52 
53                 // 存放广告栏的当前项;
54                 Bundle bundle = new Bundle();
55                 bundle.putInt("position", position);
56                 Message msg = new Message();
57 
58                 // 设置当前的消息标识符;
59                 msg.what = 1;
60                 msg.setData(bundle);
61                 handler.sendMessage(msg);
62             }
63         }, delay, period);
64     }
65 
66     // 初始化Handler,供UI主线程与计时器线程交换数据;
67     private Handler handler = new Handler() {
68         @Override
69         public void handleMessage(android.os.Message msg) {
70             super.handleMessage(msg);
71             switch (msg.what) {
72             case 1:
73                 Bundle bundle = msg.getData();
74                 int position = bundle.getInt("position");
75                 Log.i("指示器", "" + position);
76                 adsGallery.setSelection(position);
77                 refreshIndicator(position);
78                 break;
79 
80             default:
81                 Log.i("msg.what", "消息标识符错误!");
82                 break;
83             }
84         };
85     };
86 
87     // 刷新广告栏焦点
88     public void refreshIndicator(int position) {
89         LinearLayout layout = (LinearLayout) findViewById(R.id.myAdsIndicator);
90         View v = layout.getChildAt(position % 4);
91         View p = layout.getChildAt((position - 1) % 4);
92         ((ImageView) p).setImageResource(R.drawable.feature_point);
93         ((ImageView) v).setImageResource(R.drawable.feature_point_cur);
94     }
95 }

  当然项目中还存在如下问题,欢迎读者交流指正!

  (1)广告焦点指示器的第一个圆形图标出现一圈红色背景;

  (2)当手动滑动广告栏的过程中,计时器继续运行,广告焦点指示器不止一个出现红色;

  (3)能否定制一个能够自动运行的AdsGallery,而不是在Activity中控制运行;

  上述问题已经在开发的过程中得到解决,但还是期待读者能够拿出新颖的方案,交流一下!展示和分享的代码是早期的原型Demo,不是项目的实际代码,大家如果采用的话需要根据自己的实际情况加以更改。完整的Eclipse工程下载访问链接: http://pan.baidu.com/s/1dDH7nSd 密码: ah8p。

  参考文献:

    [1] Android开发权威指南,李宁著,2013-09,北京,人民邮电出版社。  

  本文历史:

  • 2015-01-30  初稿完成。

开源项目:滑动广告栏

标签:

原文地址:http://www.cnblogs.com/warnier-zhang/p/4262773.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!