为了学习Scroller类,自己写了个自定义侧滑的demo,但是效果还是有点问题,主要是会滑出边界的问题。原来都是直接用别人的开源的项目来做效果,现在想自己也弄得玩。虽然达不到很好的效果。
package com.example.learnscroller;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.LinearLayout;
import android.widget.Scroller;
public class MyScrollView extends LinearLayout {
private static final String TAG = "MyScrollerView";
private View mPerLayout;//主界面view
private View mSliderLayout;//侧边栏view
private int screenWidth; //屏幕宽度
private int screenHeight;//屏幕高度
private float scale = 0.5f;//侧边栏占比例
private Scroller scroller;
private int startX;//记录开始X位置
public static final int SNAP_VELOCITY = 200;//默认开始滑动像素点
private VelocityTracker velocityTracker;
private int mMaxVelocity;
private int verlocity;
private boolean isOpen = false;
public MyScrollView(Context context) {
this(context, null);
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed,l,t,r, b);
mSliderLayout.layout((int) -(screenWidth*scale+100), 0, 0, screenHeight);
mPerLayout.layout(0, 0, screenWidth, screenHeight);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
screenWidth = MeasureSpec.getSize(widthMeasureSpec);
screenHeight = MeasureSpec.getSize(heightMeasureSpec);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int currentX = 0;
addVelocityTracker(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
verlocity = getScrollXVelocity();
currentX = (int) event.getX();
Log.i(TAG, "getScrollX():"+getScrollX());
if(Math.abs(verlocity)> SNAP_VELOCITY){
if(getScrollX()>0||-getScrollX()>scale * screenWidth){
return true;
}
scrollBy(-(currentX - startX), 0);
}
startX = currentX;
break;
case MotionEvent.ACTION_UP:
verlocity = getScrollXVelocity();
currentX = (int) event.getX();
if(isOpen){
if(-verlocity > 500 ||-getScrollX() <= scale * screenWidth/3 ){
toLeftMove();
}else{
toRightMove();
}
}else{
if(verlocity > 500 ||-getScrollX()>= 2 * scale * screenWidth/3){
toRightMove();
}else{
toLeftMove();
}
}
startX = 0;
removeVelocityTracker();
break;
}
return true;
}
private void toLeftMove(){
scroller.startScroll(getScrollX(), 0, -getScrollX(), 0);
postInvalidate();
isOpen = false;
}
private void toRightMove() {
scroller.startScroll(getScrollX(), 0, -getScrollX()-(int)(screenWidth*scale), 0);
postInvalidate();
isOpen = true;
}
@Override
public void computeScroll() {
super.computeScroll();
if(scroller.computeScrollOffset()){
scrollTo(scroller.getCurrX(), scroller.getCurrY());
postInvalidate();
}
}
public void setPerLayout(View perLayout) {
mPerLayout = perLayout;
addView(mPerLayout);
}
public void setSliderLayout(View sliderLayout) {
mSliderLayout = sliderLayout;
addView(mSliderLayout);
}
public void setScale(float scale) {
this.scale = scale;
}
private void initView(Context context){
scroller = new Scroller(context);
ViewConfiguration.get(context);
mMaxVelocity = ViewConfiguration.getMaximumFlingVelocity();
}
private void addVelocityTracker(MotionEvent event){
if(velocityTracker == null){
velocityTracker = VelocityTracker.obtain();
}
velocityTracker.addMovement(event);
}
private void removeVelocityTracker(){
velocityTracker.recycle();
}
private int getScrollXVelocity(){
velocityTracker.computeCurrentVelocity(1000,mMaxVelocity);
int velocity = (int) velocityTracker.getXVelocity();
return velocity;
}
}