客户定制 音量控制 Preference

参考网上代码自己做了一个客户定制 Preference,没有使用 preference的 android:layout 属性,因为总觉得在不同版本系统上难以和其他preference的控件对齐,所以采用仅设置 android:widget_layout 的方式。

先创建自己要定制的 widget_layout 文件“preference_widget_seekbar.xml”:

 

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:gravity="center_vertical"

    android:minHeight="?android:attr/listPreferredItemHeight"

    android:paddingRight="?android:attr/scrollbarSize" >



    <SeekBar

        android:id="@+id/seekBar1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:max="60"

        android:minWidth="240dip"

        android:paddingRight="5dp"

        android:progress="20"

        android:textIsSelectable="true" >

    </SeekBar>

    

    <TextView

        android:id="@+id/seekBarPrefValue"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_below="@id/seekBar1"

        android:layout_centerHorizontal="true"

        android:textIsSelectable="true" >

	</TextView>

	

    <TextView

        android:id="@+id/seekBarPrefUnitsLeft"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_below="@id/seekBar1"

        android:layout_toLeftOf="@id/seekBarPrefValue"

        android:textIsSelectable="true" >

	</TextView>



    <TextView

        android:id="@+id/seekBarPrefUnitsRight"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:textIsSelectable="true"

        android:layout_below="@id/seekBar1" 

        android:layout_toRightOf="@id/seekBarPrefValue" >

	</TextView>



</RelativeLayout>

 

 

建立 com.sample.preference.SeekBarPreference 类,用来初始化界面,同步音量滑块表示的preference数据

 

package com.sample.preference;



import com.sample.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 = "SeekBarPreference";

    

    //private static final String ANDROIDNS="http://schemas.android.com/apk/res/android";

    private static final String SEEKBAR_PREFS="SeekBarPreference";

    private static final int DEFAULT_VALUE = 50;

    

    Context mContext;

	private int mMaxValue      = 100;

	private int mMinValue      = 0;

	private int mInterval      = 1;

	private int mCurrentValue  = 50;

	private String mUnitsLeft  = "";

	private String mUnitsRight = "";

	private SeekBar mSeekBar;

    

	private TextView mCurrentValueText;



    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) {

    	Log.v(TAG,"initPreference");

    	mContext = context;

        updateValuesFromXml(attrs);

        this.setWidgetLayoutResource(R.layout.preference_widget_seekbar);

    }

    

    private void updateValuesFromXml(AttributeSet attrs) {

        mMaxValue = attrs.getAttributeIntValue(SEEKBAR_PREFS, "max", 100);

        mMinValue = attrs.getAttributeIntValue(SEEKBAR_PREFS, "min", 0);

       

        mUnitsLeft = getAttributeStringValue(attrs, SEEKBAR_PREFS, "unitsLeft", "");

        String value = getAttributeStringValue(attrs, SEEKBAR_PREFS, "value", "");

        mUnitsRight = getAttributeStringValue(attrs, SEEKBAR_PREFS, "unitsRight", "");

        

        try {

        	mInterval = attrs.getAttributeIntValue(SEEKBAR_PREFS, "interval", 1);

            if( mInterval <= 0 )

            {

            	mInterval = 1;

            }

        }

        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){

    	Log.v(TAG, "onCreateView()");

        return super.onCreateView(parent);

    }

    

    @Override

    public void onBindView(View view) {

        super.onBindView(view);

        

        View layout = view;



        Log.v(TAG, "onBindView()");

        mSeekBar = (SeekBar)view.findViewById(R.id.seekBar1);

        mCurrentValueText = (TextView)view.findViewById(R.id.seekBarPrefValue);

        if( null != mCurrentValueText ){

        	mCurrentValueText.setText(String.valueOf(mCurrentValue));

        	mCurrentValueText.setMinimumWidth(30);

        }

        if( null != mSeekBar )

        {

        	mSeekBar.setMax(mMaxValue - mMinValue);

        	mSeekBar.setProgress(mCurrentValue - mMinValue);

        	mSeekBar.setOnSeekBarChangeListener(this);

        }



        TextView unitsRight = (TextView)view.findViewById(R.id.seekBarPrefUnitsRight);

        if( null != unitsRight ){

        	unitsRight.setText(mUnitsRight);

        }

        

        TextView unitsLeft = (TextView)view.findViewById(R.id.seekBarPrefUnitsLeft);

        if( null != unitsLeft ){

        	unitsLeft.setText(mUnitsLeft);  

        }



    }

    

    @Override

    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( null != mCurrentValueText ){

        	mCurrentValueText.setText(String.valueOf(newValue));

        }

        persistInt(newValue);



    }



    @Override

    public void onStartTrackingTouch(SeekBar seekBar) {}



    @Override

    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;

        }

        

    }

    

} 

 

 

最后,在preference xml中加入对应项

 

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"

	android:title="audioSetting">

	<!-- ... 其他 preference 项 -->



	<com.sample.preference.SeekBarPreference

	    android:key="key_nes_volume_option" 

	    android:title="volumeSetting" 

	    android:summary="volumeSettingSummary" />	



	<!-- ... 其他 preference 项 -->	
</PreferenceScreen>


                            

你可能感兴趣的:(Preference)