java - 最小化 setOnSeekBarChangeListener 样板

标签 java android abstract inner-classes

每次我想要一个 SeekBar 和一个相应的 TextView 来显示它的数值时,为了减少代码的编写,我编写了以下抽象类:

abstract public class SeekBarWrapper {
SeekBar bar;
TextView valueText;
int value = 0;
int minValue;
int divisor;

public SeekBarWrapper(SeekBar sb, TextView tv, int value,  int minValue,
    int divisor){
    this.bar = sb;
    this.valueText = tv;
    this.value = value;
    this.minValue = minValue;
    this.divisor = divisor;
    setListener();
}

private void setListener(){
    bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) { }
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) { }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser) {
            if(!fromUser) return;
            value = progress + minValue;
            valueText.setText(Integer.toString(value/divisor));
            sendValue();
        }
    });
}

abstract protected void sendValue();

public void updateValue(int newValue){
    if(newValue == value) return;
    value = newValue;
    valueText.setText(Integer.toString(value));
    bar.setProgress(value*divisor-minValue);
}

}

我将为每个具体的 SeekBar 编写一个嵌套类,例如:

class VolumeBarWrapper extends SeekBarWrapper{
    public VolumeBarWrapper(SeekBar s, TextView t, int v,  int min, int div){
        super(s, t, v, min, div);
    }
    public void sendValue(){
        someCallback.volume(this.value);
    }
}

然后像这样实例化:

VolumeBarWrapper volume;
    // later:
    volume = new VolumeBarWrapper((SeekBar) view.findViewById(R.id.volume_bar),
            (TextView) view.findViewById(R.id.volume_value), 300, 0, 70);

它很实用,而且看起来是一种改进。我想知道的:

  1. 有没有什么方法可以使它成为匿名内部类,或者有其他方法可以进一步压缩每个实例的代码? 不那么紧迫:
  2. 我是不是在滥用“包装器”这个标签,它在模式方面不是有一些特殊含义吗?
  3. 从 OOP 的角度来看,这种设计是否“糟糕”(我仍在努力学习这方面的知识)?

最佳答案

您总是可以制作更好的 SeekBar 并在任何地方使用它:

public class VersatileSeekBar extends SeekBar implements SeekBar.OnSeekBarChangeListener {
    private TextView mTextView;
    private ChangeHandler mChangeHandler;

    public void bindDisplayToChange(TextView textView,ChangeHandler handler) {
        mTextView = textView;
        mChangeHandler = handler;
    }

    public VersatileSeekBar(Context context) {
        super(context);
        init();
    }

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

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


    @Override
    public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
        if(mChangeHandler != null && mTextView != null){
            mChangeHandler.onChange(i,mTextView);
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    }

    private void init(){
        this.setOnSeekBarChangeListener(this);
    }

    public static abstract class ChangeHandler{
        public abstract void onChange(int value,TextView textView);
    }
}

调用代码:

myVersatileSeekBar.bindDisplayToChange(myTextView, new VersatileSeekBar.ChangeHandler() {
            @Override
            public void onChange(int value, TextView textView) {
                textView.setText("level :" + value * 100);
            }
        });

关于java - 最小化 setOnSeekBarChangeListener 样板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14000098/

相关文章:

java - 在java StillClock类中写入名称?

c# - 虚拟类中的抽象方法

java - ehcache 和 ehcache-core 的区别

android - Gson:由于 ExclusionStrategy 错误无法编译项目

android - Place Picker 不工作并消失

android - Macbook M1 : An error occurred while trying to compute required packages 上有关 Android Studio 的错误

playframework-2.0 - Morphia InstantiationException 与抽象 @Embedded 类

Java抽象类和接口(interface)方法实现

java - java httpssession的生命周期

java - 如何将 Java OutputStream 上传到 AWS S3