我有一个preferences.xml
文件,其中包含一些复选框偏好设置,自定义时间选择器偏好设置和自定义SeekBar
偏好设置。在我的2.2模拟器中一切正常。我尝试在1.6模拟器中运行它,每次调整其中一个滑块(SeekBar
首选项)或更改其他首选项时,SeekBar
首选项都会更改位置。就像它们只是随意乱扔一样。谁知道我怎么能阻止这个?
这使我无法进行分组,因为他们总是在改变位置。
我有这个用于我的偏好活动:
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 :(得分:2)
你不应该担心android 1.6,至少这意味着你的代码中有一些污垢,这在2.2中是不可见的,但可能在其他一些版本中,甚至更新版本。
无论如何,在这里最重要的是,我看到这是2011年的一个问题,但现在似乎已经重新开放了,而且在这一点上,我不会继续使用基于此代码的活动,这是相当过时的,所以除此之外没有完美的工作,现在这是最好的时刻,对于一些重新分解。
正如您所看到的那样here 自API级别11以来不推荐使用addPreferencesFromResource ,这意味着75%的设备会像旧的东西一样看待它,而有些新设备可能会在某一天看到它甚至在某种“我告诉你”的基础上提出错误。
没有替代方法,因为几年前Android团队想要的是,不是功能上的变化,而是使用Fragments完全不同的方法。
具体来说,您需要创建一些PreferenceFragment个对象来从资源文件加载首选项。我建议这样做,不要浪费时间尝试修复活动中可能出现的当前错误。迁移到新方法将很容易,您将获得更好的结果。
要开始使用,您可以在此处阅读一些代码:
Android Developer - Reference - PreferenceFragment
或者在这里阅读完整的指南:
Android Developer - Api Guides - UI - Settings
如果你继续这个,并有任何进一步的问题,请毫不犹豫地回答任何问题,我将很乐意帮助你!