Let swipe back from any place

This commit is contained in:
DrKLO 2014-06-04 22:57:11 +04:00
parent 231999ed10
commit 63ba8a5ac1
4 changed files with 132 additions and 100 deletions

View File

@ -82,7 +82,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8
targetSdkVersion 19 targetSdkVersion 19
versionCode 236 versionCode 237
versionName "1.4.15" versionName "1.4.15"
} }
} }

View File

@ -35,6 +35,7 @@ import android.text.Html;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.text.style.ImageSpan; import android.text.style.ImageSpan;
import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -542,6 +543,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
clipboard.setPrimaryClip(clip); clipboard.setPrimaryClip(clip);
} }
} }
actionBarLayer.hideActionMode();
} else if (id == delete) { } else if (id == delete) {
ArrayList<Integer> ids = new ArrayList<Integer>(selectedMessagesIds.keySet()); ArrayList<Integer> ids = new ArrayList<Integer>(selectedMessagesIds.keySet());
ArrayList<Long> random_ids = null; ArrayList<Long> random_ids = null;
@ -555,6 +557,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
} }
} }
MessagesController.getInstance().deleteMessages(ids, random_ids, currentEncryptedChat); MessagesController.getInstance().deleteMessages(ids, random_ids, currentEncryptedChat);
actionBarLayer.hideActionMode();
} else if (id == forward) { } else if (id == forward) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putBoolean("onlySelect", true); args.putBoolean("onlySelect", true);

View File

@ -12,6 +12,7 @@ import android.animation.Animator;
import android.animation.AnimatorSet; import android.animation.AnimatorSet;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Build; import android.os.Build;
@ -47,6 +48,7 @@ public class ActionBarActivity extends Activity {
private Animation openAnimation; private Animation openAnimation;
private Animation closeAnimation; private Animation closeAnimation;
private boolean maybeStartTracking = false;
private boolean startedTracking = false; private boolean startedTracking = false;
private int startedTrackingX; private int startedTrackingX;
private int prevOrientation = -10; private int prevOrientation = -10;
@ -57,6 +59,24 @@ public class ActionBarActivity extends Activity {
private long transitionAnimationStartTime; private long transitionAnimationStartTime;
private boolean inActionMode = false; private boolean inActionMode = false;
private class FrameLayoutTouch extends FrameLayout {
public FrameLayoutTouch(Context context) {
super(context);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return ((ActionBarActivity)getContext()).onTouchEvent(ev);
//return super.onInterceptTouchEvent(ev);
}
@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
((ActionBarActivity)getContext()).onTouchEvent(null);
super.requestDisallowInterceptTouchEvent(disallowIntercept);
}
}
public static ArrayList<BaseFragment> fragmentsStack = new ArrayList<BaseFragment>(); public static ArrayList<BaseFragment> fragmentsStack = new ArrayList<BaseFragment>();
protected void onCreateFinish(Bundle savedInstanceState) { protected void onCreateFinish(Bundle savedInstanceState) {
@ -77,7 +97,7 @@ public class ActionBarActivity extends Activity {
setTheme(R.style.Theme_TMessages); setTheme(R.style.Theme_TMessages);
getWindow().setBackgroundDrawableResource(R.drawable.transparent); getWindow().setBackgroundDrawableResource(R.drawable.transparent);
contentView = new FrameLayout(this); contentView = new FrameLayoutTouch(this);
setContentView(contentView, new ViewGroup.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); setContentView(contentView, new ViewGroup.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
containerViewBack = new FrameLayout(this); containerViewBack = new FrameLayout(this);
@ -185,65 +205,69 @@ public class ActionBarActivity extends Activity {
animationInProgress = false; animationInProgress = false;
} }
@Override public boolean onTouchEvent(MotionEvent ev) {
public boolean dispatchTouchEvent(MotionEvent ev) { if(android.os.Build.VERSION.SDK_INT >= 11 && !checkTransitionAnimation() && !inActionMode && fragmentsStack.size() > 1 && !animationInProgress) {
if(android.os.Build.VERSION.SDK_INT >= 11 && !checkTransitionAnimation() && !inActionMode) { if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN && !startedTracking && !maybeStartTracking) {
if (ev.getAction() == MotionEvent.ACTION_DOWN && !startedTracking && ev.getX() <= Utilities.dp(6) && fragmentsStack.size() > 1) { maybeStartTracking = true;
startedTracking = true;
startedTrackingX = (int) ev.getX(); startedTrackingX = (int) ev.getX();
shadowView.setVisibility(View.VISIBLE); } else if (ev != null && ev.getAction() == MotionEvent.ACTION_MOVE) {
shadowView.setX(-Utilities.dp(2)); int dx = Math.max(0, (int) (ev.getX() - startedTrackingX));
containerViewBack.setVisibility(View.VISIBLE); if (maybeStartTracking && !startedTracking && dx >= Utilities.dp(10)) {
beginTrackingSent = false; maybeStartTracking = false;
startedTracking = true;
startedTrackingX = (int) ev.getX();
shadowView.setVisibility(View.VISIBLE);
shadowView.setX(-Utilities.dp(2));
containerViewBack.setVisibility(View.VISIBLE);
beginTrackingSent = false;
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 2); BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 2);
actionBar.prepareForMoving(lastFragment.actionBarLayer); actionBar.prepareForMoving(lastFragment.actionBarLayer);
View fragmentView = lastFragment.createView(getLayoutInflater(), null); View fragmentView = lastFragment.createView(getLayoutInflater(), null);
ViewGroup parentView = (ViewGroup)fragmentView.getParent(); ViewGroup parentView = (ViewGroup)fragmentView.getParent();
if (parentView != null) { if (parentView != null) {
parentView.removeView(fragmentView); parentView.removeView(fragmentView);
} }
containerViewBack.addView(fragmentView); containerViewBack.addView(fragmentView);
ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams(); ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
fragmentView.setLayoutParams(layoutParams); fragmentView.setLayoutParams(layoutParams);
if (fragmentView.getBackground() == null) { if (fragmentView.getBackground() == null) {
fragmentView.setBackgroundColor(0xffffffff); fragmentView.setBackgroundColor(0xffffffff);
} }
lastFragment.onResume(); lastFragment.onResume();
try { try {
prevOrientation = getRequestedOrientation(); prevOrientation = getRequestedOrientation();
WindowManager manager = (WindowManager)getSystemService(Activity.WINDOW_SERVICE); WindowManager manager = (WindowManager)getSystemService(Activity.WINDOW_SERVICE);
if (manager != null && manager.getDefaultDisplay() != null) { if (manager != null && manager.getDefaultDisplay() != null) {
int rotation = manager.getDefaultDisplay().getRotation(); int rotation = manager.getDefaultDisplay().getRotation();
if (rotation == Surface.ROTATION_270) { if (rotation == Surface.ROTATION_270) {
if (Build.VERSION.SDK_INT >= 9) { if (Build.VERSION.SDK_INT >= 9) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
} else { } else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
} else if (rotation == Surface.ROTATION_90) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} } else if (rotation == Surface.ROTATION_0) {
} else if (rotation == Surface.ROTATION_90) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else {
} else if (rotation == Surface.ROTATION_0) { if (Build.VERSION.SDK_INT >= 9) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
} else { }
if (Build.VERSION.SDK_INT >= 9) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
} }
} }
} catch (Exception e) {
FileLog.e("tmessages", e);
} }
} catch (Exception e) { if (velocityTracker == null) {
FileLog.e("tmessages", e); velocityTracker = VelocityTracker.obtain();
} } else {
if (velocityTracker == null) { velocityTracker.clear();
velocityTracker = VelocityTracker.obtain(); }
} else { } else if (startedTracking) {
velocityTracker.clear();
}
} else if (startedTracking && !animationInProgress) {
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
if (!beginTrackingSent) { if (!beginTrackingSent) {
if (getCurrentFocus() != null) { if (getCurrentFocus() != null) {
Utilities.hideKeyboard(getCurrentFocus()); Utilities.hideKeyboard(getCurrentFocus());
@ -253,60 +277,65 @@ public class ActionBarActivity extends Activity {
beginTrackingSent = true; beginTrackingSent = true;
} }
velocityTracker.addMovement(ev); velocityTracker.addMovement(ev);
int dx = Math.max(0, (int) (ev.getX() - startedTrackingX));
actionBar.moveActionBarByX(dx); actionBar.moveActionBarByX(dx);
containerView.setX(dx); containerView.setX(dx);
shadowView.setX(dx - Utilities.dp(2)); shadowView.setX(dx - Utilities.dp(2));
} else if (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP) { }
velocityTracker.computeCurrentVelocity(1000); } else if (ev != null && startedTracking && (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP)) {
float x = containerView.getX(); velocityTracker.computeCurrentVelocity(1000);
ArrayList<Animator> animators = new ArrayList<Animator>(); float x = containerView.getX();
final boolean backAnimation = x < containerView.getMeasuredWidth() / 3.0f && velocityTracker.getXVelocity() < 6000; ArrayList<Animator> animators = new ArrayList<Animator>();
float distToMove = 0; final boolean backAnimation = x < containerView.getMeasuredWidth() / 3.0f && velocityTracker.getXVelocity() < 6000;
if (!backAnimation) { float distToMove = 0;
distToMove = containerView.getMeasuredWidth() - x; if (!backAnimation) {
animators.add(ObjectAnimator.ofFloat(containerView, "x", containerView.getMeasuredWidth())); distToMove = containerView.getMeasuredWidth() - x;
animators.add(ObjectAnimator.ofFloat(shadowView, "x", containerView.getMeasuredWidth() - Utilities.dp(2))); animators.add(ObjectAnimator.ofFloat(containerView, "x", containerView.getMeasuredWidth()));
} else { animators.add(ObjectAnimator.ofFloat(shadowView, "x", containerView.getMeasuredWidth() - Utilities.dp(2)));
distToMove = x; } else {
animators.add(ObjectAnimator.ofFloat(containerView, "x", 0)); distToMove = x;
animators.add(ObjectAnimator.ofFloat(shadowView, "x", -Utilities.dp(2))); animators.add(ObjectAnimator.ofFloat(containerView, "x", 0));
animators.add(ObjectAnimator.ofFloat(shadowView, "x", -Utilities.dp(2)));
}
actionBar.setupAnimations(animators, backAnimation);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animators);
animatorSet.setDuration((int)(200.0f / containerView.getMeasuredWidth() * distToMove));
animatorSet.start();
animationInProgress = true;
animatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
} }
actionBar.setupAnimations(animators, backAnimation);
AnimatorSet animatorSet = new AnimatorSet(); @Override
animatorSet.playTogether(animators); public void onAnimationEnd(Animator animator) {
animatorSet.setDuration((int)(200.0f / containerView.getMeasuredWidth() * distToMove)); onSlideAnimationEnd(backAnimation);
animatorSet.start(); }
animationInProgress = true;
animatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
} @Override
public void onAnimationCancel(Animator animator) {
onSlideAnimationEnd(backAnimation);
}
@Override @Override
public void onAnimationEnd(Animator animator) { public void onAnimationRepeat(Animator animator) {
onSlideAnimationEnd(backAnimation);
}
@Override }
public void onAnimationCancel(Animator animator) { });
onSlideAnimationEnd(backAnimation); velocityTracker.recycle();
} velocityTracker = null;
} else if (ev == null) {
@Override maybeStartTracking = false;
public void onAnimationRepeat(Animator animator) { startedTracking = false;
if (velocityTracker != null) {
}
});
velocityTracker.recycle(); velocityTracker.recycle();
velocityTracker = null;
} }
} }
return startedTracking || super.dispatchTouchEvent(ev); return startedTracking;
} }
return super.dispatchTouchEvent(ev); return false;
} }
@Override @Override

View File

@ -51,11 +51,11 @@ public class BaseFragment {
} }
fragmentView = null; fragmentView = null;
} }
if (actionBarLayer != null) {
actionBarLayer.onDestroy();
actionBarLayer = null;
}
if (parentActivity != null) { if (parentActivity != null) {
if (actionBarLayer != null) {
actionBarLayer.onDestroy();
actionBarLayer = null;
}
actionBarLayer = parentActivity.getInternalActionBar().createLayer(); actionBarLayer = parentActivity.getInternalActionBar().createLayer();
} }
} }