2011-01-09 63 views
3

我有一个preferences.xml文件,其中包含一些复选框首选项,自定义时间选择器首选项和自定义SeekBar首选项。在我的2.2模拟器中一切正常。我试着在1.6模拟器中运行它,并且每次调整其中一个滑块(SeekBar首选项)或更改其他首选项时,SeekBar首选项会更改位置。就像他们只是洗牌一样。任何人都知道我能如何阻止它? 这使我无法进行分组,因为他们总是在变换职位。Android为什么自动更改位置?

我有这对我的偏爱活动:

public class MySettings extends PreferenceActivity {  
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     addPreferencesFromResource(R.xml.preferences); 
    } 
} 

这对我的滑块:

public class PreferenceSlider extends Preference implements OnSeekBarChangeListener 
{ 
    public static int maximum = 100; 
    public static int interval = 1; 
    private float oldValue = 50; 
    private TextView monitorBox; 
    private float beforeTouch = 50; 

    public PreferenceSlider(Context context) 
    { 
     super(context); 
    } 

    public PreferenceSlider(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
    } 

    public PreferenceSlider(Context context, AttributeSet attrs, int defStyle) 
    { 
     super(context, attrs, defStyle); 
    }  

    @Override 
    protected View onCreateView(ViewGroup parent) 
    {  
     LinearLayout layout = new LinearLayout(getContext());  
     LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT); 
     params1.gravity = Gravity.LEFT; 
     params1.weight = 1.0f;   
     LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT); 
     params2.gravity = Gravity.LEFT; 
     LinearLayout.LayoutParams params3 = new LinearLayout.LayoutParams(30, LinearLayout.LayoutParams.WRAP_CONTENT); 
     params3.gravity = Gravity.LEFT; 

     layout.setPadding(15, 5, 10, 5); 
     layout.setOrientation(LinearLayout.VERTICAL);  
     TextView view = new TextView(getContext()); 
     view.setText(getTitle()); 
     view.setTextSize(18); 
     view.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD); 
     view.setGravity(Gravity.LEFT); 
     view.setLayoutParams(params1);  
     SeekBar bar = new SeekBar(getContext()); 
     bar.setMax(maximum); 
     bar.setProgress((int)this.oldValue); 
     //bar. 
     //bar.setLayoutParams(params2); 
     bar.setOnSeekBarChangeListener(this);  
     this.monitorBox = new TextView(getContext()); 
     this.monitorBox.setTextSize(12); 
     this.monitorBox.setTypeface(Typeface.MONOSPACE, Typeface.ITALIC); 
     this.monitorBox.setLayoutParams(params3); 
     this.monitorBox.setPadding(2, 5, 0, 0); 
     this.monitorBox.setText(bar.getProgress()+"");   
     layout.addView(view); 
     layout.addView(bar); 
     layout.addView(this.monitorBox); 
     layout.setId(android.R.id.widget_frame);   
     return layout; 
    } 

    @Override 
    public void onProgressChanged(SeekBar seekBar, int progress,boolean fromTouch) 
    {  
     progress = Math.round(((float)progress)/interval)*interval;  
     if(!callChangeListener(progress)){ 
      seekBar.setProgress((int)this.oldValue);  
      return;  }   
     seekBar.setProgress(progress);  
     this.oldValue = progress;  
     this.monitorBox.setText(progress+"");  
     updatePreference(progress);  
     //notifyChanged(); 
    } 

    @Override 
    public void onStartTrackingTouch(SeekBar seekBar) 
    { 
     beforeTouch = seekBar.getProgress(); 
    } 

    @Override 
    public void onStopTrackingTouch(SeekBar seekBar) 
    { 
     if(beforeTouch != seekBar.getProgress()) 
     { 
      notifyChanged(); 
     } 
    } 

    @Override 
    protected Object onGetDefaultValue(TypedArray ta,int index) 
    {  
     int dValue = (int)ta.getInt(index,50);  
     return validateValue(dValue); 
    }  

    @Override  
    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) 
    {   
     int temp = restoreValue ? getPersistedInt(50) : (Integer)defaultValue; 
     if(!restoreValue)   
      persistInt(temp);   
     this.oldValue = temp;  
    }  

    private int validateValue(int value) 
    {   
     if(value > maximum)  
      value = maximum;  
     else if(value < 0)  
      value = 0;  
     else if(value % interval != 0)  
      value = Math.round(((float)value)/interval)*interval;    
     return value;  
    }   

    private void updatePreference(int newValue) 
    {  
     SharedPreferences.Editor editor = getEditor(); 
     editor.putInt(getKey(), newValue); 
     editor.commit(); } 
    } 

然后preferences.xml是这样的:

<com.myprogram.PreferenceSlider     
    android:key="ringerVolume"    
    android:defaultValue="50"     
    android:title="Ringer Volume"/> 

<com.myprogram.PreferenceSlider     
    android:key="notificationVolume"     
    android:defaultValue="50"     
    android:title="Notification Volume"/> 
+0

某些代码可能会帮助您获得更好的答案。 – ninjasense 2011-01-09 08:31:37

回答

2

你不应该担心的android 1.6,至少这意味着你的代码中有一些灰尘,这是不可见的2.2中的任何原因,但可能在一些其他版本,甚至更新的版本。

无论如何,在这里最重要的是,我看到这是2011年的一个问题,但现在似乎重新打开了,此时,我不会继续使用基于此代码的活动,这已经过时了,所以除此之外它还没有完美运行,现在它是最好的时刻,对于一些重新分解。

正如你可以看到hereaddPreferencesFromResource因为API级别11已被弃用,这意味着设备的75%,看它像一些旧的东西,还有一些最新的设备有朝一日甚至在某种引发错误“我告诉过你”的基础。

没有替代方法,因为android团队在这里想要的东西,几年前,不是函数的变化,而是完全不同的方法,使用Fragments。

具体而言,您需要创建一些PreferenceFragment对象来从资源文件加载您的首选项。我会建议这样做,并且不要浪费时间来尝试解决当前可能出现的错误。迁移到新方法很容易,你会得到更好的结果。

要开始,你可以在这里阅读一些代码:

Android Developer - Reference - PreferenceFragment

或者读到这里的完整指南:

Android Developer - Api Guides - UI - Settings

如果你去与这一点,有什么进一步的问题,不要犹豫,回来的任何问题,我会很乐意帮助你!