开源项目:滑动广告栏

版权所有,禁止匿名转载;禁止商业使用。

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

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

 package org.warnier.zhang.support.v1.widget;                                                                                                                                                                                                                    
 import java.util.Timer;                                                                                                                                                                                                                                         
 import android.content.Context;                                                                                                                                                                                                                                 
 import android.util.AttributeSet;                                                                                                                                                                                                                               
 import android.view.MotionEvent;                                                                                                                                                                                                                                
 import android.widget.Gallery;                                                                                                                                                                                                                                  
 public class AdsGallery extends Gallery {                                                                                                                                                                                                                       
     public Context context;                                                                                                                                                                                                                                     
     public AdsGallery(Context context) {                                                                                                                                                                                                                        
         super(context);                                                                                                                                                                                                                                         
         this.context = context;                                                                                                                                                                                                                                 
     }                                                                                                                                                                                                                                                           
     public AdsGallery(Context context, AttributeSet attrs) {                                                                                                                                                                                                    
         super(context, attrs);                                                                                                                                                                                                                                  
         this.context = context;                                                                                                                                                                                                                                 
     }                                                                                                                                                                                                                                                           
     public AdsGallery(Context context, AttributeSet attrs, int defStyleAttr) {                                                                                                                                                                                  
         super(context, attrs, defStyleAttr);                                                                                                                                                                                                                    
         this.context = context;                                                                                                                                                                                                                                 
     }                                                                                                                                                                                                                                                           
     public AdsGallery(Context context, AttributeSet attrs, int defStyleAttr,                                                                                                                                                                                    
             int defStyleRes) {                                                                                                                                                                                                                                  
         super(context, attrs, defStyleAttr, defStyleRes);                                                                                                                                                                                                       
         this.context = context;                                                                                                                                                                                                                                 
     }                                                                                                                                                                                                                                                           
     @Override                                                                                                                                                                                                                                                   
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,                                                                                                                                                                                     
             float velocityY) {                                                                                                                                                                                                                                  
         if (isScrollingLeft(e1, e2)) {                                                                                                                                                                                                                          
             playPrevious();                                                                                                                                                                                                                                     
         }                                                                                                                                                                                                                                                       
         for (;;) {                                                                                                                                                                                                                                              
             playNext();                                                                                                                                                                                                                                         
             return true;                                                                                                                                                                                                                                        
         }                                                                                                                                                                                                                                                       
     }                                                                                                                                                                                                                                                           
     private boolean isScrollingLeft(MotionEvent paramMotionEvent1,                                                                                                                                                                                              
             MotionEvent paramMotionEvent2) {                                                                                                                                                                                                                    
         return paramMotionEvent2.getX() > paramMotionEvent1.getX();                                                                                                                                                                                             
     }                                                                                                                                                                                                                                                           
     public boolean playNext() {                                                                                                                                                                                                                                 
         int i = getSelectedItemPosition();                                                                                                                                                                                                                      
         int j = computeHorizontalScrollRange();                                                                                                                                                                                                                 
         if ((j > 0) && (i < j - 1)) {                                                                                                                                                                                                                           
             onKeyDown(22, null);                                                                                                                                                                                                                                
             return true;                                                                                                                                                                                                                                        
         }                                                                                                                                                                                                                                                       
         return false;                                                                                                                                                                                                                                           
     }                                                                                                                                                                                                                                                           
     public boolean playPrevious() {                                                                                                                                                                                                                             
         int i = getSelectedItemPosition();                                                                                                                                                                                                                      
         if ((computeHorizontalScrollRange() > 0) && (i > 0)) {                                                                                                                                                                                                  
             onKeyDown(21, null);                                                                                                                                                                                                                                
             return true;                                                                                                                                                                                                                                        
         }                                                                                                                                                                                                                                                       
         return false;                                                                                                                                                                                                                                           
     }                                                                                                                                                                                                                                                           
 }

                                                                                

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

package org.warnier.zhang.sample;                                                                                                                                                                                                                               
 import java.util.Timer;                                                                                                                                                                                                                                         
 import java.util.TimerTask;                                                                                                                                                                                                                                     
 import org.warnier.zhang.support.v1.widget.AdsAdapter;                                                                                                                                                                                                          
 import org.warnier.zhang.support.v1.widget.AdsGallery;                                                                                                                                                                                                          
 import android.util.Log;                                                                                                                                                                                                                                        
 import android.view.View;                                                                                                                                                                                                                                       
 import android.widget.ImageView;                                                                                                                                                                                                                                
 import android.widget.LinearLayout;                                                                                                                                                                                                                             
 import android.app.Activity;                                                                                                                                                                                                                                    
 import android.graphics.Color;                                                                                                                                                                                                                                  
 import android.os.Bundle;                                                                                                                                                                                                                                       
 import android.os.Handler;                                                                                                                                                                                                                                      
 import android.os.Message;                                                                                                                                                                                                                                      
 public class MainActivity extends Activity {                                                                                                                                                                                                                    
     private AdsGallery adsGallery;                                                                                                                                                                                                                              
     private LinearLayout linearLayout;                                                                                                                                                                                                                          
     private int delay = 2500;                                                                                                                                                                                                                                   
     private int period = 2500;                                                                                                                                                                                                                                  
     @Override                                                                                                                                                                                                                                                   
     protected void onCreate(Bundle savedInstanceState) {                                                                                                                                                                                                        
         super.onCreate(savedInstanceState);                                                                                                                                                                                                                     
         setContentView(R.layout.activity_main);                                                                                                                                                                                                                 
         // 初始化广告栏控件;                                                                                                                                                                                                                                   
         adsGallery = (AdsGallery) this.findViewById(R.id.myAdsGallery);                                                                                                                                                                                         
         adsGallery.setAdapter(new AdsAdapter(this));                                                                                                                                                                                                            
         // 初始化广告焦点指示器;                                                                                                                                                                                                                               
         linearLayout = (LinearLayout) this.findViewById(R.id.myAdsIndicator);                                                                                                                                                                                   
         linearLayout.setBackgroundColor(Color.argb(200, 135, 135, 152));                                                                                                                                                                                        
         for (int i = 0; i < 4; i++) {                                                                                                                                                                                                                           
             ImageView imageView = new ImageView(this);                                                                                                                                                                                                          
             if (i == 0) {                                                                                                                                                                                                                                       
                 imageView.setBackgroundResource(R.drawable.feature_point_cur);                                                                                                                                                                                  
             } else                                                                                                                                                                                                                                              
                 imageView.setBackgroundResource(R.drawable.feature_point);                                                                                                                                                                                      
             linearLayout.addView(imageView);                                                                                                                                                                                                                    
         }                                                                                                                                                                                                                                                       
         // 初始化计时器和计时器任务;                                                                                                                                                                                                                           
         new Timer().schedule(new TimerTask() {                                                                                                                                                                                                                  
             @Override                                                                                                                                                                                                                                           
             public void run() {                                                                                                                                                                                                                                 
                 int position = adsGallery.getSelectedItemPosition() + 1;                                                                                                                                                                                        
                 // 存放广告栏的当前项;                                                                                                                                                                                                                         
                 Bundle bundle = new Bundle();                                                                                                                                                                                                                   
                 bundle.putInt("position", position);                                                                                                                                                                                                            
                 Message msg = new Message();                                                                                                                                                                                                                    
                 // 设置当前的消息标识符;                                                                                                                                                                                                                       
                 msg.what = 1;                                                                                                                                                                                                                                   
                 msg.setData(bundle);                                                                                                                                                                                                                            
                 handler.sendMessage(msg);                                                                                                                                                                                                                       
             }                                                                                                                                                                                                                                                   
         }, delay, period);                                                                                                                                                                                                                                      
     }                                                                                                                                                                                                                                                           
     // 初始化Handler,供UI主线程与计时器线程交换数据;                                                                                                                                                                                                          
     private Handler handler = new Handler() {                                                                                                                                                                                                                   
         @Override                                                                                                                                                                                                                                               
         public void handleMessage(android.os.Message msg) {                                                                                                                                                                                                     
             super.handleMessage(msg);                                                                                                                                                                                                                           
             switch (msg.what) {                                                                                                                                                                                                                                 
             case 1:                                                                                                                                                                                                                                             
                 Bundle bundle = msg.getData();                                                                                                                                                                                                                  
                 int position = bundle.getInt("position");                                                                                                                                                                                                       
                 Log.i("指示器", "" + position);                                                                                                                                                                                                                 
                 adsGallery.setSelection(position);                                                                                                                                                                                                              
                 refreshIndicator(position);                                                                                                                                                                                                                     
                 break;                                                                                                                                                                                                                                          
             default:                                                                                                                                                                                                                                            
                 Log.i("msg.what", "消息标识符错误!");                                                                                                                                                                                                          
                 break;                                                                                                                                                                                                                                          
             }                                                                                                                                                                                                                                                   
         };                                                                                                                                                                                                                                                      
     };                                                                                                                                                                                                                                                          
     // 刷新广告栏焦点                                                                                                                                                                                                                                           
     public void refreshIndicator(int position) {                                                                                                                                                                                                                
         LinearLayout layout = (LinearLayout) findViewById(R.id.myAdsIndicator);                                                                                                                                                                                 
         View v = layout.getChildAt(position % 4);                                                                                                                                                                                                               
         View p = layout.getChildAt((position - 1) % 4);                                                                                                                                                                                                         
         ((ImageView) p).setImageResource(R.drawable.feature_point);                                                                                                                                                                                             
         ((ImageView) v).setImageResource(R.drawable.feature_point_cur);                                                                                                                                                                                         
     }                                                                                                                                                                                                                                                           
 }

                                                                                                                                                      

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

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

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

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

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

0 0