在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));
}
}布局就不给代码了随便弄几个布局就可以了。