Android 自定义 SeekBarPreference 控件

本文介绍了如何在Android的PreferenceScreen布局中自定义SeekbarPreference控件,特别是在创建设置模块时,由于系统未提供此类控件,因此需要进行自定义。通过实现OnSeekBarChangeListener和OnKeyListener接口,创建SeekBarPreferenceVolume类来实现音量调节功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 PreferenceScreen 布局里面,特别是做Android系统应用的同学们,比如Settings模块,会用到PreferenceScreen,但是Android又没有PreferenceScreen控件,所以就必须自定义,今天就和大家分享一下

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen android:title="@string/voice_assistant"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference 
        android:persistent="false" 
        android:title="@string/voice_assistant" 
        android:key="voice_assistant" 
        android:summaryOn="@string/voice_assistant_on" 
        android:summaryOff="@string/voice_assistant_off" 
        android:selectable="true"
        />
         <!-- 新添加这个控件 -->
         <com.android.settings.SeekBarPreferenceVolume
            android:key="ring_volume"
            android:layout="@layout/ring_volume_prefs"            
            />
</PreferenceScreen>

ring_volume_prefs.xml
`<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="horizontal" >

<TextView 
    android:id="@+id/volume_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/all_volume_title"
android:layout_marginTop="3dp"
        />

    <SeekBar 
    android:id="@+id/volume_seekbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
android:layout_marginTop="8dp"
        />

</LinearLayout>

package com.android.settings;

import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.Preference;
import android.util.AttributeSet;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.view.View;
import android.app.Activity;
import android.view.KeyEvent;
import android.media.AudioManager;
import android.view.View.OnKeyListener;

// 添加调节音量的 SeekBar
public class SeekBarPreferenceVolume extends Preference implements OnSeekBarChangeListener, OnKeyListener{

    private TextView value;
    private int mProgress;
    private int mMax = 10000;
    private boolean mTrackingTouch;
    private OnSeekBarPrefsChangeListener mListener = null;
    private int max;
    private int current;
    private Context mContext;
    private AudioManager mAudioManager;
    private SeekBar seekBar;
    private int nowVolume;
    private VoiceAssistantSettings voiceAssistantSettings;

public SeekBarPreferenceVolume(Context context, AttributeSet attrs,
        int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    mContext = context;
    setLayoutResource(R.layout.ring_volume_prefs);
}

public SeekBarPreferenceVolume(Context context, AttributeSet attrs) {
    super(context, attrs,0);
    mContext = context;
}


public SeekBarPreferenceVolume(Context context) {
    super(context,null);
    mContext = context;
}

public void getAudiosize(){
    mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
    max = mAudioManager.getStreamMaxVolume( AudioManager.STREAM_SYSTEM );
    current = mAudioManager.getStreamVolume( AudioManager.STREAM_SYSTEM );
}

public void onProgressChanged(SeekBar seekBar, int progress,
        boolean fromUser) {
    if (mListener != null) {
        mListener.onProgressChanged(getKey(),seekBar, progress, fromUser);
    }
    if (seekBar.getProgress() != mProgress) {
        syncProgress(seekBar);
    }
    if (fromUser && !mTrackingTouch) {
        syncProgress(seekBar);
    }

}

public void onStartTrackingTouch(SeekBar seekBar) {
    if (mListener != null) {
        mListener.onStartTrackingTouch(getKey(),seekBar);
    }
    mTrackingTouch = true;

}

public void onStopTrackingTouch(SeekBar seekBar) {
    if (mListener != null) {
        mListener.onStopTrackingTouch(getKey(),seekBar);
    }
    mTrackingTouch = false;
    if (seekBar.getProgress() != mProgress) {
        syncProgress(seekBar);
    }
    notifyHierarchyChanged();

}

public void setMax(int max) {
    if (max != mMax) {
        mMax = max;
        notifyChanged();
    }
}

@Override
protected Parcelable onSaveInstanceState() {
 final Parcelable superState = super.onSaveInstanceState();
    if (isPersistent()) {
        return superState;
    }

    final SavedState myState = new SavedState(superState);
    myState.progress = mProgress;
    myState.maxs = mMax;
    return myState;     
}

@Override
protected void onBindView(View view) {
    super.onBindView(view);
     getAudiosize();
    seekBar = (SeekBar) view.findViewById(R.id.volume_seekbar);
    seekBar.setMax(max);
    seekBar.setProgress(current);
    seekBar.setEnabled(isEnabled());
    seekBar.setOnSeekBarChangeListener(this);
    value = (TextView)view.findViewById(R.id.volume_text);
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
    if (!state.getClass().equals(SavedState.class)) {
        super.onRestoreInstanceState(state);
        return;
    }

    SavedState myState = (SavedState) state;
    super.onRestoreInstanceState(myState.getSuperState());
    mProgress = myState.progress;

    mMax = myState.maxs;
    notifyChanged();
}

public void setDefaultProgressValue(int defaultValue) {
    if(getPersistedInt(-1) == -1) {

        setProgress(defaultValue);
    }
}

public void setProgress(int progress) {
    setProgress(progress, true);
}

private void setProgress(int progress, boolean notifyChanged) {
    if (progress > mMax) {
        progress = mMax;
    }
    if (progress < 0) {
        progress = 0;
    }
    if (progress != mProgress) {
        mProgress = progress;
        persistInt(progress);
        if (notifyChanged) {
            notifyChanged();
        }
    }
}

 public int getProgress() {
    return mProgress;
}


 public void setOnSeekBarPrefsChangeListener(OnSeekBarPrefsChangeListener listener) {
    mListener = listener;
}

public interface OnSeekBarPrefsChangeListener {
    public void onStopTrackingTouch(String key ,SeekBar seekBar) ;
    public void onStartTrackingTouch(String key ,SeekBar seekBar);
    public void onProgressChanged(String key ,SeekBar seekBar, int progress,boolean fromUser);
}

void syncProgress(SeekBar seekBar) {
    int progress = seekBar.getProgress();
    if (progress != mProgress) {
        if (callChangeListener(progress)) {
            setProgress(progress, false);
        } else {
            seekBar.setProgress(mProgress);
        }
    }
}


private static class SavedState extends BaseSavedState {

    int progress;
    int maxs;

    public SavedState(Parcel source) {
        super(source);
        progress = source.readInt();
        maxs = source.readInt();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeInt(progress);
        dest.writeInt(maxs);
    }

    public SavedState(Parcelable superState) {
        super(superState);
    }

}

public void getVoiceAssistantSettings(VoiceAssistantSettings voiceAss){
    voiceAssistantSettings = voiceAss;
}

public boolean onKey(View v, int keyCode, KeyEvent event) {

    switch (keyCode) {
    case KeyEvent.KEYCODE_DPAD_LEFT:
         if(current != 0){
         current--;
          }
         seekBar.setProgress(current);
         mAudioManager.setStreamVolume(AudioManager.STREAM_SYSTEM, current, 0); 
         nowVolume = mAudioManager.getStreamMaxVolume( AudioManager.STREAM_SYSTEM );         
        break;

     case KeyEvent.KEYCODE_DPAD_RIGHT:
     if(current != max){
         current++;
     }
          seekBar.setProgress(current);
         mAudioManager.setStreamVolume(AudioManager.STREAM_SYSTEM, current, 0); 
         nowVolume = mAudioManager.getStreamMaxVolume( AudioManager.STREAM_SYSTEM );
        break;  

    case KeyEvent.KEYCODE_DPAD_UP:

        return false;   

    case KeyEvent.KEYCODE_DPAD_DOWN:

        return false;           

    case KeyEvent.KEYCODE_BACK:
          Activity act = (Activity)mContext;
        act.finish();
        return true;

    default:
        break;
    }
    return true;
}

}
“`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值