美文网首页Android知识点
Android 纯代码实现Seekbar布局,解决maxHeig

Android 纯代码实现Seekbar布局,解决maxHeig

作者: 匿名沉默 | 来源:发表于2018-09-29 14:49 被阅读0次

Seekbar常规使用方式通过xml布局方式实现,但是由于我们的是sdk,不能有xml布局,所以SeekBar使用纯代码实现。但是这样就遇到了很多问题。
首先是SeekBar设置setProgressDrawable问题。因为我们的是视频播放器,所以这个SeekBar需要有背景、缓冲进度和播放进度,最好的方法就是用layer-list 的xml布局实现,类似这样:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <solid android:color="#cc999999" />
            <size android:height="3dp" />
            <corners android:radius="1.5dip" />
        </shape>
    </item>
    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <solid android:color="#9f4ef1" />
                <size android:height="3dp" />
                <corners android:radius="1.5dip" />
            </shape>
        </clip>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <solid android:color="#0add2c" />
                <size android:height="3dp" />
                <corners android:radius="1.5dip" />
            </shape>
        </clip>
    </item>
</layer-list>

这是正常的xml布局样式,这样的布局我们需要用java纯代码实现,如下:

 Drawable[] drawables = new Drawable[3];
        GradientDrawable roundRect = new GradientDrawable();
        roundRect.setShape(GradientDrawable.RECTANGLE);
        roundRect.setColor(Color.parseColor(ViewUtils.getInstance().progressColor1));
        roundRect.setSize(1,FormatUtils.dip2px(1,context));
        roundRect.setCornerRadius(FormatUtils.dip2px(1.5f,context));
        drawables[0] = roundRect;

        roundRect = new GradientDrawable();
        roundRect.setShape(GradientDrawable.RECTANGLE);
        roundRect.setColor(Color.parseColor(ViewUtils.getInstance().progressColor3));
        roundRect.setSize(1,FormatUtils.dip2px(1,context));
        roundRect.setCornerRadius( FormatUtils.dip2px(1.5f,context));
        ClipDrawable clipDrawable = new ClipDrawable(roundRect, Gravity.LEFT, VERTICAL);
        drawables[1] =clipDrawable;

        roundRect = new GradientDrawable();
        roundRect.setShape(GradientDrawable.RECTANGLE);
        roundRect.setColor(Color.parseColor(ViewUtils.getInstance().colorProgress));
        roundRect.setSize(1,FormatUtils.dip2px(1,context));
        roundRect.setCornerRadius(FormatUtils.dip2px(1.5f,context));
        clipDrawable = new ClipDrawable(roundRect, Gravity.LEFT, VERTICAL);
        drawables[2] = clipDrawable;


        LayerDrawable layerDrawable = new LayerDrawable(drawables);
        layerDrawable.setId(0,android.R.id.background);
        layerDrawable.setId(1,android.R.id.secondaryProgress);
        layerDrawable.setId(2,android.R.id.progress);

然后直接SeekBar.setProgressDrawable就可以。

第二个问题是,SeekBar高度问题,这个才是最坑的,研究了很多,SeekBar如果用xml布局会有两个方法android:maxHeight="4dp"android:minHeight="4dp",但是如果是java写,就只有progressBar.setMinimumHeight(FormatUtils.dip2px(1,context));,用来设置最小高度,这样的话就有一个问题,如果你SeekBar设置seekBar.setThumb( bitmapDrawable);哪么SeekBar的进度条高度也会变得和Thumb一样高,会撑满。这里有两个解决办法:
一是在6.0以上的手机适用,就是在上面设置layerDrawable代码后面再加两句

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            layerDrawable.setLayerHeight(0,FormatUtils.dip2px(2,context));
            layerDrawable.setLayerHeight(1,FormatUtils.dip2px(2,context));
            layerDrawable.setLayerHeight(2,FormatUtils.dip2px(2,context));
            layerDrawable.setLayerGravity(0,Gravity.CENTER_VERTICAL);
            layerDrawable.setLayerGravity(1,Gravity.CENTER_VERTICAL);
            layerDrawable.setLayerGravity(2,Gravity.CENTER_VERTICAL);
        }

整体是这样:

public static Drawable genSeekProgressDrawable(Context context) {
        Drawable[] drawables = new Drawable[3];
        GradientDrawable roundRect = new GradientDrawable();
        roundRect.setShape(GradientDrawable.RECTANGLE);
        roundRect.setColor(Color.parseColor(ViewUtils.getInstance().progressColor1));
        roundRect.setSize(1,FormatUtils.dip2px(1,context));
        roundRect.setCornerRadius(FormatUtils.dip2px(1.5f,context));
        drawables[0] = roundRect;

        roundRect = new GradientDrawable();
        roundRect.setShape(GradientDrawable.RECTANGLE);
        roundRect.setColor(Color.parseColor(ViewUtils.getInstance().progressColor3));
        roundRect.setSize(1,FormatUtils.dip2px(1,context));
        roundRect.setCornerRadius( FormatUtils.dip2px(1.5f,context));
        ClipDrawable clipDrawable = new ClipDrawable(roundRect, Gravity.LEFT, VERTICAL);
        drawables[1] =clipDrawable;

        roundRect = new GradientDrawable();
        roundRect.setShape(GradientDrawable.RECTANGLE);
        roundRect.setColor(Color.parseColor(ViewUtils.getInstance().colorProgress));
        roundRect.setSize(1,FormatUtils.dip2px(1,context));
        roundRect.setCornerRadius(FormatUtils.dip2px(1.5f,context));
        clipDrawable = new ClipDrawable(roundRect, Gravity.LEFT, VERTICAL);
        drawables[2] = clipDrawable;


        LayerDrawable layerDrawable = new LayerDrawable(drawables);
        layerDrawable.setId(0,android.R.id.background);
        layerDrawable.setId(1,android.R.id.secondaryProgress);
        layerDrawable.setId(2,android.R.id.progress);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            layerDrawable.setLayerHeight(0,FormatUtils.dip2px(2,context));
            layerDrawable.setLayerHeight(1,FormatUtils.dip2px(2,context));
            layerDrawable.setLayerHeight(2,FormatUtils.dip2px(2,context));
            layerDrawable.setLayerGravity(0,Gravity.CENTER_VERTICAL);
            layerDrawable.setLayerGravity(1,Gravity.CENTER_VERTICAL);
            layerDrawable.setLayerGravity(2,Gravity.CENTER_VERTICAL);
        }

        return layerDrawable;
    }

二是适配所有的手机,这样的话我没有找到好的方法,只能用反射去修改SeekBar的父类的父类progressBar的最大高度,mMaxHeight的值,这个就是设置SeekBar的最大高度的值,xml代码android:maxHeight="4dp"其实改变的就是这个的值。
代码也很简单:

try {
                Class<?> superclass = seekBar.getClass().getSuperclass().getSuperclass();
                Field mMaxHeight = superclass.getDeclaredField("mMaxHeight");
                mMaxHeight.setAccessible(true);
                mMaxHeight.set(seekBar,FormatUtils.dip2px(2,context));
            } catch (Exception e) {
                e.printStackTrace();
            }

其实最好的方法就是两个一起用,6.0以下用反射,6.0以上用layerDrawable的方法去实现。这是我个人研究的办法,网上也没有实现的办法,找了很久。如果有更好的求告知啊!!!!!

相关文章

  • Android 纯代码实现Seekbar布局,解决maxHeig

    Seekbar常规使用方式通过xml布局方式实现,但是由于我们的是sdk,不能有xml布局,所以SeekBar使用...

  • SeekBar

    Android-SeekBar进度条的使用Android控件与布局——基础控件SeekBar

  • Android 进度控件

    Android 进度控件 Android 圆形、半圆形进度效果、半圆SeekBar、刻度尺效果实现代码下载:Git...

  • Android仿酷狗音乐SeekBar——样式篇

    Android仿酷狗音乐SeekBar 需求:仿酷狗音乐SeekBar 直接上图,上代码 ** 难点:用户点击或者...

  • TableCell自适应输入框

    纯代码实现cell布局,利用约束实现自适应布局。下面展示的为实现自适应输入框的部分关键代码 初始化cell 设置布...

  • TableCell自适应输入框

    知识点: 纯代码实现cell布局,利用约束实现自适应布局。下面展示的为实现自适应输入框的部分关键代码 [图片上传中...

  • 安卓开发入门教程-UI控件_SeekBar

    什么是SeekBar SeekBar是支持拖动的进度显示条. 基础样例 1. 普通样例 效果图 代码 布局文件 a...

  • Android纯代码布局LinearLayout

    前段时间公司要求做个SDK的登录界面,没办法用XML布局了,很头疼。等到要纯代码编界面的时候才发现XML是有多么的...

  • Android纯代码编写布局

    概述:android动态效果免不了需要编写代码布局,所以记录一下常用布局组件的编写方式。 一、编写LinearLa...

  • Android常用控件之ListView

    目录:android.widget.ListView xml布局 调用代码: 解决ScrollView嵌套List...

网友评论

    本文标题:Android 纯代码实现Seekbar布局,解决maxHeig

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