【问题标题】:Android SeekBarPreferenceAndroid SeekBarPreference
【发布时间】:2011-02-19 10:38:35
【问题描述】:

我目前正在尝试使用带有RelativeLayout 的http://android-journey.blogspot.com/2010/01/for-almost-any-application-we-need-to.html 教程来实现SeekBarPreference 类。第一个问题是 TextView preferenceText 根本没有显示。 第二个问题是不能像常规偏好中的那样滑动栏(如媒体音量栏)?

public class SeekBarPreference extends Preference implements
    OnSeekBarChangeListener {

public static int maximum    = 100;
public static int interval   = 5;
private float oldValue = 25;
private TextView Indicator;

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

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

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

@Override
protected View onCreateView(ViewGroup parent) {

    float scale = getContext().getResources().getDisplayMetrics().density;

    RelativeLayout layout = new RelativeLayout(getContext());

    RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT);

    RelativeLayout.LayoutParams sbarParams = new RelativeLayout.LayoutParams(
            Math.round(scale * 160),
            RelativeLayout.LayoutParams.WRAP_CONTENT);

    RelativeLayout.LayoutParams indParams = new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT);

    TextView preferenceText = new TextView(getContext());
    preferenceText.setId(0);
    preferenceText.setText(getTitle());
    preferenceText.setTextSize(18);
    preferenceText.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);


    SeekBar sbar = new SeekBar(getContext());
    sbar.setId(1);
    sbar.setMax(maximum);
    sbar.setProgress((int)this.oldValue);
    sbar.setOnSeekBarChangeListener(this);

    this.Indicator = new TextView(getContext());
    this.Indicator.setTextSize(12);
    this.Indicator.setTypeface(Typeface.MONOSPACE, Typeface.ITALIC);
    this.Indicator.setText("" + sbar.getProgress());

    textParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
    sbarParams.addRule(RelativeLayout.RIGHT_OF, preferenceText.getId());
    indParams.setMargins(Math.round(20*scale), 0, 0, 0);
    indParams.addRule(RelativeLayout.RIGHT_OF, sbar.getId());

    preferenceText.setLayoutParams(textParams);
    sbar.setLayoutParams(sbarParams);
    this.Indicator.setLayoutParams(indParams);
    layout.addView(preferenceText);
    layout.addView(this.Indicator);
    layout.addView(sbar);
    layout.setId(android.R.id.widget_frame);

    return layout;
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
        boolean fromUser) {
    progress = Math.round(((float) progress)/interval) * interval;

    if(!callChangeListener(progress)) {
        seekBar.setProgress((int) this.oldValue);
        return;
    }

    seekBar.setProgress(progress);
    this.oldValue = progress;
    this.Indicator.setText("" + progress);
    updatePreference(progress);

    notifyChanged();
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}

@Override
protected Object onGetDefaultValue(TypedArray ta, int index) {
    int dValue = ta.getInt(index, 25);

    return validateValue(dValue);
}

@Override
protected void onSetInitialValue(boolean restoreValue,
        Object defaultValue) {
    int temp = restoreValue ? getPersistedInt(25) : (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();
}

}

【问题讨论】:

    标签: android seekbar preference


    【解决方案1】:

    这里滑动的问题是由于notifyChange()调用。那会以某种方式干扰滑动。我也在研究类似的小部件,因为我不喜欢 Dialog 方法。

    这里承诺的是我添加到我的开源项目中的解决方案:

    我编写了一个 SeekBarPreference 类,该类嵌入在首选项活动中而不是弹出对话框中。您可以从以下位置下载 jar 文件:

    http://aniqroid.sileria.com/

    类文档和用法在这里:http://aniqroid.sileria.com/doc/api/com/sileria/android/view/SeekBarPreference.html

    当您更改 SeekBar 时,不要忘记查看方便的配套类以自动显示摘要:http://aniqroid.sileria.com/doc/api/com/sileria/android/event/PrefsSeekBarListener.html

    【讨论】:

    • 谢谢!看起来非常好,javadocs 令人印象深刻。但举个例子不会有什么坏处,尤其是关于使用 PrefsSeekBarListener 进行实时显示。
    【解决方案2】:

    通过将 onProgressChanged 更改为,滑块在教程中工作

    public void onProgressChanged( SeekBar seekBar, int progress, boolean fromUser )
    {
        progress = Math.round( ( (float) progress ) / interval ) * interval;
        persistInt(progress);
        callChangeListener( progress );
        seekBar.setProgress( progress );
        this.monitorBox.setText( progress + "" );
        updatePreference( progress );
    }
    

    【讨论】:

      【解决方案3】:

      关于无法移动滑块,这是因为它的宽度设置为 80(参见 params2),太窄而无法滑动。在为其设置合理的宽度后,例如400,以及相关的文本视图和一些模块,以使其与我的 SDK 版本一起编译,它对我有用。这个版本相对于其他许多版本的一个优势是布局是在代码中而不是 XML 中完成的,这允许应用程序轻松实例化多个滑块。

      【讨论】:

        猜你喜欢
        • 2019-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-28
        • 1970-01-01
        • 2011-11-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多