zoukankan      html  css  js  c++  java
  • 客户定制 音量控制 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>
    
    
  • 相关阅读:
    c#基础练习
    一款很厉害的死循环代码
    文字变色逐个出现的特效源码
    IOS开发之UILabel动态高度设置方法
    慎重选择容器类型
    Mac下显示隐藏文件 以及修改 hosts文件内容
    SharePoint 如何使自己的网页自动跳转
    位置和地图:地图的使用
    谈话Java在ThreadLocal理解类
    Android 滑动界面实现---Scroller类别 从源代码和开发文档了解(让你的移动布局)
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3071914.html
Copyright © 2011-2022 走看看