java sugaring,我可以在这里避免几乎重复的代码吗?

时间:2013-03-05 11:10:41

标签: java android syntactic-sugar

private class HSV extends HorizontalScrollView {
    public LinearLayout L;
    public AbsoluteLayout A;
    public HSV(Context context) {
        super(context);
        L = new LinearLayout(context);
        A = new AbsoluteLayout(context);
    }
    @Override public void addView(View child) {
        A.addView(child);
    }
    void update_scroll() {
        removeView(L);
        addView(L, 0);
        L.removeView(A);
        L.addView(A);
        A.invalidate();
        L.invalidate();
        invalidate();
        requestLayout();
    }
    int GetCurrentPos() {
        return getScrollX(); // <-- this line if HSV
        return getScrollY(); // <-- this line if VSV
    }
    ... few more methods skipped, they will not change at all in 'vertical' version
}

我有这门课,它完全符合我的要求。现在我需要新的VSV,它将从(垂直)ScrollView派生出来并且是一样的。我当然可以复制整个块并将 extends Horizo​​ntalScrolView 更改为扩展ScrollView ,然后将(L,0)更改为(0, L)(哎呀,在SO上发布时这是一个错误,肯定该行不会改变,GetCurrentPos会这样做。)

或者我可以添加“bool vertical”属性。但是Java没有模板或宏,也没有运行时原型,因此在Java中有没有其他方法可以避免代码重复?

1 个答案:

答案 0 :(得分:2)

查看android.widget.ScrollViewandroid.widget.HorizontalScrollView的文档,它们似乎都已实现

void addView(View child, int index)

所以如果我在这里没有遗漏任何内容,你就不必更改那行代码。此外,这两个类都从android.view.ViewGroup继承此方法。因此,如果两个类的实现相同,您可以执行类似这样的操作

public abstract class ScrollViewDelegate<T extends FrameLayout> {
  private final T view;
  private LinearLayout L;
  private AbsoluteLayout A;

  public ScrollViewWrapper(T view) {
    this.view = view;
    L = new LinearLayout(view.getContext());   // or pass as parameter
    A = new AbsoluteLayout(view.getContext()); // or pass as parameter
  }

  void update_scroll() {
      view.removeView(L);
      view.addView(L, 0);
      L.removeView(A);
      L.addView(A);
      A.invalidate();
      L.invalidate();
      view.invalidate();
      view.requestLayout();
  }
  // ...
}

在HSV / VSV中,您可以委托给这个班级(如有必要)。

public class HSV extends HorizontalScrollView {

  private final ScrollViewDelegate<HorizontalScrollView> delegate;

  public HSV(Context context) {
      super(context);
      this.delegate = new ScrollViewDelegate<HorizontalScrollView>(this);
  }
  // do stuff with this.delegate
}

public class VSV extends ScrollView {

  private final ScrollViewDelegate<ScrollView> delegate;

  public VSV(Context context) {
      super(context);
      this.delegate = new ScrollViewDelegate<ScrollView>(this);
  }
}