我有一个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"/>
某些代码可能会帮助您获得更好的答案。 – ninjasense 2011-01-09 08:31:37