В одном из моих проектов меня попросили спроектировать спиннер, который будет выглядеть так, чтобы он хорошо смотрелся в мобильном веб-приложении.Затем мы поняли, что нам на самом деле нужен другой вид для нашего счетчика, который также «тоньше».Поэтому я попытался применить MVP-подход к реализации моего виджета, который мне помог.Ниже приведен очень простой пример не для производственного использования, просто для демонстрации
Определите интерфейс Presenter и View, как в шаблоне MVP.Смысл здесь в том, чтобы сделать реализации представлений немыми, чтобы их можно было без проблем переключать.Обратите внимание, что Spinner на самом деле не является виджетом, но он реализует IsWidget, что означает, что он будет обрабатываться как виджет, но на самом деле мы будем передавать ссылку на нашу реализацию представления.
public class Spinner implements IsWidget, SpinnerPresenter{
interface View{
Widget asWidget();
void stepUp(int step);
void stepDown(int step);
void setValue(int value);
void setPixelSize(int width,int height);
}
View view;
int value;
public Spinner() {
view = new SpinnerImpl(this);
view.setValue(0);
}
public int getValue() {
return value;
}
public void setValue(int value) {
if (value == this.value)
return;
this.value = value;
view.setValue(value);
}
public void setPixelSize(int width, int height){
view.setPixelSize(width,height);
}
@Override
public void downButtonClicked() {
value--;
view.stepDown(1);
}
@Override
public void upButtonClicked() {
value++;
view.stepUp(1);
}
@Override
public Widget asWidget() {
return view.asWidget();
}
}
И сама реализация представления, котораяреализует интерфейс представления, определенный в классе Spinner.Обратите внимание, как мы делегируем пользовательские события классу Spinner для обработки через интерфейс SpinnerPresenter.
public class SpinnerImpl extends Composite implements Spinner.View{
private TextBox txtBox;
private Button upButton,downButton;
private HorizontalPanel panel;
private SpinnerPresenter presenter;
public SpinnerImpl(SpinnerPresenter presenter){
this.presenter = presenter;
upButton = new Button("up");
downButton = new Button("down");
txtBox = new TextBox();
txtBox.setEnabled(false);
panel = new HorizontalPanel();
panel.add(upButton);
panel.add(txtBox);
panel.add(downButton);
addHandlers();
initWidget(panel);
}
private void addHandlers() {
upButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
presenter.upButtonClicked();
}
});
downButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
presenter.downButtonClicked();
}
});
}
@Override
public void stepDown(int step) {
txtBox.setValue(Integer.parseInt(txtBox.getValue())-1+"");
}
@Override
public void stepUp(int step) {
txtBox.setValue(Integer.parseInt(txtBox.getValue())+1+"");
}
@Override
public void setValue(int value) {
txtBox.setValue(0+"");
}
}
Интерфейс SpinnerPresenter:
public interface SpinnerPresenter {
void upButtonClicked();
void downButtonClicked();
}
Наконец, чтобы добавить мой виджет в корневую панель.Обратите внимание, что я могу добавить класс прядильщика, как если бы это был виджет
Spinner s = new Spinner();
RootPanel.get().add(s);
Теперь, если я хочу изменить внешний вид моего прядильщика, изменить ориентацию, возможно, добавить необычную анимацию для прядения и т. Д., Мне нужно толькоизменить мой вид реализации.И последнее, но не менее важное, когда дело доходит до тестирования моего виджета, этот подход поможет, так как я могу легко смоделировать свой вид.