美文网首页
使用DialogFragment 实现嵌套ViewPager,按

使用DialogFragment 实现嵌套ViewPager,按

作者: 则卷滔滔 | 来源:发表于2019-06-06 10:43 被阅读0次

    产品需求:

    一个dialog中有个点击显示详情按钮,而详情要是在弹窗内部展示,产品需要的效果是想页面跳转一样有一个向右的动画效果,这个时候就想到了在dialog中嵌套viewpager来完成

    碰到的问题:

    • 选择方案
      在dialog中嵌套viewpager会存在报错的异常,网上有很多多说了,给出的解决方案是使用dialogfragment来替代dialog嵌套viewpager,由于自身项目中fragment使用也很多,所以就直接选用这套方案。
    • 高度匹配问题
      由于viewpager里面的布局高度为wrap_content时并没作用,会出现高度撑不满或者空白区域很多的情况,这个时候需要一个复写viewpager的自定义控件,计算子空间高度,取最大高度设置会viewapager高度,复写onMeasure方法,代码如下
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
        int height = 0;
        for(int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if(h > height) height = h;
        }
    
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
    
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    
    • 新问题的出现
      本以为就此可以结束,但是在添加了详情界面的列表是,出现了高度铺满屏幕的问题,新出现的问题是,列表界面的height测量出来是无效高的,只要没有设置指定的高度,是会把所有的高度给到列表的,所以通过上诉的重写onMeasure测量出来的最大child的高度就是撑屏幕的高度。仔细研究需求,根据我们界面,详情列表的展示区域是和当前界面的展示区域是一样高度的,所以改造onMeasure方法 之测量第一个pager的高度作为viewpager的高度,代码如下

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

        var height = 0
        //下面遍历所有child的高度
        for (i in 0 until childCount) {
            if (i == 0) {
                val child = getChildAt(i)
                child.measure(widthMeasureSpec,
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED))
                val h = child.measuredHeight
                if (h > height)
                //采用最大的view的高度。
                    height = h
            }
        }
    
        var heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
    
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }
    
    • 额外的需求
      去除viewpager的滑动效果,只有在点击的时候进行跳转,实现点击右滑动画,只需要在刚才自定义viewpager的控件中添加:

    fun setNoScroll(noScroll: Boolean) {

        this.noScroll = noScroll
    }
    
    override fun onTouchEvent(arg0: MotionEvent): Boolean {
        return if (noScroll)
            false
        else
            super.onTouchEvent(arg0)
    }
    
    override fun onInterceptTouchEvent(arg0: MotionEvent): Boolean {
        return if (noScroll)
            false
        else
            super.onInterceptTouchEvent(arg0)
    }
    
    • 边距问题
      最后碰到一个非常奇怪的问题,设置viewpager内部pager的边距时 直接设置在跟布局viewpager上,在内部pager设置边距可能会和跟布局padding冲突,仅此记录。

    相关文章

      网友评论

          本文标题:使用DialogFragment 实现嵌套ViewPager,按

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