NekoX/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java

1140 lines
47 KiB
Java
Raw Normal View History

/*
* This is the source code of Telegram for Android v. 1.4.x.
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013-2014.
*/
2014-11-13 21:10:14 +01:00
package org.telegram.ui.ActionBar;
import android.app.Activity;
2014-06-04 20:57:11 +02:00
import android.content.Context;
import android.content.Intent;
2014-11-11 23:16:17 +01:00
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Build;
2014-06-13 00:37:05 +02:00
import android.os.Handler;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
2014-11-11 23:16:17 +01:00
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
2014-11-11 23:16:17 +01:00
import android.widget.LinearLayout;
import org.telegram.android.AndroidUtilities;
import org.telegram.messenger.R;
import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.android.AnimationCompat.AnimatorSetProxy;
import org.telegram.android.AnimationCompat.ObjectAnimatorProxy;
import org.telegram.android.AnimationCompat.ViewProxy;
import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList;
public class ActionBarLayout extends FrameLayout {
public interface ActionBarLayoutDelegate {
boolean onPreIme();
boolean needPresentFragment(BaseFragment fragment, boolean removeLast, boolean forceWithoutAnimation, ActionBarLayout layout);
boolean needAddFragmentToStack(BaseFragment fragment, ActionBarLayout layout);
boolean needCloseLastFragment(ActionBarLayout layout);
void onRebuildAllFragments(ActionBarLayout layout);
}
2014-11-11 23:16:17 +01:00
public class LinearLayoutContainer extends LinearLayout {
public LinearLayoutContainer(Context context) {
super(context);
setOrientation(VERTICAL);
}
2014-11-17 03:44:57 +01:00
@Override
2014-11-11 23:16:17 +01:00
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
2014-11-17 03:44:57 +01:00
if (child instanceof ActionBar) {
return super.drawChild(canvas, child, drawingTime);
} else {
2015-07-22 20:56:37 +02:00
//boolean wasActionBar = false;
2014-11-17 03:44:57 +01:00
int actionBarHeight = 0;
int childCount = getChildCount();
for (int a = 0; a < childCount; a++) {
View view = getChildAt(a);
if (view == child) {
continue;
}
2014-11-19 16:17:24 +01:00
if (view instanceof ActionBar && view.getVisibility() == VISIBLE) {
2015-02-01 19:51:02 +01:00
if (((ActionBar) view).getCastShadows()) {
actionBarHeight = view.getMeasuredHeight();
2015-05-21 23:27:27 +02:00
//wasActionBar = true;
2015-02-01 19:51:02 +01:00
}
2014-11-17 03:44:57 +01:00
break;
}
}
/*if (!wasActionBar) {
if (child instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) child;
childCount = viewGroup.getChildCount();
for (int a = 0; a < childCount; a++) {
View possibleActionBar = viewGroup.getChildAt(a);
if (possibleActionBar instanceof ActionBar) {
actionBarHeight = possibleActionBar.getMeasuredHeight();
break;
}
}
}
}*/
boolean result = super.drawChild(canvas, child, drawingTime);
if (actionBarHeight != 0 && headerShadowDrawable != null) {
headerShadowDrawable.setBounds(0, actionBarHeight, getMeasuredWidth(), actionBarHeight + headerShadowDrawable.getIntrinsicHeight());
headerShadowDrawable.draw(canvas);
}
return result;
}
}
2014-11-11 23:16:17 +01:00
}
private static Drawable headerShadowDrawable;
private static Drawable layerShadowDrawable;
private static Paint scrimPaint;
private LinearLayoutContainer containerView;
private LinearLayoutContainer containerViewBack;
2014-11-07 11:23:17 +01:00
private DrawerLayoutContainer drawerLayoutContainer;
2014-11-11 23:16:17 +01:00
private ActionBar currentActionBar;
private AnimatorSetProxy currentAnimation;
private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator(1.5f);
private AccelerateDecelerateInterpolator accelerateDecelerateInterpolator = new AccelerateDecelerateInterpolator();
2014-11-11 23:16:17 +01:00
public float innerTranslationX;
2014-11-17 03:44:57 +01:00
private boolean maybeStartTracking;
protected boolean startedTracking;
private int startedTrackingX;
private int startedTrackingY;
2014-11-17 03:44:57 +01:00
protected boolean animationInProgress;
private VelocityTracker velocityTracker;
private boolean beginTrackingSent;
private boolean transitionAnimationInProgress;
private long transitionAnimationStartTime;
2014-11-17 03:44:57 +01:00
private boolean inActionMode;
private int startedTrackingPointerId;
2014-11-17 03:44:57 +01:00
private Runnable onCloseAnimationEndRunnable;
private Runnable onOpenAnimationEndRunnable;
private boolean useAlphaAnimations;
private View backgroundView;
2014-11-17 03:44:57 +01:00
private boolean removeActionBarExtraHeight;
private float animationProgress = 0.0f;
private long lastFrameTime;
2014-11-18 06:01:04 +01:00
private String titleOverlayText;
private ActionBarLayoutDelegate delegate = null;
protected Activity parentActivity = null;
2014-06-04 20:57:11 +02:00
public ArrayList<BaseFragment> fragmentsStack = null;
public ActionBarLayout(Context context) {
super(context);
2014-11-11 23:16:17 +01:00
parentActivity = (Activity) context;
if (layerShadowDrawable == null) {
layerShadowDrawable = getResources().getDrawable(R.drawable.layer_shadow);
2014-11-17 03:44:57 +01:00
headerShadowDrawable = getResources().getDrawable(R.drawable.header_shadow);
2014-11-11 23:16:17 +01:00
scrimPaint = new Paint();
}
}
public void init(ArrayList<BaseFragment> stack) {
fragmentsStack = stack;
2014-11-11 23:16:17 +01:00
containerViewBack = new LinearLayoutContainer(parentActivity);
addView(containerViewBack);
2014-11-11 23:16:17 +01:00
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) containerViewBack.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
2014-11-11 23:16:17 +01:00
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
containerViewBack.setLayoutParams(layoutParams);
containerView = new LinearLayoutContainer(parentActivity);
addView(containerView);
2014-11-11 23:16:17 +01:00
layoutParams = (FrameLayout.LayoutParams) containerView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
2014-11-11 23:16:17 +01:00
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
containerView.setLayoutParams(layoutParams);
for (BaseFragment fragment : fragmentsStack) {
fragment.setParentLayout(this);
}
}
@Override
public void onConfigurationChanged(android.content.res.Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (!fragmentsStack.isEmpty()) {
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
lastFragment.onConfigurationChanged(newConfig);
}
}
2015-06-29 19:12:11 +02:00
public void drawHeaderShadow(Canvas canvas, int y) {
if (headerShadowDrawable != null) {
headerShadowDrawable.setBounds(0, y, getMeasuredWidth(), y + headerShadowDrawable.getIntrinsicHeight());
headerShadowDrawable.draw(canvas);
}
}
2014-11-11 23:16:17 +01:00
public void setInnerTranslationX(float value) {
innerTranslationX = value;
invalidate();
}
public float getInnerTranslationX() {
return innerTranslationX;
}
public void onResume() {
2014-06-13 17:03:06 +02:00
if (transitionAnimationInProgress) {
2014-11-11 23:16:17 +01:00
if (currentAnimation != null) {
currentAnimation.cancel();
currentAnimation = null;
}
2014-06-13 17:03:06 +02:00
if (onCloseAnimationEndRunnable != null) {
onCloseAnimationEnd(false);
} else if (onOpenAnimationEndRunnable != null) {
onOpenAnimationEnd(false);
}
2014-06-12 03:13:15 +02:00
}
if (!fragmentsStack.isEmpty()) {
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
lastFragment.onResume();
}
}
public void onPause() {
if (!fragmentsStack.isEmpty()) {
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
lastFragment.onPause();
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return !(!animationInProgress && !checkTransitionAnimation()) || onTouchEvent(ev);
}
@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
onTouchEvent(null);
super.requestDisallowInterceptTouchEvent(disallowIntercept);
}
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
return delegate != null && delegate.onPreIme() || super.dispatchKeyEventPreIme(event);
}
return super.dispatchKeyEventPreIme(event);
}
@Override
2014-11-11 23:16:17 +01:00
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
2014-11-17 03:44:57 +01:00
int width = getWidth() - getPaddingLeft() - getPaddingRight();
int translationX = (int) innerTranslationX + getPaddingRight();
int clipLeft = getPaddingLeft();
int clipRight = width + getPaddingLeft();
2014-11-11 23:16:17 +01:00
if (child == containerViewBack) {
clipRight = translationX;
} else if (child == containerView) {
clipLeft = translationX;
}
final int restoreCount = canvas.save();
if (!transitionAnimationInProgress) {
canvas.clipRect(clipLeft, 0, clipRight, getHeight());
}
final boolean result = super.drawChild(canvas, child, drawingTime);
canvas.restoreToCount(restoreCount);
if (translationX != 0) {
if (child == containerView) {
final float alpha = Math.max(0, Math.min((width - translationX) / (float) AndroidUtilities.dp(20), 1.0f));
layerShadowDrawable.setBounds(translationX - layerShadowDrawable.getIntrinsicWidth(), child.getTop(), translationX, child.getBottom());
layerShadowDrawable.setAlpha((int) (0xff * alpha));
layerShadowDrawable.draw(canvas);
} else if (child == containerViewBack) {
2015-06-29 19:12:11 +02:00
float opacity = Math.min(0.8f, (width - translationX) / (float)width);
if (opacity < 0) {
opacity = 0;
}
2014-11-11 23:16:17 +01:00
scrimPaint.setColor((int) (((0x99000000 & 0xff000000) >>> 24) * opacity) << 24);
canvas.drawRect(clipLeft, 0, clipRight, getHeight(), scrimPaint);
}
}
return result;
}
public void setDelegate(ActionBarLayoutDelegate delegate) {
this.delegate = delegate;
}
private void onSlideAnimationEnd(final boolean backAnimation) {
if (!backAnimation) {
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
lastFragment.onPause();
lastFragment.onFragmentDestroy();
lastFragment.setParentLayout(null);
fragmentsStack.remove(fragmentsStack.size() - 1);
2014-11-11 23:16:17 +01:00
LinearLayoutContainer temp = containerView;
containerView = containerViewBack;
containerViewBack = temp;
2014-11-11 23:16:17 +01:00
bringChildToFront(containerView);
lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
2014-11-19 02:23:46 +01:00
currentActionBar = lastFragment.actionBar;
lastFragment.onResume();
2015-06-29 19:12:11 +02:00
lastFragment.onBecomeFullyVisible();
} else {
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 2);
lastFragment.onPause();
if (lastFragment.fragmentView != null) {
ViewGroup parent = (ViewGroup) lastFragment.fragmentView.getParent();
if (parent != null) {
parent.removeView(lastFragment.fragmentView);
}
}
2014-11-11 23:16:17 +01:00
if (lastFragment.needAddActionBar() && lastFragment.actionBar != null) {
ViewGroup parent = (ViewGroup) lastFragment.actionBar.getParent();
if (parent != null) {
parent.removeView(lastFragment.actionBar);
}
}
}
2015-06-29 19:12:11 +02:00
containerViewBack.setVisibility(View.GONE);
2014-11-19 02:23:46 +01:00
//AndroidUtilities.unlockOrientation(parentActivity);
startedTracking = false;
animationInProgress = false;
ViewProxy.setTranslationX(containerView, 0);
ViewProxy.setTranslationX(containerViewBack, 0);
2014-11-11 23:16:17 +01:00
setInnerTranslationX(0);
}
private void prepareForMoving(MotionEvent ev) {
maybeStartTracking = false;
startedTracking = true;
startedTrackingX = (int) ev.getX();
containerViewBack.setVisibility(View.VISIBLE);
beginTrackingSent = false;
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 2);
2015-04-09 20:00:14 +02:00
View fragmentView = lastFragment.fragmentView;
if (fragmentView == null) {
2015-07-22 20:56:37 +02:00
fragmentView = lastFragment.createView(parentActivity);
2015-04-09 20:00:14 +02:00
} else {
ViewGroup parent = (ViewGroup) fragmentView.getParent();
if (parent != null) {
parent.removeView(fragmentView);
}
}
2014-11-11 23:16:17 +01:00
ViewGroup parent = (ViewGroup) fragmentView.getParent();
if (parent != null) {
parent.removeView(fragmentView);
}
if (lastFragment.needAddActionBar() && lastFragment.actionBar != null) {
parent = (ViewGroup) lastFragment.actionBar.getParent();
if (parent != null) {
parent.removeView(lastFragment.actionBar);
}
2014-11-17 03:44:57 +01:00
if (removeActionBarExtraHeight) {
lastFragment.actionBar.setOccupyStatusBar(false);
}
2014-11-11 23:16:17 +01:00
containerViewBack.addView(lastFragment.actionBar);
2014-11-18 06:01:04 +01:00
lastFragment.actionBar.setTitleOverlayText(titleOverlayText);
}
containerViewBack.addView(fragmentView);
ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
fragmentView.setLayoutParams(layoutParams);
2015-04-09 20:00:14 +02:00
if (!lastFragment.hasOwnBackground && fragmentView.getBackground() == null) {
fragmentView.setBackgroundColor(0xffffffff);
}
lastFragment.onResume();
2014-11-19 02:23:46 +01:00
//AndroidUtilities.lockOrientation(parentActivity);
}
2014-06-04 20:57:11 +02:00
public boolean onTouchEvent(MotionEvent ev) {
2014-11-11 23:16:17 +01:00
if (!checkTransitionAnimation() && !inActionMode && !animationInProgress) {
2014-11-07 11:23:17 +01:00
if (fragmentsStack.size() > 1) {
if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN && !startedTracking && !maybeStartTracking) {
BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1);
if (!currentFragment.swipeBackEnabled) {
return false;
}
2014-11-07 11:23:17 +01:00
startedTrackingPointerId = ev.getPointerId(0);
maybeStartTracking = true;
startedTrackingX = (int) ev.getX();
startedTrackingY = (int) ev.getY();
if (velocityTracker != null) {
velocityTracker.clear();
}
} else if (ev != null && ev.getAction() == MotionEvent.ACTION_MOVE && ev.getPointerId(0) == startedTrackingPointerId) {
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain();
}
int dx = Math.max(0, (int) (ev.getX() - startedTrackingX));
int dy = Math.abs((int) ev.getY() - startedTrackingY);
velocityTracker.addMovement(ev);
if (maybeStartTracking && !startedTracking && dx >= AndroidUtilities.getPixelsInCM(0.4f, true) && Math.abs(dx) / 3 > dy) {
prepareForMoving(ev);
2014-11-07 11:23:17 +01:00
} else if (startedTracking) {
if (!beginTrackingSent) {
if (parentActivity.getCurrentFocus() != null) {
AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus());
}
BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1);
currentFragment.onBeginSlide();
beginTrackingSent = true;
}
ViewProxy.setTranslationX(containerView, dx);
2014-11-11 23:16:17 +01:00
setInnerTranslationX(dx);
}
2014-11-07 11:23:17 +01:00
} else if (ev != null && ev.getPointerId(0) == startedTrackingPointerId && (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_POINTER_UP)) {
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain();
}
2014-11-07 11:23:17 +01:00
velocityTracker.computeCurrentVelocity(1000);
if (!startedTracking && fragmentsStack.get(fragmentsStack.size() - 1).swipeBackEnabled) {
2014-11-07 11:23:17 +01:00
float velX = velocityTracker.getXVelocity();
float velY = velocityTracker.getYVelocity();
if (velX >= 3500 && velX > Math.abs(velY)) {
2014-11-07 11:23:17 +01:00
prepareForMoving(ev);
if (!beginTrackingSent) {
2014-11-11 23:16:17 +01:00
if (((Activity) getContext()).getCurrentFocus() != null) {
AndroidUtilities.hideKeyboard(((Activity) getContext()).getCurrentFocus());
}
beginTrackingSent = true;
}
}
2014-11-07 11:23:17 +01:00
}
if (startedTracking) {
float x = ViewProxy.getX(containerView);
AnimatorSetProxy animatorSet = new AnimatorSetProxy();
float velX = velocityTracker.getXVelocity();
float velY = velocityTracker.getYVelocity();
final boolean backAnimation = x < containerView.getMeasuredWidth() / 3.0f && (velX < 3500 || velX < velY);
2015-05-21 23:27:27 +02:00
float distToMove;
2014-11-07 11:23:17 +01:00
if (!backAnimation) {
distToMove = containerView.getMeasuredWidth() - x;
animatorSet.playTogether(
2015-06-29 19:12:11 +02:00
ObjectAnimatorProxy.ofFloat(containerView, "translationX", containerView.getMeasuredWidth()),
2014-11-11 23:16:17 +01:00
ObjectAnimatorProxy.ofFloat(this, "innerTranslationX", (float)containerView.getMeasuredWidth())
2014-11-07 11:23:17 +01:00
);
} else {
distToMove = x;
animatorSet.playTogether(
2015-06-29 19:12:11 +02:00
ObjectAnimatorProxy.ofFloat(containerView, "translationX", 0),
2014-11-11 23:16:17 +01:00
ObjectAnimatorProxy.ofFloat(this, "innerTranslationX", 0.0f)
2014-11-07 11:23:17 +01:00
);
}
2014-11-07 11:23:17 +01:00
animatorSet.setDuration(Math.max((int) (200.0f / containerView.getMeasuredWidth() * distToMove), 50));
animatorSet.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Object animator) {
onSlideAnimationEnd(backAnimation);
}
@Override
public void onAnimationCancel(Object animator) {
onSlideAnimationEnd(backAnimation);
}
});
animatorSet.start();
animationInProgress = true;
} else {
maybeStartTracking = false;
startedTracking = false;
}
if (velocityTracker != null) {
velocityTracker.recycle();
velocityTracker = null;
}
} else if (ev == null) {
maybeStartTracking = false;
startedTracking = false;
2014-11-07 11:23:17 +01:00
if (velocityTracker != null) {
velocityTracker.recycle();
velocityTracker = null;
}
}
}
2014-06-04 20:57:11 +02:00
return startedTracking;
}
2014-06-04 20:57:11 +02:00
return false;
}
public void onBackPressed() {
if (startedTracking || checkTransitionAnimation() || fragmentsStack.isEmpty()) {
return;
}
2014-11-11 23:16:17 +01:00
if (currentActionBar != null && currentActionBar.isSearchFieldVisible) {
currentActionBar.closeSearchField();
return;
}
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
if (lastFragment.onBackPressed()) {
if (!fragmentsStack.isEmpty()) {
2014-06-13 17:03:06 +02:00
closeLastFragment(true);
}
}
}
public void onLowMemory() {
for (BaseFragment fragment : fragmentsStack) {
fragment.onLowMemory();
}
}
2014-11-11 23:16:17 +01:00
private void onAnimationEndCheck(boolean byCheck) {
onCloseAnimationEnd(false);
onOpenAnimationEnd(false);
2014-11-11 23:16:17 +01:00
if (currentAnimation != null) {
if (byCheck) {
currentAnimation.cancel();
}
currentAnimation = null;
}
ViewProxy.setAlpha(this, 1.0f);
ViewProxy.setAlpha(containerView, 1.0f);
ViewProxy.setScaleX(containerView, 1.0f);
ViewProxy.setScaleY(containerView, 1.0f);
ViewProxy.setAlpha(containerViewBack, 1.0f);
ViewProxy.setScaleX(containerViewBack, 1.0f);
ViewProxy.setScaleY(containerViewBack, 1.0f);
}
public boolean checkTransitionAnimation() {
if (transitionAnimationInProgress && transitionAnimationStartTime < System.currentTimeMillis() - 1000) {
2014-11-11 23:16:17 +01:00
onAnimationEndCheck(true);
}
return transitionAnimationInProgress;
}
2014-06-13 00:37:05 +02:00
private void presentFragmentInternalRemoveOld(boolean removeLast, final BaseFragment fragment) {
if (fragment == null) {
return;
}
fragment.onPause();
if (removeLast) {
fragment.onFragmentDestroy();
fragment.setParentLayout(null);
fragmentsStack.remove(fragment);
} else {
if (fragment.fragmentView != null) {
ViewGroup parent = (ViewGroup) fragment.fragmentView.getParent();
if (parent != null) {
parent.removeView(fragment.fragmentView);
}
}
2014-11-11 23:16:17 +01:00
if (fragment.needAddActionBar() && fragment.actionBar != null) {
ViewGroup parent = (ViewGroup) fragment.actionBar.getParent();
if (parent != null) {
parent.removeView(fragment.actionBar);
}
}
}
2015-06-29 19:12:11 +02:00
containerViewBack.setVisibility(View.GONE);
}
public boolean presentFragment(BaseFragment fragment) {
2014-09-28 15:37:26 +02:00
return presentFragment(fragment, false, false, true);
}
public boolean presentFragment(BaseFragment fragment, boolean removeLast) {
2014-09-28 15:37:26 +02:00
return presentFragment(fragment, removeLast, false, true);
}
private void startLayoutAnimation(final boolean open, final boolean first) {
if (first) {
animationProgress = 0.0f;
lastFrameTime = System.nanoTime() / 1000000;
2015-06-29 19:12:11 +02:00
if (Build.VERSION.SDK_INT >= 11) {
if (open) {
containerView.setLayerType(LAYER_TYPE_HARDWARE, null);
} else {
containerViewBack.setLayerType(LAYER_TYPE_HARDWARE, null);
}
}
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (first) {
transitionAnimationStartTime = System.currentTimeMillis();
}
long newTime = System.nanoTime() / 1000000;
long dt = newTime - lastFrameTime;
if (dt > 18) {
dt = 18;
}
lastFrameTime = newTime;
animationProgress += dt / 150.0f;
if (animationProgress > 1.0f) {
animationProgress = 1.0f;
}
float interpolated = decelerateInterpolator.getInterpolation(animationProgress);
if (open) {
ViewProxy.setAlpha(containerView, interpolated);
ViewProxy.setTranslationX(containerView, AndroidUtilities.dp(48) * (1.0f - interpolated));
} else {
ViewProxy.setAlpha(containerViewBack, 1.0f - interpolated);
ViewProxy.setTranslationX(containerViewBack, AndroidUtilities.dp(48) * interpolated);
}
if (animationProgress < 1) {
startLayoutAnimation(open, false);
} else {
onAnimationEndCheck(false);
}
}
});
}
2014-09-28 15:37:26 +02:00
public boolean presentFragment(final BaseFragment fragment, final boolean removeLast, boolean forceWithoutAnimation, boolean check) {
if (checkTransitionAnimation() || delegate != null && check && !delegate.needPresentFragment(fragment, removeLast, forceWithoutAnimation, this) || !fragment.onFragmentCreate()) {
return false;
}
if (parentActivity.getCurrentFocus() != null) {
AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus());
}
2014-11-11 23:16:17 +01:00
boolean needAnimation = Build.VERSION.SDK_INT > 10 && !forceWithoutAnimation && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true);
final BaseFragment currentFragment = !fragmentsStack.isEmpty() ? fragmentsStack.get(fragmentsStack.size() - 1) : null;
fragment.setParentLayout(this);
2015-04-09 20:00:14 +02:00
View fragmentView = fragment.fragmentView;
if (fragmentView == null) {
2015-07-22 20:56:37 +02:00
fragmentView = fragment.createView(parentActivity);
2015-04-09 20:00:14 +02:00
} else {
ViewGroup parent = (ViewGroup) fragmentView.getParent();
if (parent != null) {
parent.removeView(fragmentView);
}
}
2014-11-11 23:16:17 +01:00
if (fragment.needAddActionBar() && fragment.actionBar != null) {
2014-11-17 03:44:57 +01:00
if (removeActionBarExtraHeight) {
fragment.actionBar.setOccupyStatusBar(false);
}
2014-11-19 11:32:27 +01:00
ViewGroup parent = (ViewGroup) fragment.actionBar.getParent();
if (parent != null) {
parent.removeView(fragment.actionBar);
}
2014-11-11 23:16:17 +01:00
containerViewBack.addView(fragment.actionBar);
2014-11-18 06:01:04 +01:00
fragment.actionBar.setTitleOverlayText(titleOverlayText);
2014-11-11 23:16:17 +01:00
}
2014-11-21 11:59:05 +01:00
containerViewBack.addView(fragmentView);
ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
fragmentView.setLayoutParams(layoutParams);
fragmentsStack.add(fragment);
fragment.onResume();
2014-11-11 23:16:17 +01:00
currentActionBar = fragment.actionBar;
2015-04-09 20:00:14 +02:00
if (!fragment.hasOwnBackground && fragmentView.getBackground() == null) {
fragmentView.setBackgroundColor(0xffffffff);
}
2014-11-11 23:16:17 +01:00
LinearLayoutContainer temp = containerView;
containerView = containerViewBack;
containerViewBack = temp;
containerView.setVisibility(View.VISIBLE);
setInnerTranslationX(0);
2014-11-11 23:16:17 +01:00
bringChildToFront(containerView);
if (!needAnimation) {
presentFragmentInternalRemoveOld(removeLast, currentFragment);
2014-09-28 15:37:26 +02:00
if (backgroundView != null) {
backgroundView.setVisibility(VISIBLE);
}
}
if (needAnimation) {
if (useAlphaAnimations && fragmentsStack.size() == 1) {
presentFragmentInternalRemoveOld(removeLast, currentFragment);
2014-11-11 23:16:17 +01:00
transitionAnimationStartTime = System.currentTimeMillis();
transitionAnimationInProgress = true;
onOpenAnimationEndRunnable = new Runnable() {
@Override
public void run() {
fragment.onOpenAnimationEnd();
2015-06-29 19:12:11 +02:00
fragment.onBecomeFullyVisible();
}
};
2015-02-01 19:51:02 +01:00
ArrayList<Object> animators = new ArrayList<>();
2014-11-11 23:16:17 +01:00
animators.add(ObjectAnimatorProxy.ofFloat(this, "alpha", 0.0f, 1.0f));
if (backgroundView != null) {
backgroundView.setVisibility(VISIBLE);
2014-11-11 23:16:17 +01:00
animators.add(ObjectAnimatorProxy.ofFloat(backgroundView, "alpha", 0.0f, 1.0f));
2014-06-13 17:03:06 +02:00
}
2014-11-11 23:16:17 +01:00
2015-05-21 23:27:27 +02:00
fragment.onOpenAnimationStart();
2014-11-11 23:16:17 +01:00
currentAnimation = new AnimatorSetProxy();
currentAnimation.playTogether(animators);
currentAnimation.setInterpolator(accelerateDecelerateInterpolator);
2014-11-11 23:16:17 +01:00
currentAnimation.setDuration(200);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Object animation) {
onAnimationEndCheck(false);
}
2014-12-04 21:27:06 +01:00
@Override
public void onAnimationCancel(Object animation) {
onAnimationEndCheck(false);
}
2014-11-11 23:16:17 +01:00
});
currentAnimation.start();
} else {
transitionAnimationStartTime = System.currentTimeMillis();
transitionAnimationInProgress = true;
onOpenAnimationEndRunnable = new Runnable() {
@Override
public void run() {
2015-06-29 19:12:11 +02:00
if (Build.VERSION.SDK_INT >= 18) {
containerView.setLayerType(LAYER_TYPE_NONE, null);
}
presentFragmentInternalRemoveOld(removeLast, currentFragment);
fragment.onOpenAnimationEnd();
2015-06-29 19:12:11 +02:00
fragment.onBecomeFullyVisible();
2014-11-21 11:59:05 +01:00
ViewProxy.setTranslationX(containerView, 0);
}
};
ViewProxy.setAlpha(containerView, 0.0f);
ViewProxy.setTranslationX(containerView, 48.0f);
2015-05-21 23:27:27 +02:00
fragment.onOpenAnimationStart();
startLayoutAnimation(true, true);
/*currentAnimation = new AnimatorSetProxy();
2014-11-11 23:16:17 +01:00
currentAnimation.playTogether(
ObjectAnimatorProxy.ofFloat(containerView, "alpha", 0.0f, 1.0f),
2014-11-21 01:14:44 +01:00
ObjectAnimatorProxy.ofFloat(containerView, "translationX", AndroidUtilities.dp(48), 0));
currentAnimation.setInterpolator(decelerateInterpolator);
2014-11-11 23:16:17 +01:00
currentAnimation.setDuration(200);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationStart(Object animation) {
transitionAnimationStartTime = System.currentTimeMillis();
}
2014-11-11 23:16:17 +01:00
@Override
public void onAnimationEnd(Object animation) {
onAnimationEndCheck(false);
}
2014-12-04 21:27:06 +01:00
@Override
public void onAnimationCancel(Object animation) {
onAnimationEndCheck(false);
}
2014-11-11 23:16:17 +01:00
});
currentAnimation.start();*/
}
} else {
2014-11-17 23:04:31 +01:00
if (backgroundView != null) {
ViewProxy.setAlpha(backgroundView, 1.0f);
backgroundView.setVisibility(VISIBLE);
}
2015-05-21 23:27:27 +02:00
fragment.onOpenAnimationStart();
fragment.onOpenAnimationEnd();
2015-06-29 19:12:11 +02:00
fragment.onBecomeFullyVisible();
}
return true;
}
public boolean addFragmentToStack(BaseFragment fragment) {
return addFragmentToStack(fragment, -1);
}
public boolean addFragmentToStack(BaseFragment fragment, int position) {
if (delegate != null && !delegate.needAddFragmentToStack(fragment, this) || !fragment.onFragmentCreate()) {
return false;
}
fragment.setParentLayout(this);
if (position == -1) {
if (!fragmentsStack.isEmpty()) {
BaseFragment previousFragment = fragmentsStack.get(fragmentsStack.size() - 1);
previousFragment.onPause();
if (previousFragment.actionBar != null) {
ViewGroup parent = (ViewGroup) previousFragment.actionBar.getParent();
if (parent != null) {
parent.removeView(previousFragment.actionBar);
}
}
if (previousFragment.fragmentView != null) {
ViewGroup parent = (ViewGroup) previousFragment.fragmentView.getParent();
if (parent != null) {
parent.removeView(previousFragment.fragmentView);
}
}
}
fragmentsStack.add(fragment);
} else {
fragmentsStack.add(position, fragment);
}
return true;
}
private void closeLastFragmentInternalRemoveOld(BaseFragment fragment) {
fragment.onPause();
fragment.onFragmentDestroy();
fragment.setParentLayout(null);
fragmentsStack.remove(fragment);
2015-06-29 19:12:11 +02:00
containerViewBack.setVisibility(View.GONE);
2014-11-11 23:16:17 +01:00
bringChildToFront(containerView);
}
2014-06-13 17:03:06 +02:00
public void closeLastFragment(boolean animated) {
if (delegate != null && !delegate.needCloseLastFragment(this) || checkTransitionAnimation() || fragmentsStack.isEmpty()) {
return;
}
if (parentActivity.getCurrentFocus() != null) {
AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus());
}
setInnerTranslationX(0);
2014-11-11 23:16:17 +01:00
boolean needAnimation = Build.VERSION.SDK_INT > 10 && animated && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true);
final BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1);
BaseFragment previousFragment = null;
if (fragmentsStack.size() > 1) {
previousFragment = fragmentsStack.get(fragmentsStack.size() - 2);
}
if (previousFragment != null) {
2014-11-11 23:16:17 +01:00
LinearLayoutContainer temp = containerView;
containerView = containerViewBack;
containerViewBack = temp;
containerView.setVisibility(View.VISIBLE);
previousFragment.setParentLayout(this);
2015-04-09 20:00:14 +02:00
View fragmentView = previousFragment.fragmentView;
if (fragmentView == null) {
2015-07-22 20:56:37 +02:00
fragmentView = previousFragment.createView(parentActivity);
2015-04-09 20:00:14 +02:00
} else {
ViewGroup parent = (ViewGroup) fragmentView.getParent();
if (parent != null) {
parent.removeView(fragmentView);
}
}
2014-11-11 23:16:17 +01:00
if (previousFragment.needAddActionBar() && previousFragment.actionBar != null) {
2014-11-17 03:44:57 +01:00
if (removeActionBarExtraHeight) {
previousFragment.actionBar.setOccupyStatusBar(false);
}
2014-11-19 11:32:27 +01:00
ViewGroup parent = (ViewGroup) previousFragment.actionBar.getParent();
if (parent != null) {
parent.removeView(previousFragment.actionBar);
}
2014-11-11 23:16:17 +01:00
containerView.addView(previousFragment.actionBar);
2014-11-18 06:01:04 +01:00
previousFragment.actionBar.setTitleOverlayText(titleOverlayText);
2014-11-11 23:16:17 +01:00
}
containerView.addView(fragmentView);
ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
fragmentView.setLayoutParams(layoutParams);
2015-06-29 19:12:11 +02:00
previousFragment.onOpenAnimationStart();
previousFragment.onResume();
2014-11-11 23:16:17 +01:00
currentActionBar = previousFragment.actionBar;
2015-04-09 20:00:14 +02:00
if (!previousFragment.hasOwnBackground && fragmentView.getBackground() == null) {
fragmentView.setBackgroundColor(0xffffffff);
}
if (!needAnimation) {
closeLastFragmentInternalRemoveOld(currentFragment);
}
if (needAnimation) {
transitionAnimationStartTime = System.currentTimeMillis();
transitionAnimationInProgress = true;
2015-06-29 19:12:11 +02:00
final BaseFragment previousFragmentFinal = previousFragment;
onCloseAnimationEndRunnable = new Runnable() {
@Override
public void run() {
2015-06-29 19:12:11 +02:00
if (Build.VERSION.SDK_INT >= 18) {
containerViewBack.setLayerType(LAYER_TYPE_NONE, null);
}
closeLastFragmentInternalRemoveOld(currentFragment);
2014-11-21 01:14:44 +01:00
ViewProxy.setTranslationX(containerViewBack, 0);
2015-06-29 19:12:11 +02:00
previousFragmentFinal.onOpenAnimationEnd();
previousFragmentFinal.onBecomeFullyVisible();
}
};
startLayoutAnimation(false, true);
2014-11-11 23:16:17 +01:00
/*currentAnimation = new AnimatorSetProxy();
2014-11-11 23:16:17 +01:00
currentAnimation.playTogether(
ObjectAnimatorProxy.ofFloat(containerViewBack, "alpha", 1.0f, 0.0f),
2014-11-21 01:14:44 +01:00
ObjectAnimatorProxy.ofFloat(containerViewBack, "translationX", 0, AndroidUtilities.dp(48)));
currentAnimation.setInterpolator(decelerateInterpolator);
2014-11-11 23:16:17 +01:00
currentAnimation.setDuration(200);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationStart(Object animation) {
transitionAnimationStartTime = System.currentTimeMillis();
}
2014-11-11 23:16:17 +01:00
@Override
public void onAnimationEnd(Object animation) {
onAnimationEndCheck(false);
}
2014-12-04 21:27:06 +01:00
@Override
public void onAnimationCancel(Object animation) {
onAnimationEndCheck(false);
}
2014-11-11 23:16:17 +01:00
});
currentAnimation.start();*/
2015-06-29 19:12:11 +02:00
} else {
previousFragment.onOpenAnimationEnd();
previousFragment.onBecomeFullyVisible();
}
} else {
2014-11-17 03:44:57 +01:00
if (useAlphaAnimations) {
transitionAnimationStartTime = System.currentTimeMillis();
transitionAnimationInProgress = true;
2014-11-11 23:16:17 +01:00
onCloseAnimationEndRunnable = new Runnable() {
@Override
public void run() {
removeFragmentFromStack(currentFragment);
2015-06-29 19:12:11 +02:00
setVisibility(GONE);
if (backgroundView != null) {
2015-06-29 19:12:11 +02:00
backgroundView.setVisibility(GONE);
}
2014-11-17 03:44:57 +01:00
if (drawerLayoutContainer != null) {
drawerLayoutContainer.setAllowOpenDrawer(true, false);
2014-11-17 03:44:57 +01:00
}
}
};
2014-11-11 23:16:17 +01:00
2015-02-01 19:51:02 +01:00
ArrayList<Object> animators = new ArrayList<>();
2014-11-11 23:16:17 +01:00
animators.add(ObjectAnimatorProxy.ofFloat(this, "alpha", 1.0f, 0.0f));
if (backgroundView != null) {
animators.add(ObjectAnimatorProxy.ofFloat(backgroundView, "alpha", 1.0f, 0.0f));
}
currentAnimation = new AnimatorSetProxy();
currentAnimation.playTogether(animators);
currentAnimation.setInterpolator(accelerateDecelerateInterpolator);
2014-11-11 23:16:17 +01:00
currentAnimation.setDuration(200);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationStart(Object animation) {
transitionAnimationStartTime = System.currentTimeMillis();
}
2014-11-11 23:16:17 +01:00
@Override
public void onAnimationEnd(Object animation) {
onAnimationEndCheck(false);
}
2014-12-04 21:27:06 +01:00
@Override
public void onAnimationCancel(Object animation) {
onAnimationEndCheck(false);
}
2014-11-11 23:16:17 +01:00
});
currentAnimation.start();
} else {
removeFragmentFromStack(currentFragment);
2015-06-29 19:12:11 +02:00
setVisibility(GONE);
if (backgroundView != null) {
2015-06-29 19:12:11 +02:00
backgroundView.setVisibility(GONE);
2014-06-13 17:03:06 +02:00
}
}
}
}
public void showLastFragment() {
if (fragmentsStack.isEmpty()) {
return;
}
BaseFragment previousFragment = fragmentsStack.get(fragmentsStack.size() - 1);
previousFragment.setParentLayout(this);
2015-04-09 20:00:14 +02:00
View fragmentView = previousFragment.fragmentView;
if (fragmentView == null) {
2015-07-22 20:56:37 +02:00
fragmentView = previousFragment.createView(parentActivity);
2015-04-09 20:00:14 +02:00
} else {
ViewGroup parent = (ViewGroup) fragmentView.getParent();
if (parent != null) {
parent.removeView(fragmentView);
}
}
2014-11-11 23:16:17 +01:00
if (previousFragment.needAddActionBar() && previousFragment.actionBar != null) {
2014-11-17 03:44:57 +01:00
if (removeActionBarExtraHeight) {
previousFragment.actionBar.setOccupyStatusBar(false);
}
2014-11-17 23:04:31 +01:00
ViewGroup parent = (ViewGroup) previousFragment.actionBar.getParent();
if (parent != null) {
parent.removeView(previousFragment.actionBar);
}
2014-11-11 23:16:17 +01:00
containerView.addView(previousFragment.actionBar);
2014-11-18 06:01:04 +01:00
previousFragment.actionBar.setTitleOverlayText(titleOverlayText);
2014-11-11 23:16:17 +01:00
}
containerView.addView(fragmentView);
ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
fragmentView.setLayoutParams(layoutParams);
previousFragment.onResume();
2014-11-11 23:16:17 +01:00
currentActionBar = previousFragment.actionBar;
2015-04-09 20:00:14 +02:00
if (!previousFragment.hasOwnBackground && fragmentView.getBackground() == null) {
fragmentView.setBackgroundColor(0xffffffff);
}
}
public void removeFragmentFromStack(BaseFragment fragment) {
fragment.onPause();
fragment.onFragmentDestroy();
fragment.setParentLayout(null);
fragmentsStack.remove(fragment);
}
public void removeAllFragments() {
for (int a = 0; a < fragmentsStack.size(); a++) {
removeFragmentFromStack(fragmentsStack.get(a));
a--;
}
}
public void rebuildAllFragmentViews(boolean last) {
for (int a = 0; a < fragmentsStack.size() - (last ? 0 : 1); a++) {
2015-06-29 19:12:11 +02:00
fragmentsStack.get(a).clearViews();
fragmentsStack.get(a).setParentLayout(this);
}
if (delegate != null) {
delegate.onRebuildAllFragments(this);
}
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
2014-11-11 23:16:17 +01:00
if (keyCode == KeyEvent.KEYCODE_MENU && !checkTransitionAnimation() && !startedTracking && currentActionBar != null) {
currentActionBar.onMenuButtonPressed();
}
return super.onKeyUp(keyCode, event);
}
2015-01-02 23:15:07 +01:00
public void onActionModeStarted(Object mode) {
2014-11-11 23:16:17 +01:00
if (currentActionBar != null) {
currentActionBar.setVisibility(GONE);
}
inActionMode = true;
}
2015-01-02 23:15:07 +01:00
public void onActionModeFinished(Object mode) {
2014-11-11 23:16:17 +01:00
if (currentActionBar != null) {
currentActionBar.setVisibility(VISIBLE);
}
inActionMode = false;
}
2014-06-13 17:03:06 +02:00
private void onCloseAnimationEnd(boolean post) {
if (transitionAnimationInProgress && onCloseAnimationEndRunnable != null) {
transitionAnimationInProgress = false;
transitionAnimationStartTime = 0;
if (post) {
new Handler().post(new Runnable() {
public void run() {
onCloseAnimationEndRunnable.run();
onCloseAnimationEndRunnable = null;
}
});
} else {
onCloseAnimationEndRunnable.run();
onCloseAnimationEndRunnable = null;
}
}
}
private void onOpenAnimationEnd(boolean post) {
if (transitionAnimationInProgress && onOpenAnimationEndRunnable != null) {
transitionAnimationInProgress = false;
transitionAnimationStartTime = 0;
if (post) {
new Handler().post(new Runnable() {
public void run() {
onOpenAnimationEndRunnable.run();
onOpenAnimationEndRunnable = null;
}
});
} else {
onOpenAnimationEndRunnable.run();
onOpenAnimationEndRunnable = null;
}
}
}
public void startActivityForResult(final Intent intent, final int requestCode) {
2014-10-01 00:36:18 +02:00
if (parentActivity == null) {
return;
}
2014-06-13 17:03:06 +02:00
if (transitionAnimationInProgress) {
2014-11-11 23:16:17 +01:00
if (currentAnimation != null) {
currentAnimation.cancel();
currentAnimation = null;
}
2014-06-13 17:03:06 +02:00
if (onCloseAnimationEndRunnable != null) {
onCloseAnimationEnd(false);
} else if (onOpenAnimationEndRunnable != null) {
onOpenAnimationEnd(false);
}
containerView.invalidate();
if (intent != null) {
parentActivity.startActivityForResult(intent, requestCode);
}
2014-06-13 17:03:06 +02:00
} else {
if (intent != null) {
parentActivity.startActivityForResult(intent, requestCode);
}
}
}
public void setUseAlphaAnimations(boolean value) {
useAlphaAnimations = value;
}
public void setBackgroundView(View view) {
backgroundView = view;
}
public void setDrawerLayoutContainer(DrawerLayoutContainer layout) {
2014-11-07 11:23:17 +01:00
drawerLayoutContainer = layout;
}
public DrawerLayoutContainer getDrawerLayoutContainer() {
return drawerLayoutContainer;
}
2014-11-17 03:44:57 +01:00
public void setRemoveActionBarExtraHeight(boolean value) {
removeActionBarExtraHeight = value;
}
2014-11-18 06:01:04 +01:00
public void setTitleOverlayText(String text) {
titleOverlayText = text;
for (BaseFragment fragment : fragmentsStack) {
if (fragment.actionBar != null) {
fragment.actionBar.setTitleOverlayText(titleOverlayText);
}
}
}
}