效果图
FloatingTextSeekBar.java
package com.bu_ish.blog; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Build; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.View; import android.widget.LinearLayout; import android.widget.SeekBar; import java.lang.reflect.Field; public class FloatingTextSeekBar extends LinearLayout { private SeekBar sb; private FloatingTextView ftv; private String startText = "100"; private int max = 49; private float floatingTextX; private static final String TAG = FloatingTextSeekBar.class.getName(); public FloatingTextSeekBar(Context context, AttributeSet attrs) { super(context, attrs); setOrientation(VERTICAL); sb = new SeekBar(context); LayoutParams sbLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); sb.setLayoutParams(sbLayoutParams); sb.setPadding(16, 0, 16, 0); try { Class cls = sb.getClass().getSuperclass().getSuperclass(); Field field = cls.getDeclaredField("mMaxHeight"); field.setAccessible(true); field.set(sb, PixelTool.dpToPx(context, 5)); } catch (NoSuchFieldException | IllegalAccessException ex) { Log.e(TAG, null, ex); } sb.setMax(max); sb.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar_progress_drawable)); sb.setThumb(getResources().getDrawable(R.mipmap.ic_seek_bar_thumb)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) sb.setSplitTrack(false); addView(sb); ftv = new FloatingTextView(context); LayoutParams ftvLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, PixelTool.dpToPx(context, 12)); ftvLayoutParams.topMargin = PixelTool.dpToPx(context, 2); ftv.setLayoutParams(ftvLayoutParams); ftv.setText(startText); addView(ftv); sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { float step = seekBar.getWidth() / (float) max; floatingTextX = progress * step; ftv.setText((progress + Integer.parseInt(startText) / 100) * 100 + ""); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); } public void setStartText(String startText) { this.startText = startText; } public void setMax(int max) { this.max = max; sb.setMax(max); } private class FloatingTextView extends View { private String text; private FloatingTextView(Context context) { super(context); } private void setText(String text) { this.text = text; invalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setColor(Color.parseColor("#ff5158e7")); float textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 15, getResources().getDisplayMetrics()); paint.setTextSize(textSize); paint.setTextAlign(Paint.Align.CENTER); float textWidth = paint.measureText(text); if (floatingTextX - textWidth / 2 < getLeft()) { floatingTextX += textWidth / 2; } if (floatingTextX + textWidth / 2 > getRight()) { floatingTextX -= textWidth / 2; } canvas.drawText(text, floatingTextX, getHeight(), paint); } } }
seek_bar_progress_drawable.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 android:shape="rectangle"> <solid android:color="#ffebebeb" /> <corners android:bottomLeftRadius="3dp" android:bottomRightRadius="3dp" android:topLeftRadius="3dp" android:topRightRadius="3dp" /> shape> item> <item android:id="@android:id/progress"> <clip> <shape android:shape="rectangle"> <solid android:color="#ff5158e7" /> <corners android:bottomLeftRadius="3dp" android:bottomRightRadius="3dp" android:topLeftRadius="3dp" android:topRightRadius="3dp" /> shape> clip> item> layer-list>
activity_main.xml
xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@android:color/white" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="16dp" android:text="请选择到账金额(元)" android:textColor="#ff1b1b1b" android:textSize="14sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal"> <TextView android:id="@+id/tvBorrowableMin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:layout_marginRight="5dp" android:textColor="#ff999999" android:textSize="12sp" tools:text="100" /> <com.bu_ish.blog.FloatingTextSeekBar android:id="@+id/ftsb" android:layout_width="250dp" android:layout_height="wrap_content" android:layout_marginTop="48dp" /> <TextView android:id="@+id/tvBorrowableMax" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginTop="48dp" android:textColor="#ff999999" android:textSize="12sp" tools:text="5000" /> LinearLayout> LinearLayout>
MainActivity.java
package com.bu_ish.blog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private TextView tvBorrowableMin, tvBorrowableMax; private FloatingTextSeekBar ftsb; private int borrowableMin = 500, borrowableMax = 10000; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvBorrowableMin = findViewById(R.id.tvBorrowableMin); tvBorrowableMax = findViewById(R.id.tvBorrowableMax); ftsb = findViewById(R.id.ftsb); tvBorrowableMin.setText(borrowableMin + ""); tvBorrowableMax.setText(borrowableMax + ""); ftsb.setStartText(borrowableMin + ""); ftsb.setMax((borrowableMax - borrowableMin) / 100); } }
完整Demo链接:https://pan.baidu.com/s/1ohRtbYsSJi8105brvj3fkQ,提取码:lwif
P.S.
SeekBar.setProgressDrawable(Drawable),设置进度颜色、进度背景
SeekBar.setThumb(Drawable),设置滑块