这两天有朋友在询问滚动广告怎么实现,然后我对项目中的滚动功能代码进行研究,因为之前向前辈讨论过这种无限滚动的原理。
1.设置一个伪无限的list,将当前图标显示在中间然后进行无线滚动。
2.在头部和尾部加上图标,也就是说在最后一个后面加上第一个对象,在第一个之前加上之前的最后的一个对象,当滑到加上去的对象的时候就强制设置成第一个或者最后一个对象。
自己写了一个小demo,然后代码贴一下吧。
public class MainActivity extends Activity implements ViewPager.OnPageChangeListener{ private List<ImageView> mViewList; private PageAdapter mAdapter; private CustomViewPager pageView; private LinearLayout _llPoints; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_header); pageView= (CustomViewPager)findViewById(R.id.vp_main_list_head); _llPoints = (LinearLayout) findViewById(R.id.ll_main_head_points); //数据展示 mViewList=new ArrayList<ImageView>(); int[] image=new int[]{R.drawable.android_guide_step_4,R.drawable.android_guide_step_1,R.drawable.android_guide_step_2,R.drawable.android_guide_step_3,R.drawable.android_guide_step_4,R.drawable.android_guide_step_1}; for(int i=0;i<image.length;i++){ ImageView imageView=new ImageView(this); imageView.setBackgroundResource(image[i]); mViewList.add(imageView); } mAdapter=new PageAdapter(mViewList,this); pageView.setAdapter(mAdapter); pageView.addOnPageChangeListener(this); Log.e("-------", mViewList.size() + ""); setPoints(true); } private void setPoints(boolean isNew) { if (isNew){ _llPoints.removeAllViews(); } if (_llPoints.getChildCount() == 0) { LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(Util.dp2px(this,5), Util.dp2px(this,5)); for (int i = 0; i < mViewList.size() - 2; i++) {//添加viewpager下方的点 params.leftMargin = Util.dp2px(this,5); ImageView imageView = new ImageView(this); if (mViewList.size() - 3 == i) { imageView.setImageResource(R.drawable.point_selected); } else { imageView.setImageResource(R.drawable.point); } _llPoints.addView(imageView, params); } } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { for (int i = 0; i < _llPoints.getChildCount(); i++) { ImageView imageView = (ImageView) _llPoints.getChildAt(i); imageView.setImageResource(R.drawable.point); } if (mViewList.size() != 0 && _llPoints.getChildCount() != 0) { int index = 0; index = pageView.getCurrentItem() % (mViewList.size() - 2) - 1; Log.e("----",""+pageView.getCurrentItem()); if (index < 0) { index = mViewList.size() - 3; } ImageView imageView = (ImageView) _llPoints.getChildAt(index); if (imageView != null) { imageView.setImageResource(R.drawable.point_selected); } } } @Override public void onPageScrollStateChanged(int state) { if (state == ViewPager.SCROLL_STATE_IDLE && pageView.getCurrentItem() == mViewList.size() - 1) { pageView.setCurrentItem(1, false); } else if (state == ViewPager.SCROLL_STATE_IDLE && pageView.getCurrentItem() == 0) { pageView.setCurrentItem(mViewList.size()-2, false); } } }
界面UI布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:id="@+id/rl_main_list_head" android:layout_width="match_parent" android:layout_height="240dp"> <com.example.administrator.textpagescoll.CustomViewPager android:id="@+id/vp_main_list_head" android:layout_width="match_parent" android:layout_height="match_parent"/> <LinearLayout android:id="@+id/ll_main_head_points" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:orientation="horizontal" android:layout_marginBottom="10dp"/> </RelativeLayout> </LinearLayout>其他的一些代码。
public class CustomViewPager extends android.support.v4.view.ViewPager { public boolean _isScrolling; private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>(); private static final float SCALE_MAX = 0.5f; private final int ANIMATION_DURATION = 2000 + 1200; private Context _context; private Runnable _runnable; private Click _click; private boolean viewpagersroll = false; private float xDown;// 记录手指按下时的横坐标。 private float xMove;// 记录手指移动时的横坐标。 private float yDown;// 记录手指按下时的纵坐标。 private float yMove;// 记录手指移动时的纵坐标。 public CustomViewPager(Context context) { super(context); _context = context; init(); } public CustomViewPager(Context context, AttributeSet attrs) { super(context, attrs); _context = context; init(); } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { int i = getCurrentItem() + 1; // SwitchLogger.e("tag", "自动翻页: " + i ); CustomViewPagerScroller viewPagerScroller = new CustomViewPagerScroller(_context, new CustomViewPagerInterpolator()); viewPagerScroller.initViewPagerScroll(CustomViewPager.this, 1200); setCurrentItem(i, true); handler.postDelayed(_runnable, ANIMATION_DURATION); } }; public void setObjectForPosition(View view, int position) { mChildrenViews.put(position, view); } private void init() { _runnable = new Runnable() { @Override public void run() { handler.obtainMessage().sendToTarget(); } }; handler.postDelayed(_runnable, ANIMATION_DURATION); } @Override public boolean onTouchEvent(MotionEvent ev) { Message msg; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: handler.removeCallbacksAndMessages(null); if(!_isScrolling){ CustomViewPagerScroller viewPagerScroller = new CustomViewPagerScroller(_context, new CustomViewPagerInterpolator()); viewPagerScroller.initViewPagerScroll(CustomViewPager.this, 250); } break; case MotionEvent.ACTION_UP: handler.removeCallbacksAndMessages(null); handler.postDelayed(_runnable, ANIMATION_DURATION); break; case MotionEvent.ACTION_MOVE: handler.removeCallbacksAndMessages(null); break; case MotionEvent.ACTION_CANCEL: handler.removeCallbacksAndMessages(null); handler.postDelayed(_runnable, ANIMATION_DURATION); break; default: break; } return super.onTouchEvent(ev); } public interface Click { void onClick(int position); } public void setClick(Click click) { this._click = click; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: break; } return true; } @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { // 记录按下时的位置 xDown = ev.getRawX(); yDown = ev.getRawY(); } else if (ev.getAction() == MotionEvent.ACTION_MOVE) { xMove = ev.getRawX(); yMove = ev.getRawY(); if (viewpagersroll) { // viewpager自己处理滑动效果 getParent().requestDisallowInterceptTouchEvent(true); return super.dispatchTouchEvent(ev); } // 这里的动作判断是Viewpager滑动,ListView不滑动 if (Math.abs(yMove - yDown) < 20 && Math.abs(xMove - xDown) > 20) { viewpagersroll = true; } else { // 由父容器listview来处理滑动效果 return false; } } else if (ev.getAction() == MotionEvent.ACTION_UP) { viewpagersroll = false; } return super.dispatchTouchEvent(ev); } }
public static int dp2px(Context context, float dpValue) { if (context == null){ return 0; } final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); }
public class PageAdapter extends PagerAdapter { private Context mContext; private List<ImageView> mList; public PageAdapter(List<ImageView> list,Context context){ this.mList=list; this.mContext=context; } @Override public Object instantiateItem(ViewGroup container,int position) { //这个方法用来实例化页卡 container.addView(mList.get(position)); return mList.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View)object); } @Override public int getCount() { if (mList != null) { return mList.size(); } else { return 0; } } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } }
public class CustomViewPagerScroller extends Scroller { private int mScrollDuration = 1200; public CustomViewPagerScroller(Context context) { super(context); } public CustomViewPagerScroller(Context context, Interpolator interpolator) { super(context, interpolator); } @Override public void startScroll(int startX, int startY, int dx, int dy, int duration) { super.startScroll(startX, startY, dx, dy, mScrollDuration); } @Override public void startScroll(int startX, int startY, int dx, int dy) { super.startScroll(startX, startY, dx, dy, mScrollDuration); } public void initViewPagerScroll(android.support.v4.view.ViewPager viewPager,int duration) { try { mScrollDuration = duration; Field mScroller = ViewPager.class.getDeclaredField("mScroller"); mScroller.setAccessible(true); mScroller.set(viewPager, this); } catch(Exception e) { e.printStackTrace(); } } }
public class CustomViewPagerInterpolator extends AccelerateDecelerateInterpolator { @Override public float getInterpolation(float input) { float first = (float) (0.6/Math.atan(0.4)); float second = (float) (0.4/Math.atan(0.6)); float secondFinal = first*(5.0f/3.0f-input*5.0f/3.0f)+(input-0.4f)*5.0f/3.0f*second; float scroll = (float) (input<0.4?Math.atan(input-0.4)*first+0.6:(Math.atan(input-0.4)*secondFinal+0.6)); return scroll>1?1:scroll; } }
一些代码是借鉴前辈写好的,然后自己读懂了,就在这里用上了。