仿猿题库练题滑动分屏效果

SplitView

概述

仿猿题库练题里面效果,两个 View 分层,滑动中间的 View 可调节上下 View 的高度

目标效果

在这里插入图片描述

实现效果

在这里插入图片描述

实现原理

继承 ViewGroup ,内部分为三个子 View ,分别是 top, mid (用来拖动的 View ), bottom

protected void setupViews() {
  mTop = getChildAt(0);
  mMid = getChildAt(1);
  mBottom = getChildAt(2);
  View handlerView = mMid.findViewById(R.id.handler);
  if (handlerView == null) {
      handlerView = mMid;
  }
  handlerView.setOnTouchListener(this);
}

维护一个 mSplitHeight ,用来设置分割线(即上下 View 的交界处)的位置
onMeasure(int widthMeasureSpec, int heightMeasureSpec) 中初始化 mSplitHeight 并测量子view的大小

{

  if (getChildCount() != 3) {
        throw new RuntimeException("give 3 views");
    }

    int height = MeasureSpec.getSize(heightMeasureSpec);
    if (mSplitHeight == 0) {
        mSplitHeight = (int)(height * mSplitRatio);
    }

  //measure child
  measureChild(mTop, widthMeasureSpec, MeasureSpec.makeMeasureSpec(mSplitHeight, MeasureSpec.EXACTLY));
  measureChild(mMid, widthMeasureSpec, heightMeasureSpec);
  measureChild(mBottom, widthMeasureSpec, MeasureSpec.makeMeasureSpec(getMeasuredHeight() - mSplitHeight, MeasureSpec.EXACTLY));
}

在onLayout方法中指定各个子 View 的位置

protected void onLayout(boolean changed, int l, int t, int r, int b) {
        l = t = 0;
        mTop.layout(l, t, l + mTop.getMeasuredWidth(), t + mTop.getMeasuredHeight());
        mMid.layout(l, t + mSplitHeight - mMid.getMeasuredHeight(), l + mMid.getMeasuredWidth(), t + mSplitHeight);
        mBottom.layout(l, t + mSplitHeight, l + mBottom.getMeasuredWidth(), t + mSplitHeight + mBottom.getMeasuredHeight());
    }

最后要做的就是监听 mid View 滑动时改变 mSplitHeight 的值了。
在 mid 的 onTouch(View v, MotionEvent event) 中判断,当 MotionEvent.ACTION_MOVE 时,
改变分割线的高度,然后再 requestLayout() 重新绘制即可。

{
  case MotionEvent.ACTION_MOVE:
      int delta = (int) (event.getY() - mLastMotionY);
      if (Math.abs(delta) > mTouchSlop) {
          if (delta > 0) {
              mSplitHeight += delta - mTouchSlop;
          } else {
              mSplitHeight += delta + mTouchSlop;
          }

          if (mSplitHeight < mMinSplitTop || mSplitHeight < mMid.getHeight()) {
              mSplitHeight = Math.max(mMinSplitTop, mMid.getHeight());
          } else if (mSplitHeight > getHeight() || mSplitHeight > getHeight() - mMinSplitBottom) {
              mSplitHeight = Math.min(getHeight(), getHeight() - mMinSplitBottom);
          }
          // mSplitHeight 改变之后重绘
          requestLayout();
      }
      return true;
}

项目 GitHub 地址:https://github.com/tsongski/SplitView

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值