我有一个 preferences.xml
文件,其中包含一些复选框首选项、自定义时间选择器首选项和自定义 SeekBar
首选项。在我的 2.2 模拟器中一切正常。我试过在 1.6 模拟器中运行它,每次我调整其中一个 slider (SeekBar
首选项)或更改另一个首选项时,SeekBar
首选项都会改变位置。就像他们只是四处乱窜。任何人都知道我怎么能阻止这个?
这使我无法进行分组,因为它们总是在改变位置。
我有这个作为我的偏好 Activity :
public class MySettings extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
这是我的 slider :
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"/>
最佳答案
你不应该担心 android 1.6,至少这意味着你的代码中有一些污点,在 2.2 中由于任何原因是不可见的,但可能在其他一些版本中,甚至是更新的版本中。
无论如何,这里最重要的是,我看到这是 2011 年的问题,但现在似乎重新打开了,在这一点上,我不会继续基于这段代码的 Activity ,它已经过时了,所以除此之外,它还不能完美地工作,现在是进行一些重构的最佳时机。
如你所见here addPreferencesFromResource 自 API 级别 11 起已被弃用,这意味着 75% 的设备将其视为一些旧东西,而一些最新的设备有一天甚至会以一种“我告诉过你”的方式引发错误“基础。
没有替代方法,因为几年前 android 团队在这里想要的,不是功能的改变,而是完全不同的方法,使用 Fragments。
具体来说,您应该创建一些 PreferenceFragment对象从资源文件加载您的首选项。我会建议这样做,不要浪费时间尝试修复 Activity 中可能存在的当前错误。迁移到新方法会很容易,而且您会得到更好的结果。
首先,您可以在此处阅读一些代码:
Android Developer - Reference - PreferenceFragment
或在此处阅读完整指南:
Android Developer - Api Guides - UI - Settings
如果您继续这样做,并且有任何其他问题,请随时回来提出任何问题,我很乐意为您提供帮助!
关于Android 为什么偏好会自动更改位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4637693/