mirror of
https://github.com/Dark98/SliceBeam.git
synced 2026-07-03 08:39:04 +00:00
Srat Refactoring To Santoku
This commit is contained in:
@@ -0,0 +1,270 @@
|
||||
package com.dark98.santoku.navigation;
|
||||
|
||||
import static com.dark98.santoku.utils.DebugUtils.assertTrue;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.SparseArray;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.dynamicanimation.animation.FloatValueHolder;
|
||||
import androidx.dynamicanimation.animation.SpringAnimation;
|
||||
import androidx.dynamicanimation.animation.SpringForce;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import com.dark98.santoku.theme.ThemesRepo;
|
||||
|
||||
public abstract class NavigationDelegate {
|
||||
protected Context context;
|
||||
|
||||
protected SparseArray<Stack<Fragment>> fragmentStack = new SparseArray<>();
|
||||
protected int currentSlot = 0;
|
||||
protected FrameLayout container;
|
||||
|
||||
private SpringAnimation switchAnimation;
|
||||
|
||||
public final void setContext(Context ctx) {
|
||||
context = ctx;
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
public void onCreate() {
|
||||
for (int i = 0; i < fragmentStack.size(); i++) {
|
||||
Stack<Fragment> fragments = fragmentStack.get(fragmentStack.keyAt(i));
|
||||
for (Fragment fr : fragments) {
|
||||
fr.setContext(context);
|
||||
fr.onCreate();
|
||||
}
|
||||
}
|
||||
|
||||
if (fragmentStack.get(currentSlot) == null) {
|
||||
Stack<Fragment> stack = new Stack<>();
|
||||
fragmentStack.put(currentSlot, stack);
|
||||
Fragment fr = newFragment(currentSlot);
|
||||
fr.setContext(context);
|
||||
fr.onCreate();
|
||||
stack.push(fr);
|
||||
}
|
||||
}
|
||||
|
||||
public void onApplyTheme() {
|
||||
for (int i = 0; i < fragmentStack.size(); i++) {
|
||||
Stack<Fragment> st = fragmentStack.valueAt(i);
|
||||
assertTrue(st != null);
|
||||
for (Fragment fr : st) {
|
||||
fr.onApplyTheme();
|
||||
if (fr.getView() != null) {
|
||||
ThemesRepo.invalidateView(fr.getView());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
public void onResume() {
|
||||
fragmentStack.get(currentSlot).peek().onResume();
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
public void onPause() {
|
||||
fragmentStack.get(currentSlot).peek().onPause();
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
public void onDestroy() {
|
||||
for (int i = 0; i < fragmentStack.size(); i++) {
|
||||
Stack<Fragment> fragments = fragmentStack.get(fragmentStack.keyAt(i));
|
||||
for (Fragment fr : fragments) {
|
||||
fr.onDestroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FrameLayout getContainerView() {
|
||||
return container;
|
||||
}
|
||||
|
||||
public abstract View onCreateView(Context ctx);
|
||||
public abstract Fragment newFragment(int slot);
|
||||
public abstract FrameLayout getOverlayView();
|
||||
|
||||
public boolean isSwitchingWithX() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void switchSlot(int slot, Runnable onInterfaceChange) {
|
||||
Stack<Fragment> stack = fragmentStack.get(slot);
|
||||
if (stack == null) {
|
||||
fragmentStack.put(slot, stack = new Stack<>());
|
||||
Fragment fr = newFragment(slot);
|
||||
fr.setContext(context);
|
||||
fr.onCreate();
|
||||
stack.push(fr);
|
||||
}
|
||||
int wasSlot = currentSlot;
|
||||
currentSlot = slot;
|
||||
|
||||
if (container.getChildCount() > 0) {
|
||||
if (switchAnimation != null) {
|
||||
switchAnimation.cancel();
|
||||
}
|
||||
|
||||
Fragment cur = fragmentStack.get(wasSlot).peek();
|
||||
cur.onPause();
|
||||
|
||||
Runnable next = () -> {
|
||||
onInterfaceChange.run();
|
||||
|
||||
Fragment fr = fragmentStack.get(slot).peek();
|
||||
View wasView = container.getChildAt(0);
|
||||
View newView;
|
||||
if (fr.getView() == null) {
|
||||
newView = fr.onCreateView(context);
|
||||
fr.onViewCreated(newView);
|
||||
fr.onApplyTheme();
|
||||
} else {
|
||||
newView = fr.getView();
|
||||
}
|
||||
container.addView(newView);
|
||||
|
||||
boolean forward = slot > wasSlot;
|
||||
switchAnimation = new SpringAnimation(new FloatValueHolder(0))
|
||||
.setMinimumVisibleChange(1 / 256f)
|
||||
.setSpring(new SpringForce(1f)
|
||||
.setStiffness(1000f)
|
||||
.setDampingRatio(1f))
|
||||
.addUpdateListener((animation, value, velocity) -> {
|
||||
float fValue = value;
|
||||
if (!forward) {
|
||||
fValue = 1f - fValue;
|
||||
}
|
||||
|
||||
if (isSwitchingWithX()) {
|
||||
wasView.setTranslationX(fValue * -wasView.getWidth() * 0.75f);
|
||||
newView.setTranslationX((1f - value) * (forward ? 1 : -1) * newView.getWidth() * 0.75f);
|
||||
} else {
|
||||
wasView.setTranslationY(fValue * -wasView.getHeight() * 0.75f);
|
||||
newView.setTranslationY((1f - value) * (forward ? 1 : -1) * newView.getHeight() * 0.75f);
|
||||
}
|
||||
wasView.setAlpha(1f - value);
|
||||
newView.setAlpha(value);
|
||||
})
|
||||
.addEndListener((animation, canceled, value, velocity) -> {
|
||||
switchAnimation = null;
|
||||
container.removeView(wasView);
|
||||
fr.onResume();
|
||||
});
|
||||
switchAnimation.start();
|
||||
};
|
||||
|
||||
Fragment.SlotChangeCallback callback = cur.onCheckDelayForSlotChange();
|
||||
if (callback == null || !cur.onCheckDelayForSlotChange().needDelay(next)) {
|
||||
next.run();
|
||||
}
|
||||
} else {
|
||||
Fragment fr = fragmentStack.get(slot).peek();
|
||||
fr.setContext(context);
|
||||
fr.onCreate();
|
||||
View v = fr.onCreateView(context);
|
||||
fr.onViewCreated(v);
|
||||
fr.onApplyTheme();
|
||||
container.addView(v);
|
||||
fr.onResume();
|
||||
currentSlot = slot;
|
||||
|
||||
onInterfaceChange.run();
|
||||
}
|
||||
}
|
||||
|
||||
public Fragment getCurrentFragment() {
|
||||
return fragmentStack.get(currentSlot).peek();
|
||||
}
|
||||
|
||||
public boolean destroyCurrent() {
|
||||
if (fragmentStack.get(currentSlot).size() <= 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Fragment fr = fragmentStack.get(currentSlot).peek();
|
||||
fr.onPause();
|
||||
|
||||
Fragment prev = fragmentStack.get(currentSlot).get(fragmentStack.get(currentSlot).size() - 2);
|
||||
|
||||
View wasView = container.getChildAt(0);
|
||||
View newView = prev.getView();
|
||||
|
||||
switchAnimation = new SpringAnimation(new FloatValueHolder(0))
|
||||
.setMinimumVisibleChange(1 / 256f)
|
||||
.setSpring(new SpringForce(1f)
|
||||
.setStiffness(1000f)
|
||||
.setDampingRatio(1f))
|
||||
.addUpdateListener((animation, value, velocity) -> {
|
||||
float fValue = 1f - value;
|
||||
|
||||
if (isSwitchingWithX()) {
|
||||
wasView.setTranslationX(-fValue * wasView.getWidth() * 0.75f);
|
||||
newView.setTranslationX((1f - fValue) * newView.getWidth() * 0.75f);
|
||||
} else {
|
||||
wasView.setTranslationY(-fValue * wasView.getHeight() * 0.75f);
|
||||
newView.setTranslationY((1f - fValue) * newView.getHeight() * 0.75f);
|
||||
}
|
||||
wasView.setAlpha(1f - value);
|
||||
newView.setAlpha(value);
|
||||
})
|
||||
.addEndListener((animation, canceled, value, velocity) -> {
|
||||
switchAnimation = null;
|
||||
container.removeView(wasView);
|
||||
prev.onResume();
|
||||
fr.onDestroy();
|
||||
});
|
||||
switchAnimation.start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void pushFragment(Fragment fragment) {
|
||||
fragment.setContext(context);
|
||||
fragment.onCreate();
|
||||
|
||||
fragmentStack.get(currentSlot).peek().onPause();
|
||||
View wasView = container.getChildAt(0);
|
||||
View newView = fragment.onCreateView(context);
|
||||
fragment.onViewCreated(newView);
|
||||
fragment.onApplyTheme();
|
||||
fragmentStack.get(currentSlot).push(fragment);
|
||||
|
||||
switchAnimation = new SpringAnimation(new FloatValueHolder(0))
|
||||
.setMinimumVisibleChange(1 / 256f)
|
||||
.setSpring(new SpringForce(1f)
|
||||
.setStiffness(1000f)
|
||||
.setDampingRatio(1f))
|
||||
.addUpdateListener((animation, value, velocity) -> {
|
||||
if (isSwitchingWithX()) {
|
||||
wasView.setTranslationX(-value * wasView.getWidth() * 0.75f);
|
||||
newView.setTranslationX((1f - value) * newView.getWidth() * 0.75f);
|
||||
} else {
|
||||
wasView.setTranslationY(-value * wasView.getHeight() * 0.75f);
|
||||
newView.setTranslationY((1f - value) * newView.getHeight() * 0.75f);
|
||||
}
|
||||
wasView.setAlpha(1f - value);
|
||||
newView.setAlpha(value);
|
||||
})
|
||||
.addEndListener((animation, canceled, value, velocity) -> {
|
||||
switchAnimation = null;
|
||||
container.removeView(wasView);
|
||||
fragment.onResume();
|
||||
});
|
||||
switchAnimation.start();
|
||||
}
|
||||
|
||||
public boolean onBackPressed() {
|
||||
Fragment fr = getCurrentFragment();
|
||||
if (fr != null && fr.onBackPressed()) return true;
|
||||
else if (fragmentStack.get(currentSlot).size() > 1) {
|
||||
return destroyCurrent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user