美文网首页
B1(负一楼)展示页---BasementView

B1(负一楼)展示页---BasementView

作者: truemi | 来源:发表于2018-08-01 13:10 被阅读0次

之前分享过一篇仿微信下拉显示小程序的控件,今天分享的与之相似,只不过是下拉展示全部的view,同时主界面可以添加任意布局.支持绑定AbsListview子类,和可滑动的view.

演示:

b1.gif

从上面的演示中,可以看到,有4种动作:

  1. 下拉,没有超过预设阀值,则回弹到关闭状态
  2. 下拉,超过阀值,这滚动到b1(隐藏的view)完全打开的状态
  3. 上拉,没有超过预设阀值,则回弹到b1完全打开状态
  4. 上拉,超过阀值,这滚动到b1(隐藏的view)完全关闭的状态

作用的view上就是view的显示与隐藏问题,之前我们使用改变viewpadding值,这里我们使用动态改变view的margin值,从而改变view显示与隐藏.

所以我们的思路是:

在onTouchEvent的监听中,

  • MOVE状态下,根据手势,时刻改变b1的marginTop值,达到随手势打开view和关闭view的动态效果
  • 在UP状态下,根据手势状态(下拉或上拉),预设阀值,b1的显示状态判断b1的滚动动作.
    view的滚动,依然使用Scroller滚动器.
关键步骤:

1.自定义view继承LinearLayout,初始化basementLayout和currentLayout布局

  setOrientation(VERTICAL);//设置纵向布局
        basementLayout = new RelativeLayout(context);//负一楼layout
        currentLayout = new RelativeLayout(context);//当前layout

        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                getViewTreeObserver().removeOnGlobalLayoutListener(this);
//                测量当前view的高度,通过margintop隐藏负一楼layout
                height = getHeight();
                layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height);
                layoutParams.setMargins(0, -height, 0, 0);//隐藏b1
                basementLayout.setLayoutParams(layoutParams);
                basementLayout.setEnabled(true);
                LinearLayout.LayoutParams layoutParams1 = new            LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height);
                currentLayout.setLayoutParams(layoutParams1);
                //添加到当前view中
                addView(basementLayout);
                addView(currentLayout);
            }
        });

2.MOVE状态下,改变b1的marginTop
计算手指在Y轴上滑动的距离,根据手势方向设置marginTop

 layoutParams.setMargins(0, marginTop, 0, 0);
 basementLayout.setLayoutParams(layoutParams);

3.UP状态下,view自动滚动到指定位置
创建Scroller实例,同时设置插值器(初始化里创建)
scroller = new Scroller(context, new DecelerateInterpolator());
使用startScroll设置滚动区间

scroller.startScroll(0, startY, 0, endY, duration);
postInvalidate();//必须(或Invalidate();)

重写computeScroll()方法:

 public void computeScroll() {
        moving = scroller.computeScrollOffset();
        if (scroller.computeScrollOffset()) {
/*获取实时的Y轴的变化值
*这个变化值是从上边传入的startY 到 (startY + endY)
*如:startY =0,endY=100;则变化区间是从0一直递增到100;
*startY=100,endY = -100,则变化区间是100递减到0
*/
            int currY = scroller.getCurrY();//获取实时的Y轴的变化值
            postInvalidate();//必须(或Invalidate();)
//通过这个变化值,时刻改变marginTop的值,就达到了自动滚动的效果
 layoutParams.setMargins(0, currY, 0, 0);
 basementLayout.setLayoutParams(layoutParams);
}

以上只是一些重点环节,要想实现最终效果,还有很多细节要处理:

  • onInterceptTouchEvent(MotionEvent ev)对于手势拦截的处理(关键)
  • float,int转换导致的精度损失问题
  • 零界点的判断
  • 子view的是否可滑动
    ...
    涉及代码比较零散,不好阐述,详细的实现点击查看源码

相关文章

  • B1(负一楼)展示页---BasementView

    之前分享过一篇仿微信下拉显示小程序的控件,今天分享的与之相似,只不过是下拉展示全部的view,同时主界面可以添加任...

  • 商场的B1、B2层,这个“B”指哪个单词?

    我们平时逛商场坐电梯的时候 经常可以看到标着 B1、B2、表示负一、负二层 那这个“B”指的是哪个单词呢? 负一楼...

  • 别墅大house,自己来设计中式风

    【小区】保利紫晶山 【户型】一楼带负一楼 【面积】一楼200,负一楼120 【设计】实用为主,兼顾美观,自己来 【...

  • 我们为什么喜欢明星

    今天特意跑到商场去看吴克群,准点到达结果里面已经人满为患。舞台在负一楼,负一楼已经不许观众进入了,我从一楼找到五楼...

  • 2018-05-24

    南湖维佳佰港城负一楼

  • 2018-05-24

    地址:武汉南湖佰港城负一楼

  • swift数据的缓存和清除

    展示页

  • 走进九江市图书馆

    下午五点未到,孩子在三楼综合阅览室还未下楼,我就赶到图书馆去接孩子了。我从图书馆一楼大厅走到负一楼的休闲处,负一楼...

  • 2019-11-08新店开业 欢迎捧场

    新店开业 欢迎捧场 长春钻石活力汇负一楼

  • 7.30

    有的人,说着再见,就再也不见了。 希望明天还能见到他们。 今天丢垃圾去到负一楼,被好奇心驱使,想从负一楼出去,却发...

网友评论

      本文标题:B1(负一楼)展示页---BasementView

      本文链接:https://www.haomeiwen.com/subject/cejhvftx.html