1、前语

最近在开发中,搭档关于android.widget下的控件一知半解,又恰好那天用到了Seekbar,想了想,那就从Seekbar’s father ProgressBar 来说说android.widget下的常用控件和常用用法吧。后面也会根据这些控件来进行仿写、扩展,做一些高度自定义的View啦。假如写的欠好,或许有过错之处,恳请在评论、私信、邮箱指出,万分感谢

系列更新:

5分钟带你了解Android Progress Bar1

5分钟带你了解Android Progress Bar2

5分钟带你了解Android Progress Bar3

2、ProgressBar

A user interface element that indicates the progress of an operation.

运用很简略,看看一些根本的属性

android:max:进展条的最大值
android:progress:进展条已完成进展值
android:progressDrawable:设置轨道对应的Drawable对象
android:indeterminate:假如设置成true,则进展条不精确显现进展(会一直进行动画)
android:indeterminateDrawable:设置不显现进展的进展条的Drawable对象
android:indeterminateDuration:设置不精确显现进展的持续时间
android:secondaryProgress:二级进展条(运用场景不多)

直接在布局中运用即可

        <ProgressBar
            style="@android:style/Widget.ProgressBar.Small"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp" />
        <ProgressBar
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp" />
        <ProgressBar
            style="@android:style/Widget.ProgressBar.Large"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp" />
        <ProgressBar
            android:id="@+id/sb_no_beautiful"
            style="@android:style/Widget.ProgressBar.Horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:max="100"
            android:progress="50"
            android:secondaryProgress="70" />
        <ProgressBar
            android:id="@+id/sb_no_beautiful2"
            style="@android:style/Widget.Holo.ProgressBar.Horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:indeterminate="true"
            android:max="100"
            android:progress="50"
            android:secondaryProgress="70" />

别离就对应以下图片咯

5分钟带你了解Android Progress Bar

可是这种款式,不得不怀疑Google之前的审美,肯定是不满意的,怎样换款式呢。

看看XML文件,很简略发现,这几个ProgressBar的差异是由于style引起的,顺手点开一个@android:style/Widget.ProgressBar.Horizontal 看看。

    <style name="Widget.ProgressBar.Horizontal">
        <item name="indeterminateOnly">false</item>
        <item name="progressDrawable">@drawable/progress_horizontal</item>
        <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal</item>
        <item name="minHeight">20dip</item>
        <item name="maxHeight">20dip</item>
        <item name="mirrorForRtl">true</item>
    </style>

很好,估摸着款式就出在progressDrawable/indeterminateDrawable上面,看看 @drawable/progress_horizontal 里面

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="5dip" />
            <gradient
                    android:startColor="#ff9d9e9d"
                    android:centerColor="#ff5a5d5a"
                    android:centerY="0.75"
                    android:endColor="#ff747674"
                    android:angle="270"/>
        </shape>
    </item>
    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <corners android:radius="5dip" />
                <gradient
                        android:startColor="#80ffd300"
                        android:centerColor="#80ffb600"
                        android:centerY="0.75"
                        android:endColor="#a0ffcb00"
                        android:angle="270"/>
            </shape>
        </clip>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="5dip" />
                <gradient
                        android:startColor="#ffffd300"
                        android:centerColor="#ffffb600"
                        android:centerY="0.75"
                        android:endColor="#ffffcb00"
                        android:angle="270"/>
            </shape>
        </clip>
    </item>
</layer-list>

一个款式文件,别离控制了background/secondaryProgress/progress,这样咱们很简略推测出

5分钟带你了解Android Progress Bar

再看看 @drawable/progress_indeterminate_horizontal

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
    <item android:drawable="@drawable/progressbar_indeterminate1" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate2" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate3" android:duration="200" />
</animation-list>

显而易见,这是indeterminate模式下的款式啊,那咱们仿写一个不同款式,就很简略了,着手。

styles.xml

<style name="ProgressBar_Beautiful" >
    <item name="android:indeterminateOnly">false</item>
    <item name="android:progressDrawable">@drawable/progress_horizontal_1</item>
    <item name="android:indeterminateDrawable">@drawable/progress_indeterminate_beautiful</item>
    <item name="android:mirrorForRtl">true</item>
</style>

progress_horizontal_1.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>
            <corners android:radius="25dp" />
            <solid android:color="#FFF0F0F0"/>
        </shape>
    </item>
    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <corners android:radius="25dp" />
                <solid android:color="#FFC0EC87"/>
            </shape>
        </clip>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="25dp" />
                <solid android:color="#FFA5E05B"/>
            </shape>
        </clip>
    </item>
</layer-list>

progress_indeterminate_beautiful.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@drawable/bg_progress_001" android:duration="200" />
    <item android:drawable="@drawable/bg_progress_002" android:duration="200" />
    <item android:drawable="@drawable/bg_progress_003" android:duration="200" />
    <item android:drawable="@drawable/bg_progress_004" android:duration="200" />
</animation-list>

吭呲吭呲就写出来了,看看效果

换了个色彩,加了个圆角/ 换了个图片,还行。

我没有去再写环形的ProgressBar了,由于它便是个一个图,疯狂的在旋转。

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/spinner_white_76"
    android:pivotX="50%"
    android:pivotY="50%"
    android:framesCount="12"
    android:frameDuration="100" />

还有一些属性我就不赘述了。你可以根据官方的款式,修一修、改一改,就可以满意一些根本的需求了。

用起来就这么简略,便是由于太简略,更杂乱的功能就不是ProgressBar能直接完成的了。比如带个滑块?

3、SeekBar

好吧,ProgressBar的一个子类,也在android.widget下,由于是直接承继,而且就加了个滑块相关的代码,实际上它也十分简略,然咱们来看看

<SeekBar
    android:id="@+id/sb_01"
    style="@style/ProgressBar_Beautiful"
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:layout_marginVertical="10dp"
    android:thumbOffset="1dp"
    android:max="100"
    android:progress="50"
    android:secondaryProgress="70"
    android:splitTrack="false"
    android:thumb="@drawable/icon_seekbar_thum" />
<SeekBar
    android:id="@+id/sb_02"
    style="@style/ProgressBar_Beautiful"
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:layout_marginVertical="10dp"
    android:max="100"
    android:progress="50"
    android:secondaryProgress="70"
    android:thumb="@drawable/icon_seekbar_thum" />
<SeekBar
    android:id="@+id/sb_03"
    style="@style/ProgressBar_Beautiful"
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:layout_marginVertical="10dp"
    android:max="100"
    android:progress="100"
    android:secondaryProgress="70"
    android:splitTrack="false"
    android:thumb="@drawable/icon_seekbar_thum" />
<SeekBar
    android:id="@+id/sb_04"
    style="@style/ProgressBar_Beautiful"
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:layout_marginVertical="10dp"
    android:thumbOffset="1dp"
    android:max="100"
    android:progress="100"
    android:secondaryProgress="70"
    android:splitTrack="false"
    android:thumb="@drawable/icon_seekbar_thum" />
<SeekBar
    android:id="@+id/sb_05"
    style="@style/ProgressBar_Beautiful"
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:layout_marginVertical="10dp"
    android:max="100"
    android:paddingHorizontal="0dp"
    android:progress="50"
    android:secondaryProgress="70"
    android:thumb="@drawable/icon_seekbar_thum" />
<SeekBar
    android:id="@+id/sb_06"
    style="@style/ProgressBar_Beautiful"
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:layout_marginVertical="10dp"
    android:max="100"
    android:progress="50"
    android:secondaryProgress="70"
    android:thumb="@null" />

款式就在下面了

5分钟带你了解Android Progress Bar

由于Seekbar相较而言就多了个thumb(便是那个滑块),所以就着重说一下滑块,其他的就一笔带过咯。

主要了解的是怎么设置自己的thumb和thumb的各种问题

android:thumb="@drawable/icon_seekbar_thum"

设置就这么thumb简略,一个drawable文件解决,我这儿对应的是单一图片,不过Google的是带有多种状态的thumb,咱们来看看官方是怎么完成的

<selector xmlns:android="http://schemas.android.com/apk/res/android"
          android:constantSize="true">
    <item android:state_enabled="false" android:state_pressed="true">
        <bitmap android:src="@drawable/abc_scrubber_control_off_mtrl_alpha"android:gravity="center"/>
    </item>
    <item android:state_enabled="false">
        <bitmap android:src="@drawable/abc_scrubber_control_off_mtrl_alpha"android:gravity="center"/>
    </item>
    <item android:state_pressed="true">
        <bitmap android:src="@drawable/abc_scrubber_control_to_pressed_mtrl_005" android:gravity="center"/>
    </item>
    <item>
        <bitmap android:src="@drawable/abc_scrubber_control_to_pressed_mtrl_000"android:gravity="center"/>
    </item>
</selector>

引用一个drawable,也是一个熟知的selector组,通过对应的item,咱们就可以完成在不同的状态下显现不同的thumb了,具体的款式我就不写了,再说ProgressBar的款式的时候也是有类似的操作的

不过你或许发现了,其实这几个款式看起来都差不多,是由于都是我运用Seekbar遇到的问题以及解决方法,咱们细说

(1) 自定义的thumb的背景会裁剪出一个正方形,这关于不规则图形来讲是十分难看的

5分钟带你了解Android Progress Bar

很简略一行

android:splitTrack=”false”

修正0。0

(2)thumb的中心点对齐bar的边界,所以thumb是答应超出进展条一点的。有时候咱们不需求

5分钟带你了解Android Progress Bar

很简略一行

android:thumbOffset=”1dp”

修正0,0

(3) 你或许发现就算没有写margin和padding,seekbar也不会占满父布局的,是由于它自带padding,所以假如需求去掉

5分钟带你了解Android Progress Bar

很简略一行

android:paddingHorizontal=”0dp”

修正0>0

(4)最后一个,SeekBar可是不想要滑块!为什么不必ProgressBar呢?没其他便是头铁!

很简略一行

android:thumb=”@null”

修正0」0

可是要注意的是,此时Seekbar仍是能点击的!所以需求把点击事件拦截掉

sb02.setOnTouchListener { _, _ -> true }

真的修正0[]0

好了好了,thumb的监听事件还没说呢

            sb01.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
                override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
                    //进展发生改变时会触发
                }
                override fun onStartTrackingTouch(p0: SeekBar?) {
                    //按住SeekBar时会触发
                }
                override fun onStopTrackingTouch(p0: SeekBar?) {
                    //放开SeekBar时触发
                }
            })

没啦,Seekbar就这么多。

还有一个,放在下次讲吧

对了,假如你感觉你的ProgressBar不够流通,可以用以下这个

bar.setProgress(progress, true)

4、结尾

更多杂乱的进展条需求,靠widget的控件,肯定是难以完成的,咱们接下来会讲述RatingBar,以及承继ProgressBar,做更多美观的进展条!

没啦,这次就这么多。

假如写的欠好,或许有过错之处,恳请在评论、私信、邮箱指出,万分感谢

“开启成长之旅!这是我参与「日新计划 2 月更文应战」的第 1 天,点击检查活动详情”