ViewFlipper实现带索引效果的自动播放也可手动滑动的广告栏

前几天看到淘宝和易迅的客户端的广告栏做的不错,今天就尝试了一下,模仿着写了带指引的ViewFlipper。本文主要介绍指引栏的实现,论坛上关于ViewFlipper的使用和介绍很多,就不过多介绍。

效果图如下:


首先是布局,稍有Android开发经验的人很容易看出来,这是一个Layout里面嵌套了ViewFliper和一个LinearLayout。布局如下:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <RelativeLayout   
  2.        android:id="@+id/food_recom_viewfliper_rl"  
  3.        android:layout_width="fill_parent"  
  4.        android:longClickable="true"  
  5.        android:layout_height="150dp">  
  6.     <com.mobsut.mm.widget.GestureViewFliper  
  7.         android:id="@+id/food_recom_viewfliper"  
  8.         android:layout_height="150dp"  
  9.         android:background="@color/white"  
  10.         android:layout_width="fill_parent"/>  
  11.     <LinearLayout  
  12.         android:id="@+id/food_recom_page_indicator"  
  13.         android:layout_width="fill_parent"  
  14.         android:layout_height="wrap_content"  
  15.         android:layout_alignParentBottom="true"  
  16.         android:gravity="center"  
  17.         android:orientation="horizontal"  
  18.         android:padding="@dimen/offset_2dp"></LinearLayout>  
  19.     </RelativeLayout >  


可以看到这个GestureViewFliper是我自定义的,继承于VIewFlipper,实现OnGestureListener接口用来识别用户手势,让用户可以手动滑动广告栏。在用GestureDetector 识别手势时,会出现一个问题:onFling函数不被触发,这时需要把onDown设置为true。

在用户滑动之前,需要注意:当用户将作出滑动手势时,需要停掉自动播放,然后用户结束滑动时,继续自动播放

然后是重点,要实现带索引的效果,首先需要得到ViewFlipper的当前展示的View的索引值,而这个View当自动播放时是实时变化的,但是ViewFlipper并没有提供一个接口,在可以监听自动播放时view的变化。所以,需要自定义一个回调接口,监听displayView的变化,并把相应的索引值传递出去。这样才可以实现索引效果。

自定义的ViewFlipper源码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.mobsut.mm.widget;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.view.GestureDetector;  
  6. import android.view.View;  
  7. import android.view.GestureDetector.OnGestureListener;  
  8. import android.view.MotionEvent;  
  9. import android.view.animation.AnimationUtils;  
  10. import android.widget.ViewFlipper;  
  11. /* 
  12.  * 自定义的ViewFliper,监听滑动手势,以及自动指引 
  13.  * @author jiakang 
  14.  */  
  15. import com.mobsut.mm.R;  
  16.   
  17. public class GestureViewFliper extends ViewFlipper implements OnGestureListener {  
  18.   
  19.     GestureDetector gestureDetector = null;  
  20.     private Context mContext = null;  
  21.     FlipperFacousChangedListener flipperFacousChangedListener=null;  
  22.   
  23.     public GestureViewFliper(Context mContext) {  
  24.         super(mContext);  
  25.   
  26.     }  
  27.   
  28.     public GestureViewFliper(Context mContext, AttributeSet attrs) {  
  29.         super(mContext, attrs);  
  30.         this.mContext = mContext;  
  31.         gestureDetector = new GestureDetector(mContext, this);  
  32.         setLongClickable(true);  
  33.         setOnTouchListener(new OnTouchListener() {  
  34.   
  35.             @Override  
  36.             public boolean onTouch(View v, MotionEvent event) {  
  37.                 // TODO Auto-generated method stub  
  38.                 return gestureDetector.onTouchEvent(event);  
  39.             }  
  40.         });  
  41.     }  
  42.   
  43.     @Override  
  44.     public void startFlipping() {  
  45.         // TODO Auto-generated method stub  
  46.         super.startFlipping();  
  47.         setInAnimation(AnimationUtils.loadAnimation(mContext,  
  48.                 R.anim.m_push_up_in));     
  49.         setOutAnimation(AnimationUtils.loadAnimation(mContext,  
  50.                 R.anim.m_push_up_out));  
  51.     }  
  52.   
  53.     @Override  
  54.     public boolean onTouchEvent(MotionEvent event) {  
  55.         // TODO Auto-generated method stub  
  56.         stopFlipping();       //用户点击屏幕时,停止滑动  
  57.         setAutoStart(false);   //取消自动滑动  
  58.         return this.gestureDetector.onTouchEvent(event);   //把touch事件交给gesture处理  
  59.     }  
  60.   
  61.     @Override  
  62.     public boolean onDown(MotionEvent e) {  
  63.         // TODO Auto-generated method stub  
  64.         <span style="color:#ff0000;">return true;</span> // 缺省值是false,在onTouchEvent后触发,如果为false,onFling将得不到down的事件即不触发  
  65.     }  
  66.   
  67.     /* 
  68.      * 重写了onFling,为了判断手势,让手势滑动 
  69.      *  
  70.      * @see android.view.GestureDetector.OnGestureListener#onFling(android.view. 
  71.      * MotionEvent, android.view.MotionEvent, float, float) 
  72.      */  
  73.   
  74.     @Override  
  75.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
  76.             float velocityY) {  
  77.         // TODO Auto-generated method stub  
  78.         if (e2.getX() - e1.getX() > 120) {    // 从左侧滑进  
  79.             setInAnimation(AnimationUtils.loadAnimation(mContext,  
  80.                     R.anim.m_push_up_in));     //设置进出动画  
  81.             setOutAnimation(AnimationUtils.loadAnimation(mContext,  
  82.                     R.anim.m_push_up_out));  
  83.             //用户手势滑动结束,再次开始自动播放  
  84.             showPrevious();  
  85.             setAutoStart(true);  
  86.             startFlipping();  
  87.   
  88.             return true;  
  89.         } else if (e2.getX() - e1.getX() < -120) {   //从右侧画出  
  90.             setOutAnimation(AnimationUtils.loadAnimation(mContext,  
  91.                     R.anim.m_push_up_out));         //设置进出动画  
  92.             setInAnimation(AnimationUtils.loadAnimation(mContext,  
  93.                     R.anim.m_push_up_in));            
  94.             //滑动结束,再次自动播放  
  95.             showNext();  
  96.             setAutoStart(true);  
  97.             startFlipping();  
  98.   
  99.             return true;  
  100.         }  
  101.         return false;  
  102.     }  
  103.       
  104.       
  105.   
  106.     @Override  
  107.     public void showNext() {  
  108.         // TODO Auto-generated method stub  
  109.         super.showNext();  
  110.         //监听向下向下翻页  
  111.         <span style="color:#ff0000;">flipperFacousChangedListener.onFliperChanged(getDisplayedChild());</span>  
  112.     }  
  113.   
  114.     @Override  
  115.     public void showPrevious() {  
  116.         // TODO Auto-generated method stub  
  117.         super.showPrevious();  
  118.         //监听向上翻页  
  119.         <span style="color:#ff0000;">flipperFacousChangedListener.onFliperChanged(getDisplayedChild());</span>  
  120.     }  
  121.   
  122.     @Override  
  123.     public void onLongPress(MotionEvent e) {  
  124.         // TODO Auto-generated method stub  
  125.   
  126.     }  
  127.   
  128.     @Override  
  129.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,  
  130.             float distanceY) {  
  131.         // TODO Auto-generated method stub  
  132.         return true;  
  133.     }  
  134.   
  135.     @Override  
  136.     public void onShowPress(MotionEvent e) {  
  137.         // TODO Auto-generated method stub  
  138.   
  139.     }  
  140.   
  141.     @Override  
  142.     public boolean onSingleTapUp(MotionEvent e) {  
  143.         // TODO Auto-generated method stub  
  144.         return false;  
  145.     }  
  146.     /* 
  147.      * 回调接口,用于监听viewflipper切花事件 
  148.      */  
  149.       
  150.     public interface FlipperFacousChangedListener{  
  151.         public void onFliperChanged(int index);  
  152.     }  
  153.       
  154.     public void setOnFacousChangedListener(FlipperFacousChangedListener flipperFacousChangedListener){  
  155.         this.flipperFacousChangedListener=flipperFacousChangedListener;  
  156.     }  
  157.   
  158. }  


接着是实现部分,指引条是由两张图片构成,选中项目一个颜色,未选中时一个颜色。实现比较简单,部分代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.mobsut.mm.foods;  
  2.   
  3. public class FoodRecomFragment extends Fragment {  
  4.   
  5.     private Context mContext=null;  
  6.     private LinearLayout mainLayout=null;  
  7.     private LinearLayout indicatorLayout=null;  
  8.     private ImageView[] mImageView;  
  9.       
  10.     private int[] fliperImage={R.drawable.fliper1,R.drawable.fliper2,R.drawable.fliper3};  
  11.     @Override  
  12.     public void onCreate(Bundle savedInstanceState) {  
  13.         // TODO Auto-generated method stub  
  14.         super.onCreate(savedInstanceState);  
  15.         mContext=getActivity();  
  16.     }  
  17.   
  18.     @Override  
  19.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  20.             Bundle savedInstanceState) {  
  21.         // TODO Auto-generated method stub  
  22.         mainLayout=(LinearLayout)inflater.inflate(R.layout.food_recom_fragment_main,container,false);  
  23.         indicatorLayout=(LinearLayout)mainLayout.findViewById(R.id.food_recom_page_indicator);  
  24.         GestureViewFliper viewFilper=(GestureViewFliper)mainLayout.findViewById(R.id.food_recom_viewfliper);  
  25.         mImageView=new ImageView[fliperImage.length];  
  26.         for(int i=0;i<fliperImage.length;i++){  
  27.               
  28.             ImageView iv=new ImageView(mContext);  
  29.             ImageView indicatorView=new ImageView(mContext);  
  30.             if(i==0){  
  31.                 indicatorView.setImageResource(R.drawable.page_selected);//初始默认选中第一张为当前指引  
  32.             }else{  
  33.                 indicatorView.setImageResource(R.drawable.page_normal);  
  34.             }  
  35.             iv.setImageResource(fliperImage[i]);  
  36.             //把指引条的图片添加到LinearLayout里面  
  37.             LinearLayout.LayoutParams lp=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);  
  38.             lp.setMargins(6000);  
  39.             indicatorView.setLayoutParams(lp);  
  40.             iv.setScaleType(ScaleType.FIT_XY);  
  41.             viewFilper.addView(iv, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));  
  42.             mImageView[i]=indicatorView;  
  43.             indicatorLayout.addView(mImageView[i]);  
  44.         }  
  45.         viewFilper.setAutoStart(true);    //让viewFlipper自动播放  
  46.         viewFilper.setFlipInterval(4000); //间隔为4S  
  47.         if(viewFilper.isAutoStart()&&viewFilper.isFlipping()){  
  48.             viewFilper.startFlipping();  
  49.         }  
  50.         if(viewFilper.getDisplayedChild()!=0){  
  51.             viewFilper.setInAnimation(AnimationUtils.loadAnimation(  
  52.                     mContext, R.anim.m_push_up_in));   //进出动画  
  53.             viewFilper.setOutAnimation(AnimationUtils.loadAnimation(  
  54.                     mContext, R.anim.m_push_up_out));  
  55.         }  
  56.         viewFilper.setOnFacousChangedListener(new FlipperFacousChangedListener() {  
  57.               
  58.             @Override  //实现监听接口  
  59.             public void onFliperChanged(int index) {  
  60.                 // TODO Auto-generated method stub  
  61.                 for(int i=0;i<mImageView.length;i++){  
  62.                     if(i==index){                     
  63.                     mImageView[i].setImageResource(R.drawable.page_selected);  
  64.                     }else{  
  65.                         mImageView[i].setImageResource(R.drawable.page_normal);  
  66.                     }  
  67.                       
  68.                 }  
  69.             }  
  70.         });  
  71.         return mainLayout;  
  72.     }  
  73. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值