Android没有提供SeekBarPreference,所以只有自己写一个了。。
SeekBarPreference.java
package com.sheng00.BatteryStatus; import com.sheng00.BattaryStatus.R; import android.content.Context; import android.content.res.TypedArray; import android.preference.Preference; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; public class SeekBarPreference extends Preference implements OnSeekBarChangeListener { private final String TAG = getClass().getName(); private static final String ANDROIDNS="http://schemas.android.com/apk/res/android"; private static final String SHENG00NS="http://sheng00.com"; private static final int DEFAULT_VALUE = 50; private int mMaxValue = 100; private int mMinValue = 0; private int mInterval = 1; private int mCurrentValue; private String mUnitsLeft = ""; private String mUnitsRight = ""; private SeekBar mSeekBar; private TextView mStatusText; public SeekBarPreference(Context context, AttributeSet attrs) { super(context, attrs); initPreference(context, attrs); } public SeekBarPreference(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initPreference(context, attrs); } private void initPreference(Context context, AttributeSet attrs) { setValuesFromXml(attrs); mSeekBar = new SeekBar(context, attrs); mSeekBar.setOnSeekBarChangeListener(this); mSeekBar.setMax(mMaxValue - mMinValue); } private void setValuesFromXml(AttributeSet attrs) { mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", 100); mMinValue = attrs.getAttributeIntValue(SHENG00NS, "min", 0); mUnitsLeft = getAttributeStringValue(attrs, SHENG00NS, "unitsLeft", ""); String units = getAttributeStringValue(attrs, SHENG00NS, "units", ""); mUnitsRight = getAttributeStringValue(attrs, SHENG00NS, "unitsRight", units); try { String newInterval = attrs.getAttributeValue(SHENG00NS, "interval"); if(newInterval != null) mInterval = Integer.parseInt(newInterval); } catch(Exception e) { Log.e(TAG, "Invalid interval value", e); } } private String getAttributeStringValue(AttributeSet attrs, String namespace, String name, String defaultValue) { String value = attrs.getAttributeValue(namespace, name); if(value == null) value = defaultValue; return value; } @Override protected View onCreateView(ViewGroup parent){ RelativeLayout layout = null; try { LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); layout = (RelativeLayout)mInflater.inflate(R.layout.seek_bar_preference, parent, false); } catch(Exception e) { Log.e(TAG, "Error creating seek bar preference", e); } return layout; } @Override public void onBindView(View view) { super.onBindView(view); try { // move our seekbar to the new view we've been given ViewParent oldContainer = mSeekBar.getParent(); ViewGroup newContainer = (ViewGroup) view.findViewById(R.id.seekBarPrefBarContainer); if (oldContainer != newContainer) { // remove the seekbar from the old view if (oldContainer != null) { ((ViewGroup) oldContainer).removeView(mSeekBar); } // remove the existing seekbar (there may not be one) and add ours newContainer.removeAllViews(); newContainer.addView(mSeekBar, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } } catch(Exception ex) { Log.e(TAG, "Error binding view: " + ex.toString()); } updateView(view); } /** * Update a SeekBarPreference view with our current state * @param view */ protected void updateView(View view) { try { RelativeLayout layout = (RelativeLayout)view; mStatusText = (TextView)layout.findViewById(R.id.seekBarPrefValue); mStatusText.setText(String.valueOf(mCurrentValue)); mStatusText.setMinimumWidth(30); mSeekBar.setProgress(mCurrentValue - mMinValue); mSeekBar.setEnabled(this.isEnabled()); TextView unitsRight = (TextView)layout.findViewById(R.id.seekBarPrefUnitsRight); unitsRight.setText(mUnitsRight); TextView unitsLeft = (TextView)layout.findViewById(R.id.seekBarPrefUnitsLeft); unitsLeft.setText(mUnitsLeft); } catch(Exception e) { Log.e(TAG, "Error updating seek bar preference", e); } } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { int newValue = progress + mMinValue; if(newValue > mMaxValue) newValue = mMaxValue; else if(newValue < mMinValue) newValue = mMinValue; else if(mInterval != 1 && newValue % mInterval != 0) newValue = Math.round(((float)newValue)/mInterval)*mInterval; // change rejected, revert to the previous value if(!callChangeListener(newValue)){ seekBar.setProgress(mCurrentValue - mMinValue); return; } // change accepted, store it mCurrentValue = newValue; if (mStatusText != null) { mStatusText.setText(String.valueOf(newValue)); } persistInt(newValue); } public void onStartTrackingTouch(SeekBar seekBar) {} public void onStopTrackingTouch(SeekBar seekBar) { notifyChanged(); } @Override protected Object onGetDefaultValue(TypedArray ta, int index){ int defaultValue = ta.getInt(index, DEFAULT_VALUE); return defaultValue; } @Override protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { if(restoreValue) { mCurrentValue = getPersistedInt(mCurrentValue); } else { int temp = 0; try { temp = (Integer)defaultValue; } catch(Exception ex) { Log.e(TAG, "Invalid default value: " + defaultValue.toString()); } persistInt(temp); mCurrentValue = temp; } } }
这时需要在layout里写布局文件
seek_bar_preference.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/widget_frame"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:paddingTop="5dp"
android:paddingRight="10dp"
android:paddingBottom="5dp"
>
<TextView android:id="@android:id/title"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="22dp"
android:typeface="sans"
android:textStyle="normal"
android:textColor="#ffffff"
></TextView>
<TextView android:id="@android:id/summary"
android:layout_alignParentLeft="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@android:id/title"
></TextView>
<TextView android:id="@+id/seekBarPrefUnitsRight"
android:layout_alignParentRight="true"
android:layout_below="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
></TextView>
<TextView android:id="@+id/seekBarPrefValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/seekBarPrefUnitsRight"
android:layout_below="@android:id/title"
android:gravity="right"
></TextView>
<TextView android:id="@+id/seekBarPrefUnitsLeft"
android:layout_below="@android:id/title"
android:layout_toLeftOf="@id/seekBarPrefValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
></TextView>
<LinearLayout android:id="@+id/seekBarPrefBarContainer"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@android:id/summary">
</LinearLayout>
</RelativeLayout>
然后可以写进我们的activity的布局文件里了:
<com.sheng00.batterystatus.seekbarpreference
sheng00:unitsright="%"
sheng00:unitsleft=""
android:dependency="@string/low_alert_checkbox"
android:summary=" "
android:title="@string/low_alert_level"
sheng00:min="1"
android:max="50"
android:key="@string/low_alert_level_key"
android:defaultvalue="15" />