package com.example.sjd.danmu; import android.content.Context; import android.graphics.Color; import android.support.v4.view.ViewConfigurationCompat; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.Scroller; /** * Created by sjd on 2017/2/15. */ public class ScrollerLayout extends ViewGroup { private static final String TAG = "ScrollerLayout"; Scroller mScroller; int touchSlop; private int vLeft; private int vRight; /** * 手机按下时的屏幕坐标 */ private float mXDown; /** * 手机当时所处的屏幕坐标 */ private float mXMove; /** * 上次触发ACTION_MOVE事件时的屏幕坐标 */ private float mXLastMove; private int dx; public ScrollerLayout(Context context, AttributeSet attrs) { super(context, attrs); mScroller=new Scroller(context); ViewConfiguration viewConfiguration=ViewConfiguration.get(context); touchSlop= viewConfiguration.getScaledPagingTouchSlop(); setBackgroundColor(Color.GREEN); } public ScrollerLayout(Context context) { super(context,null); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); for (int i = 0; i < getChildCount(); i++) { measureChild(getChildAt(i),widthMeasureSpec,heightMeasureSpec); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if(changed){ for (int i = 0; i < getChildCount(); i++) { View v= getChildAt(i); if(i==1){ v.layout(getWidth(), 0, (i + 2) * v.getMeasuredWidth(), v.getMeasuredHeight()); }else { v.layout(i * v.getMeasuredWidth(), 0, (i + 1) * v.getMeasuredWidth(), v.getMeasuredHeight()); } Log.i(TAG, "onLayout:"+ i*v.getMeasuredWidth() +" " + (i+1)*v.getMeasuredWidth() + " " + v.getMeasuredHeight() ); } vLeft=getChildAt(0).getLeft(); vRight=getChildAt(getChildCount()-1).getRight(); } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.i(TAG, "onInterceptTouchEvent:1 "); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mXDown = ev.getRawX(); mXLastMove = mXDown; break; case MotionEvent.ACTION_MOVE: mXMove = ev.getRawX(); float diff = Math.abs(mXMove - mXDown); mXLastMove = mXMove; // 当手指拖动值大于TouchSlop值时,认为应该进行滚动,拦截子控件的事件 if (diff > touchSlop) { return true; } break; } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { Log.i(TAG, "onTouchEvent: "); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: return true; case MotionEvent.ACTION_MOVE: mXMove = event.getRawX(); int scrolledX = (int) (mXLastMove - mXMove); if (getScrollX() + scrolledX < vLeft) { scrollTo(vLeft, 0); Log.i(TAG, "onTouchEvent1: "+vLeft); return true; } else if (getScrollX() + getWidth() + scrolledX > vRight) { scrollTo(vRight - getWidth(), 0); Log.i(TAG, "onTouchEvent2: "+(vRight - getWidth())); return true; } scrollBy(scrolledX, 0); Log.i(TAG, "onTouchEvent3: "+scrolledX); mXLastMove = mXMove; break; case MotionEvent.ACTION_UP: // 当手指抬起时,根据当前的滚动值来判定应该滚动到哪个子控件的界面 int targetIndex = (getScrollX() + getWidth() / 2) / getWidth(); dx = targetIndex * getWidth() - getScrollX(); // 第二步,调用startScroll()方法来初始化滚动数据并刷新界面 if(getScrollX()<660){ mScroller.startScroll(getScrollX(), 0, dx, 0); } else { mScroller.startScroll(getScrollX(), 0, 0, 0); } Log.i(TAG, "onTouchEvent4: "+getScrollX()+ " "+getWidth()); invalidate(); break; } return super.onTouchEvent(event); } void outSlide() { scrollTo(dx,0); mScroller.startScroll(dx,0,-dx,0); } @Override public void computeScroll() { // 第三步,重写computeScroll()方法,并在其内部完成平滑滚动的逻辑 if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); invalidate(); } }
}
<?xml version="1.0" encoding="utf-8"?> <com.example.sjd.danmu.ScrollerLayout android:id="@+id/sc" android:descendantFocusability="beforeDescendants" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:onClick="scroll" android:gravity="center" android:textSize="18sp" android:text="哈哈哈哈哈" android:layout_width="match_parent" android:layout_height="100dp" /> <LinearLayout android:orientation="horizontal" android:layout_width="200dp" android:layout_height="100dp"> <TextView android:onClick="scroll" android:layout_weight="1" android:gravity="center" android:text="删除" android:background="@color/colorAccent" android:layout_width="wrap_content" android:layout_height="100dp" /> <TextView android:onClick="scroll" android:layout_weight="1" android:gravity="center" android:text="置顶" android:background="@color/colorPrimaryDark" android:layout_width="wrap_content" android:layout_height="100dp" /> </LinearLayout> </com.example.sjd.danmu.ScrollerLayout>
public void scroll(View view) { scrollerLayout= (ScrollerLayout) findViewById(R.id.sc); Toast.makeText(this,((TextView)view).getText(),Toast.LENGTH_SHORT).show(); scrollerLayout.outSlide(); }