Android P SystemUI 添加自定义垂直SeekBar控件,带监听事件

将定义水平seekbar旋转-90度, 直接上代码

package com.android.systemui.statusbar.car.hvac;
import android.widget.SeekBar;
import android.content.Context;
import android.graphics.Canvas;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.annotation.SuppressLint;
import android.content.res.TypedArray;
import android.util.Log;

import com.android.systemui.R;
import com.android.systemui.Dependency;


public class CarVerticalSeekBar extends SeekBar implements HvacSeekBar, HvacComponent {
    private static final String TAG = "CarVerticalSeekBar";
    private static final boolean DEBUG = true;

    private OnSeekBarChangeListener mOnSeekBarChangeListener;
    private final int mAreaId;
    private final int mPropertyId;
    private final int mHvacOffset;
    private final int mLastPostion;

    public CarVerticalSeekBar(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CarVerticalSeekBar);
        try {
            mAreaId = typedArray.getInt(R.styleable.CarVerticalSeekBar_hvacAreaId, -1);
            mPropertyId = typedArray.getInt(R.styleable.CarVerticalSeekBar_hvacPropertyId, -1);
            mHvacOffset = typedArray.getInt(R.styleable.CarVerticalSeekBar_hvacOffset, -1);
        } finally {
            typedArray.recycle();
        }
        if (DEBUG) {
            Log.i(TAG, "mAreaId :" + mAreaId);
            Log.i(TAG, "mPropertyId :" + mPropertyId);
        }
        // register with controller
        HvacController hvacController = Dependency.get(HvacController.class);
        hvacController.addHvacView(this, true);
        mLastPostion = getProgress();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.rotate(-90);
        canvas.translate(-getHeight(), 0);
        super.onDraw(canvas);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = getMeasuredHeight();
        int height = getMeasuredWidth();
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(h, w, oldh, oldw);
    }

    public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {
        mOnSeekBarChangeListener = l;
    }

    private void onStartTrackingTouch() {
        if (mOnSeekBarChangeListener != null) {
            mOnSeekBarChangeListener.onStartTrackingTouch(this);
        }
    }

    private void onStopTrackingTouch() {
        if (mOnSeekBarChangeListener != null) {
            mOnSeekBarChangeListener.onStopTrackingTouch(this);
        }
    }
    private void onProgressChanged() {
        if (mOnSeekBarChangeListener != null) {
            int progress = getProgress();
            //Log.i("tag", "yong  onProgressChanged ACTION_MOVE");
            mOnSeekBarChangeListener.onProgressChanged(this, progress, false);
        }
    }
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) return false;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                setPressed(true);
                onStartTrackingTouch();
                break;
            case MotionEvent.ACTION_MOVE:
                onProgressChanged();
                int progress = getMax() - (int) (getMax() * event.getY() / getHeight());
                setProgress(progress);
                onSizeChanged(getWidth(), getHeight(), 0, 0);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                onStopTrackingTouch();
                setPressed(false);
                break;
        }
        return true;
    }

    @Override
    public int getPropertyId() {
        return mPropertyId;
    }

    @Override
    public int getAreaId() {
        return mAreaId;
    }

    @Override
    public void setTemp(float temp) {
        if(DEBUG) {
            Log.i(TAG, "setTemp temp: " + temp);
        }
        int value =  ((int)temp) - mHvacOffset;
        setProgress((int)value);
    }

    @Override
    public float getTemp() {
        return 0;
    }
    public int getHvacOffset(){
        return mHvacOffset;
    }
}

xml中引用

<com.android.systemui.statusbar.car.hvac.CarVerticalSeekBar
        android:id="@+id/navi_seek"
        android:layout_width="320dp"
        android:layout_height="80dp"
        android:layout_marginTop="-5dp"
        android:min="0"
		android:max="16"
        systemui:hvacOffset="16"
        android:progressDrawable="@drawable/seekbar_bg"
        systemui:hvacAreaId="49"
		systemui:hvacPropertyId="358614275"
		android:splitTrack="false"
		android:background="@null"
		android:maxHeight="70dp"
		android:thumb="@drawable/systemui_slider_label_80x30"/>

这里遇到一个问题,在拖动滑块时,会再水平方向上多出一个灰色圆形小球。
添加下面配置修正,android:splitTrack="false"这个说是修改滑块透明度的,未验证

android:background="@null"
android:splitTrack="false"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SeekBarAndroid中的一个自定义控件,它允许用户通过滑动来选择一个数值。你可以在XML布局文件中声明一个SeekBar控件,并通过代码来获取和设置其值。 要创建一个自定义SeekBar控件,你可以继承SeekBar类,并重写一些方法来实现自定义的行为。以下是一个示例: ```java public class CustomSeekBar extends SeekBar { public CustomSeekBar(Context context) { super(context); } public CustomSeekBar(Context context, AttributeSet attrs) { super(context, attrs); } public CustomSeekBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public synchronized void setProgress(int progress) { // 在设置进度之前进行一些自定义操作 // 例如限制进度的范围或者改变进度条的外观 super.setProgress(progress); } @Override public synchronized void onProgressChanged(int progress, boolean fromUser) { super.onProgressChanged(progress, fromUser); // 当进度发生改变时的处理逻辑 // 可以根据进度值做出相应的响应 } } ``` 在这个示例中,我们重写了`setProgress()`方法和`onProgressChanged()`方法来实现自定义行为。你可以根据自己的需求进行修改和扩展。 在布局文件中使用自定义SeekBar控件时,需要指定完整的自定义控件的类名,例如: ```xml <com.example.app.CustomSeekBar android:id="@+id/customSeekBar" android:layout_width="match_parent" android:layout_height="wrap_content" /> ``` 这样就可以在代码中获取到这个自定义SeekBar控件,并对其进行操作了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值