public void showLastFragment() {
   if (fragmentsStack.isEmpty()) {
     return;
   }
   BaseFragment previousFragment = fragmentsStack.get(fragmentsStack.size() - 1);
   previousFragment.setParentLayout(this);
   View fragmentView = previousFragment.createView(parentActivity.getLayoutInflater());
   if (previousFragment.needAddActionBar() && previousFragment.actionBar != null) {
     if (removeActionBarExtraHeight) {
       previousFragment.actionBar.setOccupyStatusBar(false);
     }
     ViewGroup parent = (ViewGroup) previousFragment.actionBar.getParent();
     if (parent != null) {
       parent.removeView(previousFragment.actionBar);
     }
     containerView.addView(previousFragment.actionBar);
     previousFragment.actionBar.setTitleOverlayText(titleOverlayText);
   }
   containerView.addView(fragmentView);
   ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
   layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
   layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
   fragmentView.setLayoutParams(layoutParams);
   previousFragment.onResume();
   currentActionBar = previousFragment.actionBar;
   if (fragmentView.getBackground() == null) {
     fragmentView.setBackgroundColor(0xffffffff);
   }
 }
 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);
       }
     }
     if (fragment.needAddActionBar() && fragment.actionBar != null) {
       ViewGroup parent = (ViewGroup) fragment.actionBar.getParent();
       if (parent != null) {
         parent.removeView(fragment.actionBar);
       }
     }
   }
   containerViewBack.setVisibility(View.GONE);
 }
 private void closeLastFragmentInternalRemoveOld(BaseFragment fragment) {
   fragment.onPause();
   fragment.onFragmentDestroy();
   fragment.setParentLayout(null);
   fragmentsStack.remove(fragment);
   containerViewBack.setVisibility(View.GONE);
   bringChildToFront(containerView);
 }
  public void init(ArrayList<BaseFragment> stack) {
    fragmentsStack = stack;
    containerViewBack = new LinearLayoutContainer(parentActivity);
    addView(containerViewBack);
    FrameLayout.LayoutParams layoutParams =
        (FrameLayout.LayoutParams) containerViewBack.getLayoutParams();
    layoutParams.width = LayoutParams.MATCH_PARENT;
    layoutParams.height = LayoutParams.MATCH_PARENT;
    layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
    containerViewBack.setLayoutParams(layoutParams);

    containerView = new LinearLayoutContainer(parentActivity);
    addView(containerView);
    layoutParams = (FrameLayout.LayoutParams) containerView.getLayoutParams();
    layoutParams.width = LayoutParams.MATCH_PARENT;
    layoutParams.height = LayoutParams.MATCH_PARENT;
    layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
    containerView.setLayoutParams(layoutParams);

    for (BaseFragment fragment : fragmentsStack) {
      fragment.setParentLayout(this);
    }
  }
  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);
    View fragmentView = lastFragment.createView(parentActivity.getLayoutInflater());
    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);
      }
      if (removeActionBarExtraHeight) {
        lastFragment.actionBar.setOccupyStatusBar(false);
      }
      containerViewBack.addView(lastFragment.actionBar);
      lastFragment.actionBar.setTitleOverlayText(titleOverlayText);
    }
    containerViewBack.addView(fragmentView);
    ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
    layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
    layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
    fragmentView.setLayoutParams(layoutParams);
    if (fragmentView.getBackground() == null) {
      fragmentView.setBackgroundColor(0xffffffff);
    }
    lastFragment.onResume();

    // AndroidUtilities.lockOrientation(parentActivity);
  }
  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);

      LinearLayoutContainer temp = containerView;
      containerView = containerViewBack;
      containerViewBack = temp;
      bringChildToFront(containerView);

      lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
      currentActionBar = lastFragment.actionBar;
      lastFragment.onResume();
    } 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);
        }
      }
      if (lastFragment.needAddActionBar() && lastFragment.actionBar != null) {
        ViewGroup parent = (ViewGroup) lastFragment.actionBar.getParent();
        if (parent != null) {
          parent.removeView(lastFragment.actionBar);
        }
      }
    }
    containerViewBack.setVisibility(View.GONE);
    // AndroidUtilities.unlockOrientation(parentActivity);
    startedTracking = false;
    animationInProgress = false;

    ViewProxy.setTranslationX(containerView, 0);
    ViewProxy.setTranslationX(containerViewBack, 0);
    setInnerTranslationX(0);
  }
 public void startActivityForResult(final Intent intent, final int requestCode) {
   if (parentActivity == null) {
     return;
   }
   if (transitionAnimationInProgress) {
     if (currentAnimation != null) {
       currentAnimation.cancel();
       currentAnimation = null;
     }
     if (onCloseAnimationEndRunnable != null) {
       onCloseAnimationEnd(false);
     } else if (onOpenAnimationEndRunnable != null) {
       onOpenAnimationEnd(false);
     }
     containerView.invalidate();
     if (intent != null) {
       parentActivity.startActivityForResult(intent, requestCode);
     }
   } else {
     if (intent != null) {
       parentActivity.startActivityForResult(intent, requestCode);
     }
   }
 }
  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);
    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) {
      LinearLayoutContainer temp = containerView;
      containerView = containerViewBack;
      containerViewBack = temp;
      containerView.setVisibility(View.VISIBLE);

      previousFragment.setParentLayout(this);
      View fragmentView = previousFragment.createView(parentActivity.getLayoutInflater());
      if (previousFragment.needAddActionBar() && previousFragment.actionBar != null) {
        if (removeActionBarExtraHeight) {
          previousFragment.actionBar.setOccupyStatusBar(false);
        }
        ViewGroup parent = (ViewGroup) previousFragment.actionBar.getParent();
        if (parent != null) {
          parent.removeView(previousFragment.actionBar);
        }
        containerView.addView(previousFragment.actionBar);
        previousFragment.actionBar.setTitleOverlayText(titleOverlayText);
      }
      containerView.addView(fragmentView);
      ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
      layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
      layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
      fragmentView.setLayoutParams(layoutParams);
      previousFragment.onResume();
      currentActionBar = previousFragment.actionBar;
      if (fragmentView.getBackground() == null) {
        fragmentView.setBackgroundColor(0xffffffff);
      }

      if (!needAnimation) {
        closeLastFragmentInternalRemoveOld(currentFragment);
      }

      if (needAnimation) {
        transitionAnimationStartTime = System.currentTimeMillis();
        transitionAnimationInProgress = true;
        onCloseAnimationEndRunnable =
            new Runnable() {
              @Override
              public void run() {
                closeLastFragmentInternalRemoveOld(currentFragment);
                ViewProxy.setTranslationX(containerViewBack, 0);
              }
            };

        currentAnimation = new AnimatorSetProxy();
        currentAnimation.playTogether(
            ObjectAnimatorProxy.ofFloat(containerViewBack, "alpha", 1.0f, 0.0f),
            ObjectAnimatorProxy.ofFloat(
                containerViewBack, "translationX", 0, AndroidUtilities.dp(48)));
        currentAnimation.setInterpolator(new DecelerateInterpolator(1.5f));
        currentAnimation.setDuration(200);
        currentAnimation.addListener(
            new AnimatorListenerAdapterProxy() {
              @Override
              public void onAnimationStart(Object animation) {
                transitionAnimationStartTime = System.currentTimeMillis();
              }

              @Override
              public void onAnimationEnd(Object animation) {
                onAnimationEndCheck(false);
              }

              @Override
              public void onAnimationCancel(Object animation) {
                onAnimationEndCheck(false);
              }
            });
        currentAnimation.start();
      }
    } else {
      if (useAlphaAnimations) {
        transitionAnimationStartTime = System.currentTimeMillis();
        transitionAnimationInProgress = true;

        onCloseAnimationEndRunnable =
            new Runnable() {
              @Override
              public void run() {
                removeFragmentFromStack(currentFragment);
                setVisibility(GONE);
                if (backgroundView != null) {
                  backgroundView.setVisibility(GONE);
                }
                if (drawerLayoutContainer != null) {
                  drawerLayoutContainer.setAllowOpenDrawer(true);
                }
              }
            };

        ArrayList<Object> animators = new ArrayList<>();
        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(new AccelerateDecelerateInterpolator());
        currentAnimation.setDuration(200);
        currentAnimation.addListener(
            new AnimatorListenerAdapterProxy() {
              @Override
              public void onAnimationStart(Object animation) {
                transitionAnimationStartTime = System.currentTimeMillis();
              }

              @Override
              public void onAnimationEnd(Object animation) {
                onAnimationEndCheck(false);
              }

              @Override
              public void onAnimationCancel(Object animation) {
                onAnimationEndCheck(false);
              }
            });
        currentAnimation.start();
      } else {
        removeFragmentFromStack(currentFragment);
        setVisibility(GONE);
        if (backgroundView != null) {
          backgroundView.setVisibility(GONE);
        }
      }
    }
  }
  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());
      NotificationCenter.getInstance().postNotificationName(NotificationCenter.hideEmojiKeyboard);
    }
    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);
    View fragmentView = fragment.createView(parentActivity.getLayoutInflater());
    if (fragment.needAddActionBar() && fragment.actionBar != null) {
      if (removeActionBarExtraHeight) {
        fragment.actionBar.setOccupyStatusBar(false);
      }
      ViewGroup parent = (ViewGroup) fragment.actionBar.getParent();
      if (parent != null) {
        parent.removeView(fragment.actionBar);
      }
      containerViewBack.addView(fragment.actionBar);
      fragment.actionBar.setTitleOverlayText(titleOverlayText);
    }

    containerViewBack.addView(fragmentView);
    ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
    layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
    layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
    fragmentView.setLayoutParams(layoutParams);
    fragmentsStack.add(fragment);
    fragment.onResume();
    currentActionBar = fragment.actionBar;
    if (fragmentView.getBackground() == null) {
      fragmentView.setBackgroundColor(0xffffffff);
    }

    LinearLayoutContainer temp = containerView;
    containerView = containerViewBack;
    containerViewBack = temp;
    containerView.setVisibility(View.VISIBLE);
    setInnerTranslationX(0);

    bringChildToFront(containerView);

    if (!needAnimation) {
      presentFragmentInternalRemoveOld(removeLast, currentFragment);
      if (backgroundView != null) {
        backgroundView.setVisibility(VISIBLE);
      }
    }

    if (needAnimation) {
      if (useAlphaAnimations && fragmentsStack.size() == 1) {
        presentFragmentInternalRemoveOld(removeLast, currentFragment);

        ArrayList<Object> animators = new ArrayList<>();
        animators.add(ObjectAnimatorProxy.ofFloat(this, "alpha", 0.0f, 1.0f));
        if (backgroundView != null) {
          backgroundView.setVisibility(VISIBLE);
          animators.add(ObjectAnimatorProxy.ofFloat(backgroundView, "alpha", 0.0f, 1.0f));
        }

        currentAnimation = new AnimatorSetProxy();
        currentAnimation.playTogether(animators);
        currentAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
        currentAnimation.setDuration(200);
        currentAnimation.addListener(
            new AnimatorListenerAdapterProxy() {
              @Override
              public void onAnimationEnd(Object animation) {
                onAnimationEndCheck(false);
              }

              @Override
              public void onAnimationCancel(Object animation) {
                onAnimationEndCheck(false);
              }
            });
        currentAnimation.start();
      } else {
        transitionAnimationStartTime = System.currentTimeMillis();
        transitionAnimationInProgress = true;
        onOpenAnimationEndRunnable =
            new Runnable() {
              @Override
              public void run() {
                presentFragmentInternalRemoveOld(removeLast, currentFragment);
                fragment.onOpenAnimationEnd();
                ViewProxy.setTranslationX(containerView, 0);
              }
            };
        ViewProxy.setAlpha(containerView, 0.0f);
        ViewProxy.setTranslationX(containerView, 48.0f);
        currentAnimation = new AnimatorSetProxy();
        currentAnimation.playTogether(
            ObjectAnimatorProxy.ofFloat(containerView, "alpha", 0.0f, 1.0f),
            ObjectAnimatorProxy.ofFloat(containerView, "translationX", AndroidUtilities.dp(48), 0));
        currentAnimation.setInterpolator(new DecelerateInterpolator(1.5f));
        currentAnimation.setDuration(200);
        currentAnimation.addListener(
            new AnimatorListenerAdapterProxy() {
              @Override
              public void onAnimationStart(Object animation) {
                transitionAnimationStartTime = System.currentTimeMillis();
              }

              @Override
              public void onAnimationEnd(Object animation) {
                onAnimationEndCheck(false);
              }

              @Override
              public void onAnimationCancel(Object animation) {
                onAnimationEndCheck(false);
              }
            });
        currentAnimation.start();
      }
    } else {
      if (backgroundView != null) {
        ViewProxy.setAlpha(backgroundView, 1.0f);
        backgroundView.setVisibility(VISIBLE);
      }
      fragment.onOpenAnimationEnd();
    }
    return true;
  }
  public boolean onTouchEvent(MotionEvent ev) {
    if (!checkTransitionAnimation() && !inActionMode && !animationInProgress) {
      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;
          }
          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.dp(10)
              && Math.abs(dx) / 3 > dy) {
            prepareForMoving(ev);
          } 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);
            setInnerTranslationX(dx);
          }
        } 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();
          }
          velocityTracker.computeCurrentVelocity(1000);
          if (!startedTracking) {
            float velX = velocityTracker.getXVelocity();
            float velY = velocityTracker.getYVelocity();
            if (velX >= 3500 && velX > velY) {
              prepareForMoving(ev);
              if (!beginTrackingSent) {
                if (((Activity) getContext()).getCurrentFocus() != null) {
                  AndroidUtilities.hideKeyboard(((Activity) getContext()).getCurrentFocus());
                }
                beginTrackingSent = true;
              }
            }
          }
          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);
            float distToMove = 0;
            if (!backAnimation) {
              distToMove = containerView.getMeasuredWidth() - x;
              animatorSet.playTogether(
                  ObjectAnimatorProxy.ofFloat(containerView, "x", containerView.getMeasuredWidth()),
                  ObjectAnimatorProxy.ofFloat(
                      this, "innerTranslationX", (float) containerView.getMeasuredWidth()));
            } else {
              distToMove = x;
              animatorSet.playTogether(
                  ObjectAnimatorProxy.ofFloat(containerView, "x", 0),
                  ObjectAnimatorProxy.ofFloat(this, "innerTranslationX", 0.0f));
            }

            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;
          if (velocityTracker != null) {
            velocityTracker.recycle();
            velocityTracker = null;
          }
        }
      }
      return startedTracking;
    }
    return false;
  }