问题
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?
回答1:
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);
}
}
来源:https://stackoverflow.com/questions/15222285/java-sugaring-can-i-avoid-almost-duplicate-code-here