问题
as per the material guidelines on transitions, I want to establish a certain look and feel on app screens to convey a hierarchy for these. Meaning, everything that transitions left to right is on same level or importance. Smaller forms or brief user inputs will transition in and out as simple popups, not horizontally but vertically.
Expected behaviour:
- The slide form uses the default transition. Show() will slide the source to the left and the destination slides in from the right. showback() will slide the source in from the left and the destination leaves to the right.
- The popup form uses a custom transition: show() will cause the source to remaining in place (not slide or transition in any other way) and the destination (the popup) will slide in from below. Showback() will cause the source (the popup) to slide out towards the bottom, revealing the destination (the main window) underneath.
Actual Behaviour
slide form works as expected in my scenario.
show() causes the popup form to slide into the screen from the bottom, while the source form stays in place, being covered up (as expected). BUT the showback() causes the main window to slide in from the top, covering the popup screen.
Full code sample to show actual behavior
public class MyApplication {
private Form current;
private Resources theme;
private Transition defaultInTrans = CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, true, 300);
private Transition defaultOutTrans = CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, true, 300);
private Transition popupInTrans = CommonTransitions.createCover(CommonTransitions.SLIDE_VERTICAL, false, 300);
private Transition popupOutTrans = CommonTransitions.createSlide(CommonTransitions.SLIDE_VERTICAL, false, 300);
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
Toolbar.setGlobalToolbar(true);
}
public void start() {
if (current != null) {
current.show();
return;
}
new MainForm().show();
}
public void stop() {
current = getCurrentForm();
if (current instanceof Dialog) {
((Dialog) current).dispose();
current = getCurrentForm();
}
}
public void destroy() {
}
class MainForm extends Form {
public MainForm() {
setLayout(BoxLayout.y());
Button slideBut = new Button("Slide Form");
Button popBut = new Button("Popup Form");
add(slideBut).add(popBut);
slideBut.addActionListener(e -> {
new SlideForm().show();
});
popBut.addActionListener(e -> {
new PopupForm(this).show();
});
}
}
class SlideForm extends Form {
public SlideForm() {
Style bg = getContentPane().getUnselectedStyle();
bg.setBgTransparency(255);
bg.setBgColor(0x00ff00);
getToolbar().setBackCommand("", e -> {
new MainForm().showBack();
});
add(new Label("Slide Form content"));
}
}
class PopupForm extends Form {
public PopupForm(Form orig) {
Style bg = getContentPane().getUnselectedStyle();
bg.setBgTransparency(255);
bg.setBgColor(0xff0000);
getToolbar().setBackCommand("", e -> {
new MainForm().showBack();
orig.setTransitionInAnimator(defaultInTrans);
orig.setTransitionOutAnimator(defaultOutTrans);
});
add(new Label("This is a popup!"));
// remove source animation to remain in place
orig.setTransitionInAnimator(null);
orig.setTransitionOutAnimator(null);
// add transition for target popup to appear and vanish from/to the bottom
setTransitionInAnimator(popupInTrans);
setTransitionOutAnimator(popupOutTrans);
}
}
}
Having different CommonTransition types, the in transition vs the out transition, the transition direction parameterand on top of that the direction of show() vs showback() is quite confusing.
how can I achieve the expected behaviour for the popup form to slide OUT correctly?
is there a better way or less code required to achieve this?
Thank you.
回答1:
Cover has an in/out effect where slide only has an out effect. When you slide from form A to form B there is one motion including both forms that works exactly the same in reverse. However, with cover it slides on top of form A while the latter stays in place then slides off of it making it look like form A has been under it all along.
That means both transition in and out are used to convey both cover modes. However this can collide with the transition out of form A so we need to temporarily disable it.
E.g.:
removeTransitionsTemporarily(backTo);
f.setTransitionInAnimator(CommonTransitions.createCover(CommonTransitions.SLIDE_VERTICAL, false, 300));
f.setTransitionOutAnimator(CommonTransitions.createUncover(CommonTransitions.SLIDE_VERTICAL, true, 300));
public static void removeTransitionsTemporarily(final Form f) {
final Transition originalOut = f.getTransitionOutAnimator();
final Transition originalIn = f.getTransitionInAnimator();
f.setTransitionOutAnimator(CommonTransitions.createEmpty());
f.setTransitionInAnimator(CommonTransitions.createEmpty());
f.addShowListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
f.setTransitionOutAnimator(originalOut);
f.setTransitionInAnimator(originalIn);
f.removeShowListener(this);
}
});
}
来源:https://stackoverflow.com/questions/55453437/codename-one-popup-like-form-transition