Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java sugaring, can I avoid almost-duplicate code here?

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
}

I have this class, it perfectly does what I want. Now I need new class VSV which will derive from (vertical)ScrollView and be just the same. I surely can just copy whole block and change extends HorizontalScrolView to extends ScrollView, and then (L, 0) to (0, L) (oops, this was a mistake when publishing on SO, surely that line will not change, the GetCurrentPos will).

or I can add "bool vertical" property. But Java has no templates or macros, nor runtime prototyping, so is there any other way in Java to avoid code duplication in this example?

like image 333
exebook Avatar asked Nov 04 '22 03:11

exebook


1 Answers

Looking at the documentation for android.widget.ScrollView and android.widget.HorizontalScrollView, both of them seem to implement

void addView(View child, int index)

So you would not have to change that line of code, if I am not missing anything here. Also, both classes inherit this method from android.view.ViewGroup. So, if the implementation of both classes is the same, you could do something like this

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();
  }
  // ...
}

and in HSV/VSV you can delegate to this class (if necessary).

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);
  }
}
like image 85
moxn Avatar answered Nov 15 '22 12:11

moxn