2012-12-22 67 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