In Android, horizontal scrolling may often result in a good user experience. Recently, I have sorted out the relevant information as follows:
Solution 1: override onintercepttouchevent (motionevent event) and ontouchevent (motionevent) by inheriting framelayout or linearlayout layout.
:
Main Code:
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);}@Overridepublic 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;}@Overridepublic 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;}@Overrideprotected 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;}}@Overridepublic 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)); } }
Layout does not give the code any layout.