自定义SeekBar , 滑动评分

先说一下需求,【自定义可滑动评分拉杆】,

如下图(完成后的效果图):

看到这个需求,第一反应是自定义SeekBar , 因为这样相对于自己重新写一个可省去很多功夫。

其实很简单: 直接使用原生SeekBar,替换它的滑块、及背景图。

这么做呢是没有什么问题,但当你实际替换的时候,你会发现滑块可以替换,但背景图替换后会出现问题:

杆状背景图无法充满,滑块与滑杆之间有距离(如图):

这是因为,原生SeekBar的滑块是个圆形球状,它的直径要比我们要替换的滑块宽很多,所以才会留下缝隙,导致无法充满。

网上说要设置什么SeekBar的各种属性,我都试了没毛用,

所以我就偷个懒,直接将SeekBar的背景设置成透明的,然后再将自己的彩虹背景图替换到同等位置拉伸充满就OK了。

事实证明,我偷懒的功夫还是可以的,这样做出来完全没毛病(请参照完成效果图)。

然后就是滑块上面的Popup了,当初是想做成Popup的,但一想太费工夫效率也不高,所有就又想偷懒了。

我的思路是,直接将这个Popup写成一个Layout,

给Layou设置一个背景图,然后将这个Layout置于滑块正上方给一个初始位置,滑动的时候再去计算位置就OK了。

事实证明,我偷懒的功夫还是可以的,这样做出来完全没毛病(请参照完成效果图)。

代码贴出来,这里主要就是 Item 的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:descendantFocusability="blocksDescendants">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="15dp"
        android:background="@color/white">
        <TextView
            android:id="@+id/scoreName"
            android:layout_width="70dp"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            tools:text="技术能力"
            android:textColor="@color/black"
            android:singleLine="true"
            android:layout_marginTop="28.5dp"/>

        <TextView
            android:id="@+id/scoreValue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            tools:text="3.5分"
            android:textColor="@color/blue2"
            android:layout_alignParentRight="true"
            android:layout_marginTop="28.5dp"/>

        <RelativeLayout
            android:id="@+id/mTopLayout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="60dp">
            <TextView
                android:id="@+id/mTopTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="很差"
                android:textSize="14sp"
                android:textColor="@color/im_blue"
                android:background="@drawable/icon_msg"
                android:gravity="center"
                android:paddingBottom="2dp"/>
        </RelativeLayout>

        <LinearLayout
            android:id="@+id/seekLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/scoreName"
            android:layout_toLeftOf="@id/scoreValue"
            android:layout_centerVertical="true"
            android:orientation="vertical"
            android:layout_below="@id/mTopLayout">
            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="10dp">
                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="12dp"
                    android:src="@drawable/jihui_bg_pingfen"
                    android:layout_centerVertical="true"
                    android:scaleType="fitXY"/>
                <SeekBar
                    android:id="@+id/mSeekBar"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:thumb="@drawable/my_seekbar_thumb"
                    android:progressDrawable="@drawable/my_seeckbar_background"
                    android:max="50"
                    android:splitTrack="false"/>
            </RelativeLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:layout_marginTop="5dp"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="10dp">
                <RelativeLayout
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1">
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="0"
                        android:textColor="@color/gray_font"
                        android:textSize="14sp"/>
                </RelativeLayout>

                <RelativeLayout
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1">
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="1"
                        android:textColor="@color/gray_font"
                        android:textSize="14sp"/>
                </RelativeLayout>

                <RelativeLayout
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1">
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="2"
                        android:textColor="@color/gray_font"
                        android:textSize="14sp"/>
                </RelativeLayout>

                <RelativeLayout
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1">
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="3"
                        android:textColor="@color/gray_font"
                        android:textSize="14sp"/>
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="4"
                        android:textColor="@color/gray_font"
                        android:textSize="14sp"
                        android:layout_alignParentRight="true"/>
                </RelativeLayout>

                <RelativeLayout
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1">
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="5"
                        android:textColor="@color/gray_font"
                        android:textSize="14sp"
                        android:layout_alignParentRight="true"/>
                </RelativeLayout>
            </LinearLayout>
        </LinearLayout>
    </RelativeLayout>
</LinearLayout>
彩虹条背景图android:src="@drawable/jihui_bg_pingfen",可根据需求自己替换;

滑块图片android:thumb="@drawable/my_seekbar_thumb",可根据需求自己替换;

SeekBar透明背景android:progressDrawable="@drawable/my_seeckbar_background"如下:


<?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="@color/transparent" />
        </shape>
    </item>
    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <solid android:color="@color/transparent" />
            </shape>
        </clip>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <solid android:color="@color/transparent" />
            </shape>
        </clip>
    </item>

</layer-list>

OK,到这里我们的布局基本完成,接下来就是要计算这个Popup的位置了。

当SeekBar的滑块滑动的时候,Popup要跟随滑块滑动,并随着滑动区域不同而显示不同的文字。

既然Popup写成了Layout,我们就通过setLayoutParams来改变Popup的位置,

那位置怎么计算,重点来了:

SeekBar的实际宽度 / SeekBar的最大值 = SeekBar最小单位的实际滑动距离

SeekBar当前值 * SeekBar最小单位的实际滑动距离 = Popup距左侧的实际距离

看懂这两个公式,其实就很简单了,

最后一步setLayoutParams(layoutParams)就OK了

贴一下代码(以下代码在adapter中的getVeiw中):

//设置SeekBar的初始值
if(firstIn.equals("0")){ //防止循环设置seekBar的progress
    scoreValue.setText(Float.valueOf(mScore)+"分");
    mSeekBar.setProgress((int) (Float.valueOf(mScore) * 10));
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            //延时设置Popup的初始位置
            setSeekBarLocation(mSeekBar,(int) (Float.valueOf(mScore) * 10),mTopTextView);
        }
    },200);
}

//seekBar滑动监听
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    @Override
    public void onProgressChanged(SeekBar seekBar, int value, boolean b) {
        float mValue = (float) value / 10;
        scoreValue.setText(mValue+"分");
        setSeekBarLocation(seekBar,value,mTopTextView);//每次滑动都设置一遍Popup的位置
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        firstIn = "1";
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
       
    }
});
//设置Popup的位置
private void setSeekBarLocation(SeekBar seekBar,int value,TextView mTopTextView){
    if(mWidth == 0){
        mWidth = seekBar.getWidth();//SeekBar的实际宽度
        movePixes = ((float) mWidth / (float) seekBar.getMax());
    }

    int newLeftMargin = (int) (movePixes * seekBar.getProgress());//SeekBar滑块距左侧的距离

    //设置不同区域的显示文字
    if(value >= 0 && value <= 20){ 
        mTopTextView.setText("很差");
    }else if(value >20 && value < 25){
        mTopTextView.setText("不合格");
    }else if(value >=25 && value <= 30){
        mTopTextView.setText("合格");
    }else if(value >30 && value < 40){
        mTopTextView.setText("良好");
    }else if(value >= 40){
        mTopTextView.setText("优秀");
    }

    RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTopTextView.getLayoutParams();
    layoutParams.leftMargin = newLeftMargin;
    mTopTextView.setLayoutParams(layoutParams);//设置Popup的位置
}

OK,到这里就大功告成了。

猜你喜欢

转载自blog.csdn.net/qq_22714623/article/details/81168476