2012-12-22 29 views
1

在试图每次我想要一个搜索栏和相应的TextView时间写少一点的代码显示它的数值,我写了下面的抽象类:最小化setOnSeekBarChangeListener样板

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); 
} 

} 

对于每个具体的搜索栏我LL写一个嵌套类,例如:

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的角度来看,这种设计是否“不好”(我仍然试图在这方面自学)?
+0

我最终被上述与包装的具体版本去一个自定义监听器,如下所述。这使用SeekBar和VerticalSeekBar无缝,而扩展的SeekBar,我将不得不为每个SeekBar的子类,并更改XML中的引用。 – anthropomo

回答

1

你总是可以做出更好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); 
      } 
     }); 
+0

我的抽象类的一个重要特性是能够在onProgressChanged方法中调用一个可重写的抽象方法。是否有某种方法可以在不扩展每个实例的SimpleSeekBar的情况下进行管理?如果否,这可能更优雅,但我可能更喜欢坚持抽象类。 – anthropomo

+0

@anthropomo你现在可以提供'ChangeHandler'的任何实现来更新'TextView',看到更新的答案。 –

+1

我是谷歌搜索“自定义java侦听器”,并跳过GoF观察者模式,同时翻到这里。这个例子会为我节省几次尝试。谢谢! – anthropomo