android报表控件,任意方向联动

来源:互联网 发布:炉石40包淘宝变贵了 编辑:程序博客网 时间:2024/06/05 04:44

任意方向滑动中间的那块View,上面和左边的滚动条将联动。还支持回弹效果。
这里写图片描述

先说说这个布局文件

这里写图片描述

总的思路是获取中间那个自定义View在x,y轴上滚动的偏移量,然后让上面和左边的滚动条滚动相同的偏移量就行。主要是如何实现中间这个自定义的View。

public class ReportScrollview extends LinearLayout {private Scroller mscroller;    int slop;    VelocityTracker mVelocityTracker;    int screenW,screenH;    public int visibleW=0,visibleH=0;    public ReportScrollview(Context context) {        super(context);        init(context);    }    public ReportScrollview(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        init(context);    }    public ReportScrollview(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context){        mscroller=new Scroller(context);        slop= ViewConfiguration.getTouchSlop();        screenW=context.getResources().getDisplayMetrics().widthPixels;        screenH=context.getResources().getDisplayMetrics().heightPixels;    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();    }    @Override    protected void onMeasure(int widthSpec, int heightSpec) {        super.onMeasure(widthSpec, heightSpec);    }    float lastx,lasty;    @Override    public boolean onTouchEvent(MotionEvent event) {        if ( mVelocityTracker == null ) {            mVelocityTracker = VelocityTracker.obtain();        }        mVelocityTracker.addMovement(event);           switch (event.getAction()){               case MotionEvent.ACTION_DOWN:                   lastx=event.getX();                   lasty=event.getY();                   break;               case  MotionEvent.ACTION_MOVE:                   float curx=event.getX();                   float cury=event.getY();                   float disx=curx-lastx;                   float disy=cury-lasty;                   if(Math.abs(disx)>slop|| Math.abs(disy)>slop){                       lastx=curx;                       lasty=cury;                       scrollBy(-(int)disx,-(int)disy);//让视图顺着手指滑动的方向移动                   }                   break;               case MotionEvent.ACTION_UP:                   mVelocityTracker.computeCurrentVelocity(1000,2000.0f);                   int xVelocity = (int) mVelocityTracker.getXVelocity();                   int yVelocity = (int) mVelocityTracker.getYVelocity();                   if ( Math.abs(xVelocity) > 10                           || Math.abs(xVelocity) > 10 ) {                       mscroller.fling(getScrollX(),getScrollY(),                               -xVelocity,-yVelocity,0,getMeasuredWidth()-visibleW,0,getMeasuredHeight()-visibleH);//手指拿起后,让视图随着惯性移动,并设置好移动的最大最小范围                       invalidate();                   }                   break;           }        return true;    }    public void startScrollBy(int dx,int dy) {        mscroller.forceFinished(true);        int startX = getScrollX();        int startY = getScrollY();        mscroller.startScroll(startX,startY,startX+dx,startY+dy);        invalidate();    }    @Override    public void computeScroll() {        super.computeScroll();        if (mscroller.computeScrollOffset()) {            scrollTo(mscroller.getCurrX(),mscroller.getCurrY());            if (mscroller.getCurrX() == getScrollX()                    && mscroller.getCurrY() == getScrollY() ) {                postInvalidate();            }        }    }    @Override    protected void onScrollChanged(int l, int t, int oldl, int oldt) {        super.onScrollChanged(l, t, oldl, oldt);          if(scrollChangedListener!=null){          //通过接口把这个View横纵坐标上的偏移量暴露出去           scrollChangedListener.onScrollChanged(l,t,oldl,oldt);          }    }    private OnScrollChangedListener scrollChangedListener;    public void setScrollChangedListener(OnScrollChangedListener scrollChangedListener) {        this.scrollChangedListener = scrollChangedListener;    }    public interface  OnScrollChangedListener{        public void onScrollChanged(int l, int t, int oldl, int oldt);    }}

中间这个View我是通过继承LinearLayout实现的,主要是重写onTouchEvent,computeScroll(),onScrollChanged(int l, int t, int oldl, int oldt)这几个方法,关键步骤已经注释了。

原创粉丝点击