在android中横向滚动可能经常会用到用户体验也不错,最近整理了一下相关资料如下:
方案一:通过继承FrameLayout,或linearlayout布局重写onInterceptTouchEvent(MotionEvent event),onTouchEvent(MotionEvent event)方法实现
效果图:
主要代码:
package com.scroll.frame; import android.content.Context; import android.graphics.PointF; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.widget.FrameLayout; import android.widget.Scroller; public class MyScrollView extends FrameLayout { private Scroller scroller; private PointF last = new PointF(); private final int TOUCH_SLOP = ViewConfiguration.get(getContext()).getScaledTouchSlop(); public MyScrollView(Context context) { super(context); scroller = new Scroller(context); } public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent event) { final int x = (int) event.getX(); boolean flag = false; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: last.x = x; break; case MotionEvent.ACTION_MOVE: final int deltaX = (int) (last.x - x); if (Math.abs(deltaX) > TOUCH_SLOP) { flag = true; } break; case MotionEvent.ACTION_UP: break; } return flag; } @Override public boolean onTouchEvent(MotionEvent event) { final int x = (int) event.getX(); final int width = getWidth(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (!scroller.isFinished()) { scroller.abortAnimation(); } break; case MotionEvent.ACTION_MOVE: final int deltaX = (int) (last.x - x); if (Math.abs(deltaX) < TOUCH_SLOP) { break; } last.x = x; if (deltaX < 0) { if (getScrollX() > 0) { scrollBy(Math.max(-getScrollX(), deltaX), 0); } } else if (deltaX > 0) { final int availableToScroll = getChildAt(getChildCount() - 1) .getRight() - getScrollX() - getWidth(); if (availableToScroll > 0) { scrollBy(Math.min(availableToScroll, deltaX), 0); } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: int dx = (getScrollX() + width / 2) / width; if (dx < 0) { dx = 0; } if (dx > getChildCount() - 1) { dx = getChildCount() - 1; } dx *= width; dx -= getScrollX(); scroller.startScroll(getScrollX(), 0, dx, 0, Math.abs(dx) * 3); break; } invalidate(); return true; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int width = getWidth(); final int count = getChildCount(); int height = getHeight(); int childLeft = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); child.layout(childLeft, 0, childLeft + width, height); childLeft += width; } } @Override public void computeScroll() { if (scroller.computeScrollOffset()) { scrollTo(scroller.getCurrX(), scroller.getCurrY()); invalidate(); } } }
package com.scroll.frame; import android.app.Activity; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; public class FlowScreenActivity extends Activity { private MyScrollView container; private View v1,v2,v3; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.main); getView(); } void getView(){ LayoutInflater inflater = LayoutInflater.from(this); container = new MyScrollView(this); // container.setVerticalScrollBarEnabled(false); // container.setHorizontalScrollBarEnabled(false); setContentView(container); v1 = inflater.inflate(R.layout.main, null); v2 = inflater.inflate(R.layout.second, null); v3 = inflater.inflate(R.layout.third, null); FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(-1, -1); container.addView(v1, new FrameLayout.LayoutParams(lp)); container.addView(v2, new FrameLayout.LayoutParams(lp)); container.addView(v3, new FrameLayout.LayoutParams(lp)); } }
布局就不给代码了随便弄几个布局就可以了。