Android の高度な SeekBar は進行状況を動的に表示します

SeekBar は開発にとって馴染みのあるものです。デフォルトの SeekBar は進行状況を表示しません。もちろん、トーストやコピーライティングを使用してリアルタイムに表示することも可能です。移動時のみ表示できますか? デフォルトでは表示されません。もちろんネット上には派手な三者関係もあるし、クラスも多すぎるけど、SeekBarをベースに動きに合わせて表示できるバブルを追加したいだけです~

まずは効果を見てみましょう。

ここに画像の説明を挿入

この記事はあなたのニーズを満たすかもしれません
1. Native SeekBar を書き換えずに使用します
2. 変更量が少なく、コントロールに影響を与えません
3. 柔軟な使用、Utils 使用、コピーアンドペーストが使用可能
4. 柔軟なスタイル、あなた自身の書き方

まず原理についてお話します。
1. まず最も基本的なことは、元のコントロールに影響を与えずに表示する方法です。
回答: PopupWindow、表示位置を指定するために対応するターゲット コントロールを取得するだけで済みます
2. 動きを追跡するにはどうすればよいですか?
回答: PopupWindow 自体は動的に移動しません。ポップアップ ウィンドウにコントロールを設定するだけで済みます。コントロールの動きは、

具体的な実装 コントロール
を取得し、PopupWindowを使用してコントロールの近くに表示し、SeekBarの進行状況に応じてポップアップウィンドウ内のサブコントロールの位置を動的に設定します。

使用

これは SeekBar モバイル モニタリングです。ここでの 3 つの方法と対応する方法です。

        mDataBind.controlVolumeSeekbar.setOnSeekBarChangeListener(object: SeekBar.OnSeekBarChangeListener{
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                //滑块移动

                SeekBarPopUtils.move(progress,seekBar!!)
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
                //滑块按下
                SeekBarPopUtils.showPop(seekBar!!)
            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                //滑块松开
                SeekBarPopUtils.dismiss()
            }
        })

SeekBarPopUtils (Kotlin)

ここの tvPopTxt は、上の図の小さなバブルです。他のスタイルが必要な場合は、ポップアップ ウィンドウのレイアウトに直接書き込むことができます。

/**
 * SeekBar移动时弹出对应的气泡加数字*/
@SuppressLint("StaticFieldLeak")
object SeekBarPopUtils {

    private var popWin: PopupWindow? = null
    private var clPopPar: ConstraintLayout? = null
    private var tvPopTxt: TextView? = null

    fun showPop(seekBar: SeekBar){
        popWin = PopupWindow()
        val mPopView = LayoutInflater.from(BaseApplication.getContext()).inflate(R.layout.item_popup_win,null,false)
        clPopPar = mPopView.findViewById<ConstraintLayout>(R.id.cl_pop_par)
        tvPopTxt = mPopView.findViewById<TextView>(R.id.tv_pop_txt)

        popWin?.contentView = mPopView
        popWin?.height = AppHelper.dp2px(30)
        popWin?.width = seekBar.width
        popWin?.showAsDropDown(seekBar,0,-(AppHelper.dp2px(30) + popWin!!.height))
    }


    fun move(progress: Int,seekBar: SeekBar){
        if (clPopPar != null){
            val tvPopWidth = AppHelper.dp2px(40)
            val params: ConstraintLayout.LayoutParams = ConstraintLayout.LayoutParams(
                tvPopWidth, AppHelper.dp2px(30)
            )
            params.startToStart = clPopPar!!.id
            params.marginStart = (seekBar.width - tvPopWidth)/100 * progress + tvPopWidth/3
            tvPopTxt?.layoutParams = params

            tvPopTxt?.text = progress.toString()
        }
    }


    fun dismiss(){
        popWin?.dismiss()
        popWin = null
        clPopPar = null
        tvPopTxt = null
    }

}

SeekBarPopUtils (Java)

public class SeekBarPopUtils {
    
    

    private static PopupWindow popWin = null;
    private static ConstraintLayout clPopPar = null;
    private static TextView tvPopTxt = null;

    public static void showPop(SeekBar seekBar){
    
    
        popWin = new PopupWindow();
        View mPopView = LayoutInflater.from(App.getInstance().getBaseContext()).inflate(R.layout.item_popup_win,null,false);
        clPopPar = mPopView.findViewById(R.id.cl_pop_par);
        tvPopTxt = mPopView.findViewById(R.id.tv_pop_txt);
        popWin.setContentView(mPopView);
        popWin.setHeight(dp2px(30));
        popWin.setWidth(seekBar.getWidth());
        popWin.showAsDropDown(seekBar,0,-(dp2px(30) + popWin.getHeight()));
    }


    public static void move(int progress,SeekBar seekBar){
    
    
        if (clPopPar != null){
    
    
            int tvPopWidth = dp2px(40);
            ConstraintLayout.LayoutParams params  = new ConstraintLayout.LayoutParams(
                    tvPopWidth, dp2px(30)
            );
            params.startToStart = clPopPar.getId();
            params.setMarginStart((seekBar.getWidth() - tvPopWidth)/100 * progress + tvPopWidth/3);
            tvPopTxt.setLayoutParams(params);

            tvPopTxt.setText(progress + "");
        }
    }

    private static int dp2px(int dpVal){
    
    
        return (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP,
                (float) dpVal,
                App.getInstance().getBaseContext().getResources().getDisplayMetrics()
        );
    }

    public static void dismiss(){
    
    
        popWin.dismiss();
        popWin = null;
        clPopPar = null;
        tvPopTxt = null;
    }
}

item_popup_win コード

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/cl_pop_par"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <TextView
        android:id="@+id/tv_pop_txt"
        android:layout_width="40dp"
        android:layout_height="match_parent"
        android:gravity="center"
        app:layout_constraintStart_toStartOf="parent"
        android:background="@drawable/bg_ffffff_12"
        android:textSize="16sp"
        android:textColor="#000000"
        tools:text = "999"/>

</androidx.constraintlayout.widget.ConstraintLayout>

bg_ffffff_12

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:ignore="ResourceName">
    <solid android:color="#FFFFFF" />
    <corners android:radius="12dp" />
</shape>

AppHelper.dp2px

    fun dp2px(dpVal: Int): Int {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            dpVal.toFloat(),
            BaseApplication.getContext().resources.displayMetrics
        ).toInt()
    }

おすすめ

転載: blog.csdn.net/As_thin/article/details/132182464