Android开发自定义双向SeekBar拖动条控件

下面就给大家详细讲解一下“Android开发自定义双向SeekBar拖动条控件的完整攻略”。

1. 开发自定义双向SeekBar的前期准备

在开始开发自定义双向SeekBar之前,我们需要先进行一些前期准备工作:

  1. 创建一个新的Android项目;
  2. 在项目的build.gradle文件中添加如下依赖:

implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'

  1. res/values/attrs.xml文件中添加自定义属性:

<attr name="left_progress" format="integer"/>
<attr name="right_progress" format="integer"/>
<attr name="max" format="integer"/>
<attr name="progress_color" format="color"/>

2. 开发自定义双向SeekBar的布局文件

接着,我们可以开始开发自定义双向SeekBar的布局文件。在res/layout目录下创建一个custom_seek_bar.xml文件,并添加如下代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/left_progress_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/black"
        android:textSize="16sp"/>

    <SeekBar
        android:id="@+id/seek_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="@integer/max_seek_bar"
        android:progressDrawable="@drawable/custom_seek_bar_background"
        android:thumb="@drawable/custom_seek_bar_thumb"/>

    <TextView
        android:id="@+id/right_progress_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/black"
        android:textSize="16sp"/>

</LinearLayout>

接着,我们需要分别开发自定义的SeekBar背景和thumb资源文件。

3. 开发自定义背景资源文件

res/drawable目录下创建一个custom_seek_bar_background.xml文件,并添加如下代码:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />
            <corners android:radius="8dp" />
            <stroke
                android:width="1dp"
                android:color="@color/black"/>
        </shape>
    </item>

    <item android:id="@android:id/progress">
        <clip>
            <shape android:shape="rectangle">    
                <size android:height="4dp" />
                <solid android:color="@color/custom_seek_bar_color" />
                <corners android:radius="8dp" />
            </shape>
        </clip>
    </item>

</layer-list>

4. 开发自定义thumb资源文件

res/drawable目录下创建一个custom_seek_bar_thumb.xml文件,并添加如下代码:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <size android:width="24dp" android:height="24dp" />

    <solid android:color="@color/custom_seek_bar_color" />

</shape>

5. 开发自定义SeekBar控件

最后,我们需要新建一个名为CustomSeekBar的Java类,该类继承自LinearLayout

public class CustomSeekBar extends LinearLayout {

    private SeekBar seekBar;
    private TextView leftProgressText;
    private TextView rightProgressText;

    private int max;
    private int leftProgress;
    private int rightProgress;
    private int progressColor;

    public CustomSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.custom_seek_bar, this, true);

        seekBar = findViewById(R.id.seek_bar);
        leftProgressText = findViewById(R.id.left_progress_text);
        rightProgressText = findViewById(R.id.right_progress_text);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomSeekBar);
        max = a.getInt(R.styleable.CustomSeekBar_max, 100);
        leftProgress = a.getInt(R.styleable.CustomSeekBar_left_progress, 0);
        rightProgress = a.getInt(R.styleable.CustomSeekBar_right_progress, max);
        progressColor = a.getColor(R.styleable.CustomSeekBar_progress_color, ContextCompat.getColor(context, R.color.custom_seek_bar_color));
        a.recycle();

        seekBar.setMax(max);
        seekBar.setProgressDrawable(ContextCompat.getDrawable(context, R.drawable.custom_seek_bar_background));
        seekBar.setThumb(ContextCompat.getDrawable(context, R.drawable.custom_seek_bar_thumb));

        updateProgress(leftProgress, rightProgress);

        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser) {
                    if (progress <= leftProgress) {
                        updateProgress(progress, rightProgress);
                    } else {
                        updateProgress(leftProgress, progress);
                    }
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }

    private void updateProgress(int leftProgress, int rightProgress) {
        this.leftProgress = leftProgress;
        this.rightProgress = rightProgress;

        seekBar.setProgressDrawable(getSeekBarDrawable());

        leftProgressText.setText(String.valueOf(leftProgress));
        rightProgressText.setText(String.valueOf(rightProgress));
    }

    private Drawable getSeekBarDrawable() {
        Bitmap bitmap = Bitmap.createBitmap(seekBar.getWidth(), seekBar.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);

        // draw left progress
        Paint leftPaint = new Paint();
        leftPaint.setColor(progressColor);
        RectF leftRect = new RectF(0, 0, getProgressWidth(leftProgress), seekBar.getHeight());
        canvas.drawRect(leftRect, leftPaint);

        // draw right progress
        Paint rightPaint = new Paint();
        rightPaint.setColor(progressColor);
        RectF rightRect = new RectF(getProgressWidth(leftProgress), 0, seekBar.getWidth(), seekBar.getHeight());
        canvas.drawRect(rightRect, rightPaint);

        // draw thumb
        Drawable thumbDrawable = seekBar.getThumb();
        int thumbX = (int) (getProgressWidth(leftProgress) - (thumbDrawable.getIntrinsicWidth() / 2.0f));
        int thumbY = seekBar.getHeight() / 2 - thumbDrawable.getIntrinsicHeight() / 2;

        canvas.translate(thumbX, thumbY);
        thumbDrawable.draw(canvas);

        return new BitmapDrawable(getResources(), bitmap);
    }

    private int getProgressWidth(int progress) {
        int progressBarWidth = seekBar.getWidth() - seekBar.getPaddingLeft() - seekBar.getPaddingRight();
        float ratio = (float) (progress - seekBar.getMin()) / (float) (seekBar.getMax() - seekBar.getMin());
        return (int) (ratio * progressBarWidth);
    }

    public int getLeftProgress() {
        return leftProgress;
    }

    public int getRightProgress() {
        return rightProgress;
    }

}

以上就是开发一个自定义双向SeekBar拖动条控件的完整攻略,下面给出一个使用示例。

示例

在布局文件中使用自定义SeekBar:

<com.example.customseekbar.CustomSeekBar
    android:id="@+id/custom_seek_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:left_progress="20"
    app:right_progress="80"
    app:max="100"
    app:progress_color="@color/custom_seek_bar_color"/>

在代码中获取自定义SeekBar的左右进度值:

CustomSeekBar customSeekBar = findViewById(R.id.custom_seek_bar);
int leftProgress = customSeekBar.getLeftProgress();
int rightProgress = customSeekBar.getRightProgress();

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android开发自定义双向SeekBar拖动条控件 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • Ubuntu10下如何搭建MySQL Proxy读写分离探讨

    以下是在Ubuntu 10下搭建MySQL Proxy读写分离的详细攻略: 安装MySQL Proxy: 在Ubuntu 10上安装MySQL Proxy软件包。可以使用以下命令进行安装: sudo apt-get install mysql-proxy 配置MySQL Proxy: 创建MySQL Proxy的配置文件。可以使用以下命令创建一个名为prox…

    other 2023年10月17日
    00
  • Python运算符优先级详细整理

    Python运算符优先级详细整理 在Python中,运算符的优先级会影响表达式的计算顺序。了解运算符的优先级对于正确理解和编写代码非常重要。下面是Python运算符的优先级从高到低的详细整理。 1. 一元运算符 一元运算符作用于单个操作数。- -x:取反- +x:正数标识符 2. 幂运算符 幂运算符是计算幂的操作符。- **:计算幂 3. 乘法、除法、取余和…

    other 2023年6月28日
    00
  • 魔兽世界6.2防骑属性优先级 输出循环玩法心得分享

    魔兽世界6.2防骑属性优先级 输出循环玩法心得分享 简介 在6.2版本的魔兽世界中,想要在PK和PVE中获胜的关键是选择合适的属性。本攻略将详细讲解防骑属性的优先级,以及输出循环玩法的心得分享。 防骑属性优先级 在PK和PVE中,防骑是一个关键属性。在选择装备和宝石时,需要考虑以下属性的优先级: 韧性 物理防御 法术防御 生命值 韧性可以增加对魔法和物理技能…

    other 2023年6月27日
    00
  • Linux下使用killall命令终止进程的8大用法实例详解

    Linux下使用killall命令终止进程的8大用法实例详解 在Linux操作系统中,经常需要终止某些进程,而killall命令则是比较常用的一种终止进程的方法。本文将详细介绍killall命令的8大用法实例,帮助用户更好地掌握killall命令的各种用法。 1. 简单的killall命令 killall命令的最基本用法就是通过指定要终止的进程名称,来结束所…

    other 2023年6月26日
    00
  • linux常见配置文件

    以下是“Linux常见配置文件的完整攻略”的标准markdown格式文本,其中包含了两个示例说明: Linux常见配置文件 Linux系统中有许多配置文件,这些文件用于配置系统和应用程序的行为。本文将介绍Linux系统中常见的配置文件,包括如何使用和示例说明。 1. /etc/passwd /etc/passwd文件是Linux系统中存储用户信息的文件。每个…

    other 2023年5月10日
    00
  • 编程之显示/隐式声明

    编程之显示/隐式声明攻略 在编程中,声明是指为变量或函数分配内存空间并指定其类型和名称的过程。显示声明是明确地指定变量或函数的类型和名称,而隐式声明是根据上下文推断变量或函数的类型。 显示声明 显示声明是通过使用关键字来明确指定变量或函数的类型和名称。以下是一些常见的显示声明的示例: 显示声明变量 # 显示声明整数变量 num1: int = 10 # 显示…

    other 2023年8月16日
    00
  • centOS下yum安装配置samba

    CentOS下yum安装配置samba Samba是一项实现了Windows和Linux/Unix之间文件和打印机共享的服务。如果你有Linux和Windows机器在同一局域网内,那么在CentOS上安装和配置Samba是非常有用的,可以方便地在Windows上访问Linux文件。 1. 安装Samba 使用 yum 命令直接在CentOS系统中安装Samb…

    其他 2023年3月28日
    00
  • linux中如何安装rar

    Linux中如何安装rar 在Linux中安装rar工具可以帮助我们解压缩rar格式的压缩文件,同时也可以压缩文件为rar格式。本文将简要介绍如何在Linux上安装rar工具。 步骤一:确认系统是否已经安装rar 在安装rar之前,我们需要确定系统是否已经安装了rar。我们可以通过执行以下命令查看系统中是否已经安装了rar: which rar 如果系统已经…

    其他 2023年3月29日
    00
合作推广
合作推广
分享本页
返回顶部