首先,爲了不滑動衝突,咱們要繼承ViewFlow,重寫onInterceptTouchEventandroid
1 public class MyViewFlow extends ViewFlow { 2 private ViewPager mPager; 3 4 public MyViewFlow(Context context, AttributeSet attrs) { 5 super(context, attrs); 6 } 7 8 9 public void setViewPager(ViewPager viewPager) { 10 mPager = viewPager; 11 } 12 13 @Override 14 public boolean onInterceptTouchEvent(MotionEvent ev) { 15 if (mPager != null) 16 switch (ev.getAction()) { 17 case MotionEvent.ACTION_DOWN: 18 mPager.requestDisallowInterceptTouchEvent(true); 19 break; 20 case MotionEvent.ACTION_UP: 21 mPager.requestDisallowInterceptTouchEvent(false); 22 break; 23 case MotionEvent.ACTION_CANCEL: 24 mPager.requestDisallowInterceptTouchEvent(false); 25 break; 26 case MotionEvent.ACTION_MOVE: 27 mPager.requestDisallowInterceptTouchEvent(true); 28 break; 29 } 30 return super.onInterceptTouchEvent(ev); 31 } 32 }
調用setViewPager指定viewPager後,滑動便再也不衝突ide
接下來,咱們實現無限循環滾動oop
1 public class AdapterBanner extends BaseAdapter { 2 3 private LayoutInflater mInflater; 4 private static final int[] ids = { R.drawable.banner, R.drawable.banner, R.drawable.banner, R.drawable.banner}; 5 6 public AdapterBanner(Context context) { 7 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 8 } 9 10 @Override 11 public int getCount() { 12 //return ids.length; 13 return Integer.MAX_VALUE;//返回很大的值使得getView中的position不斷增大來實現循環 14 } 15 16 @Override 17 public Object getItem(int position) { 18 return position; 19 } 20 21 @Override 22 public long getItemId(int position) { 23 return position; 24 } 25 26 @Override 27 public View getView(int position, View convertView, ViewGroup parent) { 28 if (convertView == null) { 29 convertView = mInflater.inflate(R.layout.item_fr_acmain_nearby_banner, null); 30 } 31 convertView.findViewById(R.id.imgView).setBackgroundResource(ids[position%ids.length]); 32 return convertView; 33 } 34 35 }
關鍵代碼在第13行和31行的紅色部分。不過這樣實現以後,和CircleFlowIndicator結合使用,會發現程序ANR(無響應),緣由是CircleFlowIndicator會調用ViewFlow.getViewCount()來繪製圓點,顯然這個數是Integer.MAX_VALUE,圓點數太多了致使ANR,咱們須要繼續擴展MyViewFlow的getViewCount()。以下。spa
1 private int mCount; 2 public void setCount(int count){ 3 mCount=count; 4 } 5 @Override 6 public int getViewsCount() { 7 return mCount; 8 }
須要調用MyViewFlow.setCount(int count)指定真實的數目,這樣作了以後,發現程序不會ANR了。CircleFlowIndicator繪製的圓點數目也正常。可是會發現,不管怎麼滑動,圓點狀態都不變化,分析ViewFlow的源碼,發現要重寫一下onScrollChanged,咱們繼續擴展MyViewFlow,代碼以下。code
1 private int mLastIndex; 2 @Override 3 public void setAdapter(Adapter adapter, int initialPosition){ 4 super.setAdapter(adapter,initialPosition); 5 mLastIndex = initialPosition; 6 } 7 8 @Override 9 protected void onScrollChanged(int h, int v, int oldh, int oldv) { 10 //super.onScrollChanged(h, v, oldh, oldv); 11 if (mIndicator != null) { 12 /* 13 * The actual horizontal scroll origin does typically not match the 14 * perceived one. Therefore, we need to calculate the perceived 15 * horizontal scroll origin here, since we use a view buffer. 16 */ 17 int hPerceived = h + (mCurrentAdapterIndex%mCount - mCurrentBufferIndex) 18 * getChildWidth(); 19 20 if(mLastIndex%mCount==mCount-1 && mCurrentAdapterIndex>mLastIndex) { 21 oldh=0; 22 hPerceived = 0; 23 } 24 if(mLastIndex%mCount==0&&mCurrentAdapterIndex<mLastIndex) 25 hPerceived=h+(mCount-1-mCurrentBufferIndex)*getChildWidth(); 26 27 LogUtil.e(Config.MYTAG,"mCurrentAdapterIndex="+mCurrentAdapterIndex); 28 LogUtil.e(Config.MYTAG,"mLastIndex="+mLastIndex); 29 LogUtil.e(Config.MYTAG, "hPerceived=" + hPerceived); 30 31 mIndicator.onScrolled(hPerceived, v, oldh, oldv); 32 33 mLastIndex=mCurrentAdapterIndex; 34 } 35 }
固然,有幾個變量mIndicator,mCurrentAdapterIndex,mCurrentBufferIndex是沿用父類ViewFlow的,若是找不到,須要將父類ViewFlow中這些變量改成public便可(雖然從oop角度,這種作法很髒,但很省事,大半夜碼文字很累,我很懶)。blog
至此,大功告成!繼承
總體MyViewFlow代碼以下:get
package common.control.viewflow; import android.content.Context; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.Adapter; import com.xxx.android.main.Config; import common.util.LogUtil; public class MyViewFlow extends ViewFlow { private ViewPager mPager; public MyViewFlow(Context context, AttributeSet attrs) { super(context, attrs); } public void setViewPager(ViewPager viewPager) { mPager = viewPager; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (mPager != null) switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mPager.requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_UP: mPager.requestDisallowInterceptTouchEvent(false); break; case MotionEvent.ACTION_CANCEL: mPager.requestDisallowInterceptTouchEvent(false); break; case MotionEvent.ACTION_MOVE: mPager.requestDisallowInterceptTouchEvent(true); break; } return super.onInterceptTouchEvent(ev); } private int mCount; public void setCount(int count){ mCount=count; } @Override public int getViewsCount() { return mCount; } private int mLastIndex; @Override public void setAdapter(Adapter adapter, int initialPosition){ super.setAdapter(adapter,initialPosition); mLastIndex = initialPosition; } @Override protected void onScrollChanged(int h, int v, int oldh, int oldv) { //super.onScrollChanged(h, v, oldh, oldv); if (mIndicator != null) { /* * The actual horizontal scroll origin does typically not match the * perceived one. Therefore, we need to calculate the perceived * horizontal scroll origin here, since we use a view buffer. */ int hPerceived = h + (mCurrentAdapterIndex%mCount - mCurrentBufferIndex) * getChildWidth(); if(mLastIndex%mCount==mCount-1 && mCurrentAdapterIndex>mLastIndex) { oldh=0; hPerceived = 0; } if(mLastIndex%mCount==0&&mCurrentAdapterIndex<mLastIndex) hPerceived=h+(mCount-1-mCurrentBufferIndex)*getChildWidth(); LogUtil.e(Config.MYTAG,"mCurrentAdapterIndex="+mCurrentAdapterIndex); LogUtil.e(Config.MYTAG,"mLastIndex="+mLastIndex); LogUtil.e(Config.MYTAG, "hPerceived=" + hPerceived); mIndicator.onScrolled(hPerceived, v, oldh, oldv); mLastIndex=mCurrentAdapterIndex; } } }
自動播放就不用講了,網上不少。同窗們若是有收穫,記得回贊。源碼