mirror of
https://github.com/moparisthebest/k-9
synced 2024-12-26 01:28:50 -05:00
Extracted functionality common to most activities to K9ActivityCommon
This commit is contained in:
parent
bbcc4988ba
commit
8a226972a5
@ -1,230 +1,37 @@
|
|||||||
package com.fsck.k9.activity;
|
package com.fsck.k9.activity;
|
||||||
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.content.res.TypedArray;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.GestureDetector;
|
|
||||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.animation.AccelerateInterpolator;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.view.animation.TranslateAnimation;
|
|
||||||
|
|
||||||
import com.actionbarsherlock.app.SherlockActivity;
|
import com.actionbarsherlock.app.SherlockActivity;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.activity.K9ActivityCommon.K9ActivityMagic;
|
||||||
|
import com.fsck.k9.activity.misc.SwipeGestureDetector.OnSwipeGestureListener;
|
||||||
|
|
||||||
|
|
||||||
public class K9Activity extends SherlockActivity {
|
public class K9Activity extends SherlockActivity implements K9ActivityMagic {
|
||||||
protected static final int BEZEL_SWIPE_THRESHOLD = 20;
|
|
||||||
|
private K9ActivityCommon mBase;
|
||||||
|
|
||||||
protected GestureDetector mGestureDetector;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
setLanguage(this, K9.getK9Language());
|
mBase = K9ActivityCommon.newInstance(this);
|
||||||
setTheme(K9.getK9ThemeResourceId());
|
super.onCreate(savedInstanceState);
|
||||||
super.onCreate(icicle);
|
|
||||||
setupFormats();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setLanguage(Context context, String language) {
|
|
||||||
Locale locale;
|
|
||||||
if (language == null || language.equals("")) {
|
|
||||||
locale = Locale.getDefault();
|
|
||||||
} else if (language.length() == 5 && language.charAt(2) == '_') {
|
|
||||||
// language is in the form: en_US
|
|
||||||
locale = new Locale(language.substring(0, 2), language.substring(3));
|
|
||||||
} else {
|
|
||||||
locale = new Locale(language);
|
|
||||||
}
|
|
||||||
Configuration config = new Configuration();
|
|
||||||
config.locale = locale;
|
|
||||||
context.getResources().updateConfiguration(config,
|
|
||||||
context.getResources().getDisplayMetrics());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
public boolean dispatchTouchEvent(MotionEvent event) {
|
||||||
if (mGestureDetector != null) {
|
mBase.preDispatchTouchEvent(event);
|
||||||
mGestureDetector.onTouchEvent(ev);
|
return super.dispatchTouchEvent(event);
|
||||||
}
|
|
||||||
return super.dispatchTouchEvent(ev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
setupFormats();
|
|
||||||
}
|
|
||||||
|
|
||||||
private java.text.DateFormat mTimeFormat;
|
|
||||||
|
|
||||||
private void setupFormats() {
|
|
||||||
mTimeFormat = android.text.format.DateFormat.getTimeFormat(this); // 12/24 date format
|
|
||||||
}
|
|
||||||
|
|
||||||
public java.text.DateFormat getTimeFormat() {
|
|
||||||
return mTimeFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a swipe from right to left is handled by {@link MyGestureDetector}. See
|
|
||||||
* {@link android.view.GestureDetector.OnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent, float, float)}
|
|
||||||
* for more information on the {@link MotionEvent}s being passed.
|
|
||||||
* @param e1 First down motion event that started the fling.
|
|
||||||
* @param e2 The move motion event that triggered the current onFling.
|
|
||||||
*/
|
|
||||||
protected void onSwipeRightToLeft(final MotionEvent e1, final MotionEvent e2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a swipe from left to right is handled by {@link MyGestureDetector}. See
|
|
||||||
* {@link android.view.GestureDetector.OnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent, float, float)}
|
|
||||||
* for more information on the {@link MotionEvent}s being passed.
|
|
||||||
* @param e1 First down motion event that started the fling.
|
|
||||||
* @param e2 The move motion event that triggered the current onFling.
|
|
||||||
*/
|
|
||||||
protected void onSwipeLeftToRight(final MotionEvent e1, final MotionEvent e2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Animation inFromRightAnimation() {
|
|
||||||
return slideAnimation(0.0f, +1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Animation outToLeftAnimation() {
|
|
||||||
return slideAnimation(0.0f, -1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Animation slideAnimation(float right, float left) {
|
|
||||||
|
|
||||||
Animation slide = new TranslateAnimation(
|
|
||||||
Animation.RELATIVE_TO_PARENT, right, Animation.RELATIVE_TO_PARENT, left,
|
|
||||||
Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f
|
|
||||||
);
|
|
||||||
slide.setDuration(125);
|
|
||||||
slide.setFillBefore(true);
|
|
||||||
slide.setInterpolator(new AccelerateInterpolator());
|
|
||||||
return slide;
|
|
||||||
}
|
|
||||||
|
|
||||||
class MyGestureDetector extends SimpleOnGestureListener {
|
|
||||||
private boolean gesturesEnabled = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link android.view.GestureDetector.OnGestureListener}. Enabled/disabled based upon
|
|
||||||
* {@link com.fsck.k9.K9#gesturesEnabled()}}.
|
|
||||||
*/
|
|
||||||
public MyGestureDetector() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new {@link android.view.GestureDetector.OnGestureListener}.
|
|
||||||
* @param gesturesEnabled Setting to <code>true</code> will enable gesture detection,
|
|
||||||
* regardless of the system-wide gesture setting.
|
|
||||||
*/
|
|
||||||
public MyGestureDetector(final boolean gesturesEnabled) {
|
|
||||||
super();
|
|
||||||
this.gesturesEnabled = gesturesEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final float SWIPE_MAX_OFF_PATH_DIP = 250f;
|
|
||||||
private static final float SWIPE_THRESHOLD_VELOCITY_DIP = 325f;
|
|
||||||
|
|
||||||
|
|
||||||
protected MotionEvent mLastOnDownEvent = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onDown(MotionEvent e) {
|
|
||||||
mLastOnDownEvent = e;
|
|
||||||
return super.onDown(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
|
||||||
// Do fling-detection if gestures are force-enabled or we have system-wide gestures enabled.
|
|
||||||
if (gesturesEnabled || K9.gesturesEnabled()) {
|
|
||||||
|
|
||||||
// Apparently sometimes e1 is null
|
|
||||||
// Found a workaround here: http://stackoverflow.com/questions/4151385/
|
|
||||||
if (e1 == null) {
|
|
||||||
e1 = mLastOnDownEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we avoid NullPointerExceptions
|
|
||||||
if (e1 == null || e2 == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the minimum distance required for this to count as a swipe.
|
|
||||||
// Convert the constant dips to pixels.
|
|
||||||
final float mGestureScale = getResources().getDisplayMetrics().density;
|
|
||||||
final int minVelocity = (int)(SWIPE_THRESHOLD_VELOCITY_DIP * mGestureScale + 0.5f);
|
|
||||||
final int maxOffPath = (int)(SWIPE_MAX_OFF_PATH_DIP * mGestureScale + 0.5f);
|
|
||||||
|
|
||||||
// Calculate how much was actually swiped.
|
|
||||||
final float deltaX = e2.getX() - e1.getX();
|
|
||||||
final float deltaY = e2.getY() - e1.getY();
|
|
||||||
|
|
||||||
// Calculate the minimum distance required for this to be considered a swipe.
|
|
||||||
final int minDistance = (int)Math.abs(deltaY * 4);
|
|
||||||
|
|
||||||
if(K9.DEBUG) {
|
|
||||||
final boolean movedAcross = (Math.abs(deltaX) > Math.abs(deltaY * 4));
|
|
||||||
final boolean steadyHand = (Math.abs(deltaX / deltaY) > 2);
|
|
||||||
Log.d(K9.LOG_TAG, String.format("Old swipe algorithm: movedAcross=%s steadyHand=%s result=%s", movedAcross, steadyHand, movedAcross && steadyHand));
|
|
||||||
Log.d(K9.LOG_TAG, String.format("New swipe algorithm: deltaX=%.2f deltaY=%.2f minDistance=%d velocity=%.2f (min=%d)", deltaX, deltaY, minDistance, velocityX, minVelocity));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (Math.abs(deltaY) > maxOffPath) {
|
|
||||||
if(K9.DEBUG)
|
|
||||||
Log.d(K9.LOG_TAG, "New swipe algorithm: Swipe too far off horizontal path.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(Math.abs(velocityX) < minVelocity) {
|
|
||||||
if(K9.DEBUG)
|
|
||||||
Log.d(K9.LOG_TAG, "New swipe algorithm: Swipe too slow.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// right to left swipe
|
|
||||||
if (deltaX < (minDistance * -1)) {
|
|
||||||
onSwipeRightToLeft(e1, e2);
|
|
||||||
if(K9.DEBUG)
|
|
||||||
Log.d(K9.LOG_TAG, "New swipe algorithm: Right to Left swipe OK.");
|
|
||||||
} else if (deltaX > minDistance) {
|
|
||||||
onSwipeLeftToRight(e1, e2);
|
|
||||||
if(K9.DEBUG)
|
|
||||||
Log.d(K9.LOG_TAG, "New swipe algorithm: Left to Right swipe OK.");
|
|
||||||
} else {
|
|
||||||
if(K9.DEBUG)
|
|
||||||
Log.d(K9.LOG_TAG, "New swipe algorithm: Swipe did not meet minimum distance requirements.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// successful fling, cancel the 2nd event to prevent any other action from happening
|
|
||||||
// see http://code.google.com/p/android/issues/detail?id=8497
|
|
||||||
e2.setAction(MotionEvent.ACTION_CANCEL);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getThemeBackgroundColor() {
|
public int getThemeBackgroundColor() {
|
||||||
TypedArray array = getTheme().obtainStyledAttributes(new int[] {
|
return mBase.getThemeBackgroundColor();
|
||||||
android.R.attr.colorBackground,
|
|
||||||
});
|
|
||||||
int backgroundColor = array.getColor(0, 0xFF00FF);
|
|
||||||
array.recycle();
|
|
||||||
return backgroundColor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupGestureDetector(OnSwipeGestureListener listener) {
|
||||||
|
mBase.setupGestureDetector(listener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
115
src/com/fsck/k9/activity/K9ActivityCommon.java
Normal file
115
src/com/fsck/k9/activity/K9ActivityCommon.java
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
package com.fsck.k9.activity;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import com.fsck.k9.K9;
|
||||||
|
import com.fsck.k9.activity.misc.SwipeGestureDetector;
|
||||||
|
import com.fsck.k9.activity.misc.SwipeGestureDetector.OnSwipeGestureListener;
|
||||||
|
import com.fsck.k9.helper.StringUtils;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.view.GestureDetector;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements functionality common to most activities used in K-9 Mail.
|
||||||
|
*
|
||||||
|
* @see K9Activity
|
||||||
|
* @see K9ListActivity
|
||||||
|
* @see K9FragmentActivity
|
||||||
|
*/
|
||||||
|
public class K9ActivityCommon {
|
||||||
|
/**
|
||||||
|
* Creates a new instance of {@link K9ActivityCommon} bound to the specified activity.
|
||||||
|
*
|
||||||
|
* @param activity
|
||||||
|
* The {@link Activity} the returned {@code K9ActivityCommon} instance will be bound to.
|
||||||
|
*
|
||||||
|
* @return The {@link K9ActivityCommon} instance that will provide the base functionality of the
|
||||||
|
* "K9" activities.
|
||||||
|
*/
|
||||||
|
public static K9ActivityCommon newInstance(Activity activity) {
|
||||||
|
return new K9ActivityCommon(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setLanguage(Activity activity, String language) {
|
||||||
|
Locale locale;
|
||||||
|
if (StringUtils.isNullOrEmpty(language)) {
|
||||||
|
locale = Locale.getDefault();
|
||||||
|
} else if (language.length() == 5 && language.charAt(2) == '_') {
|
||||||
|
// language is in the form: en_US
|
||||||
|
locale = new Locale(language.substring(0, 2), language.substring(3));
|
||||||
|
} else {
|
||||||
|
locale = new Locale(language);
|
||||||
|
}
|
||||||
|
|
||||||
|
Configuration config = new Configuration();
|
||||||
|
config.locale = locale;
|
||||||
|
Resources resources = activity.getResources();
|
||||||
|
resources.updateConfiguration(config, resources.getDisplayMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base activities need to implement this interface.
|
||||||
|
*
|
||||||
|
* <p>The implementing class simply has to call through to the implementation of these methods
|
||||||
|
* in {@link K9ActivityCommon}.</p>
|
||||||
|
*/
|
||||||
|
public interface K9ActivityMagic {
|
||||||
|
int getThemeBackgroundColor();
|
||||||
|
void setupGestureDetector(OnSwipeGestureListener listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Activity mActivity;
|
||||||
|
private GestureDetector mGestureDetector;
|
||||||
|
|
||||||
|
|
||||||
|
private K9ActivityCommon(Activity activity) {
|
||||||
|
mActivity = activity;
|
||||||
|
setLanguage(mActivity, K9.getK9Language());
|
||||||
|
mActivity.setTheme(K9.getK9ThemeResourceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this before calling {@code super.dispatchTouchEvent(MotionEvent)}.
|
||||||
|
*/
|
||||||
|
public void preDispatchTouchEvent(MotionEvent event) {
|
||||||
|
if (mGestureDetector != null) {
|
||||||
|
mGestureDetector.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the background color of the theme used for this activity.
|
||||||
|
*
|
||||||
|
* @return The background color of the current theme.
|
||||||
|
*/
|
||||||
|
public int getThemeBackgroundColor() {
|
||||||
|
TypedArray array = mActivity.getTheme().obtainStyledAttributes(
|
||||||
|
new int[] { android.R.attr.colorBackground });
|
||||||
|
|
||||||
|
int backgroundColor = array.getColor(0, 0xFF00FF);
|
||||||
|
|
||||||
|
array.recycle();
|
||||||
|
|
||||||
|
return backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this if you wish to use the swipe gesture detector.
|
||||||
|
*
|
||||||
|
* @param listener
|
||||||
|
* A listener that will be notified if a left to right or right to left swipe has been
|
||||||
|
* detected.
|
||||||
|
*/
|
||||||
|
public void setupGestureDetector(OnSwipeGestureListener listener) {
|
||||||
|
mGestureDetector = new GestureDetector(mActivity,
|
||||||
|
new SwipeGestureDetector(mActivity, listener));
|
||||||
|
}
|
||||||
|
}
|
@ -1,230 +1,37 @@
|
|||||||
package com.fsck.k9.activity;
|
package com.fsck.k9.activity;
|
||||||
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.content.res.TypedArray;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.GestureDetector;
|
|
||||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.animation.AccelerateInterpolator;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.view.animation.TranslateAnimation;
|
|
||||||
|
|
||||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.activity.K9ActivityCommon.K9ActivityMagic;
|
||||||
|
import com.fsck.k9.activity.misc.SwipeGestureDetector.OnSwipeGestureListener;
|
||||||
|
|
||||||
|
|
||||||
public class K9FragmentActivity extends SherlockFragmentActivity {
|
public class K9FragmentActivity extends SherlockFragmentActivity implements K9ActivityMagic {
|
||||||
protected static final int BEZEL_SWIPE_THRESHOLD = 20;
|
|
||||||
|
private K9ActivityCommon mBase;
|
||||||
|
|
||||||
protected GestureDetector mGestureDetector;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
setLanguage(this, K9.getK9Language());
|
mBase = K9ActivityCommon.newInstance(this);
|
||||||
setTheme(K9.getK9ThemeResourceId());
|
super.onCreate(savedInstanceState);
|
||||||
super.onCreate(icicle);
|
|
||||||
setupFormats();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setLanguage(Context context, String language) {
|
|
||||||
Locale locale;
|
|
||||||
if (language == null || language.equals("")) {
|
|
||||||
locale = Locale.getDefault();
|
|
||||||
} else if (language.length() == 5 && language.charAt(2) == '_') {
|
|
||||||
// language is in the form: en_US
|
|
||||||
locale = new Locale(language.substring(0, 2), language.substring(3));
|
|
||||||
} else {
|
|
||||||
locale = new Locale(language);
|
|
||||||
}
|
|
||||||
Configuration config = new Configuration();
|
|
||||||
config.locale = locale;
|
|
||||||
context.getResources().updateConfiguration(config,
|
|
||||||
context.getResources().getDisplayMetrics());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
public boolean dispatchTouchEvent(MotionEvent event) {
|
||||||
if (mGestureDetector != null) {
|
mBase.preDispatchTouchEvent(event);
|
||||||
mGestureDetector.onTouchEvent(ev);
|
return super.dispatchTouchEvent(event);
|
||||||
}
|
|
||||||
return super.dispatchTouchEvent(ev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
setupFormats();
|
|
||||||
}
|
|
||||||
|
|
||||||
private java.text.DateFormat mTimeFormat;
|
|
||||||
|
|
||||||
private void setupFormats() {
|
|
||||||
mTimeFormat = android.text.format.DateFormat.getTimeFormat(this); // 12/24 date format
|
|
||||||
}
|
|
||||||
|
|
||||||
public java.text.DateFormat getTimeFormat() {
|
|
||||||
return mTimeFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a swipe from right to left is handled by {@link MyGestureDetector}. See
|
|
||||||
* {@link android.view.GestureDetector.OnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent, float, float)}
|
|
||||||
* for more information on the {@link MotionEvent}s being passed.
|
|
||||||
* @param e1 First down motion event that started the fling.
|
|
||||||
* @param e2 The move motion event that triggered the current onFling.
|
|
||||||
*/
|
|
||||||
protected void onSwipeRightToLeft(final MotionEvent e1, final MotionEvent e2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a swipe from left to right is handled by {@link MyGestureDetector}. See
|
|
||||||
* {@link android.view.GestureDetector.OnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent, float, float)}
|
|
||||||
* for more information on the {@link MotionEvent}s being passed.
|
|
||||||
* @param e1 First down motion event that started the fling.
|
|
||||||
* @param e2 The move motion event that triggered the current onFling.
|
|
||||||
*/
|
|
||||||
protected void onSwipeLeftToRight(final MotionEvent e1, final MotionEvent e2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Animation inFromRightAnimation() {
|
|
||||||
return slideAnimation(0.0f, +1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Animation outToLeftAnimation() {
|
|
||||||
return slideAnimation(0.0f, -1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Animation slideAnimation(float right, float left) {
|
|
||||||
|
|
||||||
Animation slide = new TranslateAnimation(
|
|
||||||
Animation.RELATIVE_TO_PARENT, right, Animation.RELATIVE_TO_PARENT, left,
|
|
||||||
Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f
|
|
||||||
);
|
|
||||||
slide.setDuration(125);
|
|
||||||
slide.setFillBefore(true);
|
|
||||||
slide.setInterpolator(new AccelerateInterpolator());
|
|
||||||
return slide;
|
|
||||||
}
|
|
||||||
|
|
||||||
class MyGestureDetector extends SimpleOnGestureListener {
|
|
||||||
private boolean gesturesEnabled = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link android.view.GestureDetector.OnGestureListener}. Enabled/disabled based upon
|
|
||||||
* {@link com.fsck.k9.K9#gesturesEnabled()}}.
|
|
||||||
*/
|
|
||||||
public MyGestureDetector() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new {@link android.view.GestureDetector.OnGestureListener}.
|
|
||||||
* @param gesturesEnabled Setting to <code>true</code> will enable gesture detection,
|
|
||||||
* regardless of the system-wide gesture setting.
|
|
||||||
*/
|
|
||||||
public MyGestureDetector(final boolean gesturesEnabled) {
|
|
||||||
super();
|
|
||||||
this.gesturesEnabled = gesturesEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final float SWIPE_MAX_OFF_PATH_DIP = 250f;
|
|
||||||
private static final float SWIPE_THRESHOLD_VELOCITY_DIP = 325f;
|
|
||||||
|
|
||||||
|
|
||||||
protected MotionEvent mLastOnDownEvent = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onDown(MotionEvent e) {
|
|
||||||
mLastOnDownEvent = e;
|
|
||||||
return super.onDown(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
|
||||||
// Do fling-detection if gestures are force-enabled or we have system-wide gestures enabled.
|
|
||||||
if (gesturesEnabled || K9.gesturesEnabled()) {
|
|
||||||
|
|
||||||
// Apparently sometimes e1 is null
|
|
||||||
// Found a workaround here: http://stackoverflow.com/questions/4151385/
|
|
||||||
if (e1 == null) {
|
|
||||||
e1 = mLastOnDownEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we avoid NullPointerExceptions
|
|
||||||
if (e1 == null || e2 == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the minimum distance required for this to count as a swipe.
|
|
||||||
// Convert the constant dips to pixels.
|
|
||||||
final float mGestureScale = getResources().getDisplayMetrics().density;
|
|
||||||
final int minVelocity = (int)(SWIPE_THRESHOLD_VELOCITY_DIP * mGestureScale + 0.5f);
|
|
||||||
final int maxOffPath = (int)(SWIPE_MAX_OFF_PATH_DIP * mGestureScale + 0.5f);
|
|
||||||
|
|
||||||
// Calculate how much was actually swiped.
|
|
||||||
final float deltaX = e2.getX() - e1.getX();
|
|
||||||
final float deltaY = e2.getY() - e1.getY();
|
|
||||||
|
|
||||||
// Calculate the minimum distance required for this to be considered a swipe.
|
|
||||||
final int minDistance = (int)Math.abs(deltaY * 4);
|
|
||||||
|
|
||||||
if(K9.DEBUG) {
|
|
||||||
final boolean movedAcross = (Math.abs(deltaX) > Math.abs(deltaY * 4));
|
|
||||||
final boolean steadyHand = (Math.abs(deltaX / deltaY) > 2);
|
|
||||||
Log.d(K9.LOG_TAG, String.format("Old swipe algorithm: movedAcross=%s steadyHand=%s result=%s", movedAcross, steadyHand, movedAcross && steadyHand));
|
|
||||||
Log.d(K9.LOG_TAG, String.format("New swipe algorithm: deltaX=%.2f deltaY=%.2f minDistance=%d velocity=%.2f (min=%d)", deltaX, deltaY, minDistance, velocityX, minVelocity));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (Math.abs(deltaY) > maxOffPath) {
|
|
||||||
if(K9.DEBUG)
|
|
||||||
Log.d(K9.LOG_TAG, "New swipe algorithm: Swipe too far off horizontal path.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(Math.abs(velocityX) < minVelocity) {
|
|
||||||
if(K9.DEBUG)
|
|
||||||
Log.d(K9.LOG_TAG, "New swipe algorithm: Swipe too slow.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// right to left swipe
|
|
||||||
if (deltaX < (minDistance * -1)) {
|
|
||||||
onSwipeRightToLeft(e1, e2);
|
|
||||||
if(K9.DEBUG)
|
|
||||||
Log.d(K9.LOG_TAG, "New swipe algorithm: Right to Left swipe OK.");
|
|
||||||
} else if (deltaX > minDistance) {
|
|
||||||
onSwipeLeftToRight(e1, e2);
|
|
||||||
if(K9.DEBUG)
|
|
||||||
Log.d(K9.LOG_TAG, "New swipe algorithm: Left to Right swipe OK.");
|
|
||||||
} else {
|
|
||||||
if(K9.DEBUG)
|
|
||||||
Log.d(K9.LOG_TAG, "New swipe algorithm: Swipe did not meet minimum distance requirements.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// successful fling, cancel the 2nd event to prevent any other action from happening
|
|
||||||
// see http://code.google.com/p/android/issues/detail?id=8497
|
|
||||||
e2.setAction(MotionEvent.ACTION_CANCEL);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getThemeBackgroundColor() {
|
public int getThemeBackgroundColor() {
|
||||||
TypedArray array = getTheme().obtainStyledAttributes(new int[] {
|
return mBase.getThemeBackgroundColor();
|
||||||
android.R.attr.colorBackground,
|
|
||||||
});
|
|
||||||
int backgroundColor = array.getColor(0, 0xFF00FF);
|
|
||||||
array.recycle();
|
|
||||||
return backgroundColor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupGestureDetector(OnSwipeGestureListener listener) {
|
||||||
|
mBase.setupGestureDetector(listener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.fsck.k9.activity;
|
package com.fsck.k9.activity;
|
||||||
|
|
||||||
import android.util.Log;
|
import java.text.DateFormat;
|
||||||
import android.view.GestureDetector;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
@ -10,94 +10,96 @@ import android.os.Bundle;
|
|||||||
|
|
||||||
import com.actionbarsherlock.app.SherlockListActivity;
|
import com.actionbarsherlock.app.SherlockListActivity;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
|
import com.fsck.k9.activity.K9ActivityCommon.K9ActivityMagic;
|
||||||
|
import com.fsck.k9.activity.misc.SwipeGestureDetector.OnSwipeGestureListener;
|
||||||
import com.fsck.k9.helper.DateFormatter;
|
import com.fsck.k9.helper.DateFormatter;
|
||||||
|
|
||||||
public class K9ListActivity extends SherlockListActivity {
|
|
||||||
protected GestureDetector mGestureDetector;
|
public class K9ListActivity extends SherlockListActivity implements K9ActivityMagic {
|
||||||
|
|
||||||
|
private K9ActivityCommon mBase;
|
||||||
|
private DateFormat mDateFormat;
|
||||||
|
private DateFormat mTimeFormat;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
K9Activity.setLanguage(this, K9.getK9Language());
|
mBase = K9ActivityCommon.newInstance(this);
|
||||||
setTheme(K9.getK9ThemeResourceId());
|
super.onCreate(savedInstanceState);
|
||||||
super.onCreate(icicle);
|
|
||||||
setupFormats();
|
setupFormats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchTouchEvent(MotionEvent event) {
|
||||||
|
mBase.preDispatchTouchEvent(event);
|
||||||
|
return super.dispatchTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
setupFormats();
|
setupFormats();
|
||||||
}
|
}
|
||||||
|
|
||||||
private java.text.DateFormat mDateFormat;
|
public DateFormat getDateFormat() {
|
||||||
private java.text.DateFormat mTimeFormat;
|
return mDateFormat;
|
||||||
|
|
||||||
private void setupFormats() {
|
|
||||||
mDateFormat = DateFormatter.getDateFormat(this);
|
|
||||||
mTimeFormat = android.text.format.DateFormat.getTimeFormat(this); // 12/24 date format
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.text.DateFormat getTimeFormat() {
|
public DateFormat getTimeFormat() {
|
||||||
return mTimeFormat;
|
return mTimeFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.text.DateFormat getDateFormat() {
|
private void setupFormats() {
|
||||||
return mDateFormat;
|
mTimeFormat = android.text.format.DateFormat.getTimeFormat(this);
|
||||||
|
mDateFormat = DateFormatter.getDateFormat(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getThemeBackgroundColor() {
|
||||||
|
return mBase.getThemeBackgroundColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupGestureDetector(OnSwipeGestureListener listener) {
|
||||||
|
mBase.setupGestureDetector(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
// Shortcuts that work no matter what is selected
|
// Shortcuts that work no matter what is selected
|
||||||
switch (keyCode) {
|
if (K9.useVolumeKeysForListNavigationEnabled() &&
|
||||||
case KeyEvent.KEYCODE_VOLUME_UP: {
|
(keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
|
||||||
|
keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
|
||||||
|
|
||||||
final ListView listView = getListView();
|
final ListView listView = getListView();
|
||||||
if (K9.useVolumeKeysForListNavigationEnabled()) {
|
|
||||||
int currentPosition = listView.getSelectedItemPosition();
|
|
||||||
if (currentPosition == AdapterView.INVALID_POSITION || listView.isInTouchMode()) {
|
|
||||||
currentPosition = listView.getFirstVisiblePosition();
|
|
||||||
}
|
|
||||||
if (currentPosition > 0) {
|
|
||||||
listView.setSelection(currentPosition - 1);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case KeyEvent.KEYCODE_VOLUME_DOWN: {
|
|
||||||
final ListView listView = getListView();
|
|
||||||
if (K9.useVolumeKeysForListNavigationEnabled()) {
|
|
||||||
int currentPosition = listView.getSelectedItemPosition();
|
int currentPosition = listView.getSelectedItemPosition();
|
||||||
if (currentPosition == AdapterView.INVALID_POSITION || listView.isInTouchMode()) {
|
if (currentPosition == AdapterView.INVALID_POSITION || listView.isInTouchMode()) {
|
||||||
currentPosition = listView.getFirstVisiblePosition();
|
currentPosition = listView.getFirstVisiblePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPosition < listView.getCount()) {
|
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && currentPosition > 0) {
|
||||||
|
listView.setSelection(currentPosition - 1);
|
||||||
|
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN &&
|
||||||
|
currentPosition < listView.getCount()) {
|
||||||
listView.setSelection(currentPosition + 1);
|
listView.setSelection(currentPosition + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onKeyDown(keyCode, event);
|
return super.onKeyDown(keyCode, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||||
// Swallow these events too to avoid the audible notification of a volume change
|
// Swallow these events too to avoid the audible notification of a volume change
|
||||||
if (K9.useVolumeKeysForListNavigationEnabled()) {
|
if (K9.useVolumeKeysForListNavigationEnabled() &&
|
||||||
if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
|
(keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
|
||||||
if (K9.DEBUG)
|
keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
|
||||||
Log.v(K9.LOG_TAG, "Swallowed key up.");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return super.onKeyUp(keyCode, event);
|
return super.onKeyUp(keyCode, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
|
||||||
if (mGestureDetector != null) {
|
|
||||||
mGestureDetector.onTouchEvent(ev);
|
|
||||||
}
|
|
||||||
return super.dispatchTouchEvent(ev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import android.preference.Preference;
|
|||||||
public class K9PreferenceActivity extends SherlockPreferenceActivity {
|
public class K9PreferenceActivity extends SherlockPreferenceActivity {
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
K9Activity.setLanguage(this, K9.getK9Language());
|
K9ActivityCommon.setLanguage(this, K9.getK9Language());
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= 6 && Build.VERSION.SDK_INT < 14) {
|
if (Build.VERSION.SDK_INT >= 6 && Build.VERSION.SDK_INT < 14) {
|
||||||
// There's a display bug in all supported Android versions before 4.0 (SDK 14) which
|
// There's a display bug in all supported Android versions before 4.0 (SDK 14) which
|
||||||
@ -88,5 +88,4 @@ public class K9PreferenceActivity extends SherlockPreferenceActivity {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,22 +30,23 @@ import android.util.Log;
|
|||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
import android.view.ContextMenu.ContextMenuInfo;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.KeyEvent;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
import android.widget.AdapterView.AdapterContextMenuInfo;
|
||||||
import android.widget.AdapterView.OnItemClickListener;
|
import android.widget.AdapterView.OnItemClickListener;
|
||||||
import android.widget.AdapterView.OnItemLongClickListener;
|
|
||||||
import android.widget.BaseAdapter;
|
import android.widget.BaseAdapter;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.actionbarsherlock.app.ActionBar;
|
import com.actionbarsherlock.app.ActionBar;
|
||||||
import com.actionbarsherlock.internal.view.menu.MenuBuilder;
|
|
||||||
import com.actionbarsherlock.view.ActionMode;
|
import com.actionbarsherlock.view.ActionMode;
|
||||||
import com.actionbarsherlock.view.Menu;
|
import com.actionbarsherlock.view.Menu;
|
||||||
import com.actionbarsherlock.view.MenuInflater;
|
import com.actionbarsherlock.view.MenuInflater;
|
||||||
@ -59,14 +60,12 @@ import com.fsck.k9.K9;
|
|||||||
import com.fsck.k9.Preferences;
|
import com.fsck.k9.Preferences;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
import com.fsck.k9.SearchSpecification;
|
import com.fsck.k9.SearchSpecification;
|
||||||
import com.fsck.k9.activity.misc.SwipeGestureDetector;
|
|
||||||
import com.fsck.k9.activity.misc.SwipeGestureDetector.OnSwipeGestureListener;
|
import com.fsck.k9.activity.misc.SwipeGestureDetector.OnSwipeGestureListener;
|
||||||
import com.fsck.k9.activity.setup.AccountSettings;
|
import com.fsck.k9.activity.setup.AccountSettings;
|
||||||
import com.fsck.k9.activity.setup.FolderSettings;
|
import com.fsck.k9.activity.setup.FolderSettings;
|
||||||
import com.fsck.k9.activity.setup.Prefs;
|
import com.fsck.k9.activity.setup.Prefs;
|
||||||
import com.fsck.k9.controller.MessagingController;
|
import com.fsck.k9.controller.MessagingController;
|
||||||
import com.fsck.k9.controller.MessagingListener;
|
import com.fsck.k9.controller.MessagingListener;
|
||||||
import com.fsck.k9.helper.MenuPopup;
|
|
||||||
import com.fsck.k9.helper.MessageHelper;
|
import com.fsck.k9.helper.MessageHelper;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.Flag;
|
import com.fsck.k9.mail.Flag;
|
||||||
@ -724,7 +723,7 @@ public class MessageList extends K9ListActivity implements OnItemClickListener,
|
|||||||
mListView.setVerticalFadingEdgeEnabled(false);
|
mListView.setVerticalFadingEdgeEnabled(false);
|
||||||
|
|
||||||
// Enable gesture detection for MessageLists
|
// Enable gesture detection for MessageLists
|
||||||
mGestureDetector = new GestureDetector(new SwipeGestureDetector(this, this));
|
setupGestureDetector(this);
|
||||||
|
|
||||||
// Correcting for screen rotation when in ActionMode
|
// Correcting for screen rotation when in ActionMode
|
||||||
mSelectedCount = getSelectionFromCheckboxes().size();
|
mSelectedCount = getSelectionFromCheckboxes().size();
|
||||||
|
@ -12,6 +12,8 @@ import com.fsck.k9.Account;
|
|||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.Preferences;
|
import com.fsck.k9.Preferences;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
|
import com.fsck.k9.activity.misc.SwipeGestureDetector;
|
||||||
|
import com.fsck.k9.activity.misc.SwipeGestureDetector.OnSwipeGestureListener;
|
||||||
import com.fsck.k9.crypto.PgpData;
|
import com.fsck.k9.crypto.PgpData;
|
||||||
import com.fsck.k9.fragment.MessageViewFragment;
|
import com.fsck.k9.fragment.MessageViewFragment;
|
||||||
import com.fsck.k9.fragment.MessageViewFragment.MessageViewFragmentListener;
|
import com.fsck.k9.fragment.MessageViewFragment.MessageViewFragmentListener;
|
||||||
@ -28,14 +30,14 @@ import android.os.Bundle;
|
|||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.GestureDetector;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
|
||||||
public class MessageView extends K9FragmentActivity implements MessageViewFragmentListener {
|
public class MessageView extends K9FragmentActivity implements MessageViewFragmentListener,
|
||||||
|
OnSwipeGestureListener {
|
||||||
|
|
||||||
private static final String EXTRA_MESSAGE_REFERENCE = "com.fsck.k9.MessageView_messageReference";
|
private static final String EXTRA_MESSAGE_REFERENCE = "com.fsck.k9.MessageView_messageReference";
|
||||||
private static final String EXTRA_MESSAGE_REFERENCES = "com.fsck.k9.MessageView_messageReferences";
|
private static final String EXTRA_MESSAGE_REFERENCES = "com.fsck.k9.MessageView_messageReferences";
|
||||||
@ -71,15 +73,11 @@ public class MessageView extends K9FragmentActivity implements MessageViewFragme
|
|||||||
private Menu mMenu;
|
private Menu mMenu;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Screen width in pixels.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Used to detect right-to-left bezel swipes.
|
* Used to detect right-to-left bezel swipes.
|
||||||
* </p>
|
|
||||||
*
|
*
|
||||||
* @see #onSwipeRightToLeft(MotionEvent, MotionEvent)
|
* @see #onSwipeRightToLeft(MotionEvent, MotionEvent)
|
||||||
*/
|
*/
|
||||||
private int mScreenWidthInPixels;
|
private int mRightBezelThreshold;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -92,10 +90,13 @@ public class MessageView extends K9FragmentActivity implements MessageViewFragme
|
|||||||
initializeActionBar();
|
initializeActionBar();
|
||||||
setTitle("");
|
setTitle("");
|
||||||
|
|
||||||
mScreenWidthInPixels = getResources().getDisplayMetrics().widthPixels;
|
int screenWidth = getResources().getDisplayMetrics().widthPixels;
|
||||||
|
mRightBezelThreshold = screenWidth - SwipeGestureDetector.BEZEL_SWIPE_THRESHOLD;
|
||||||
|
|
||||||
// Enable gesture detection for MessageViews
|
// Enable gesture detection for MessageViews
|
||||||
mGestureDetector = new GestureDetector(new MyGestureDetector(false));
|
if (K9.gesturesEnabled()) {
|
||||||
|
setupGestureDetector(this);
|
||||||
|
}
|
||||||
|
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
|
|
||||||
@ -409,8 +410,8 @@ public class MessageView extends K9FragmentActivity implements MessageViewFragme
|
|||||||
* Handle a right-to-left swipe starting at the edge of the screen as "move to next message."
|
* Handle a right-to-left swipe starting at the edge of the screen as "move to next message."
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void onSwipeRightToLeft(MotionEvent e1, MotionEvent e2) {
|
public void onSwipeRightToLeft(MotionEvent e1, MotionEvent e2) {
|
||||||
if ((int) e1.getRawX() > mScreenWidthInPixels - BEZEL_SWIPE_THRESHOLD) {
|
if ((int) e1.getRawX() > mRightBezelThreshold) {
|
||||||
onNext();
|
onNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,8 +421,8 @@ public class MessageView extends K9FragmentActivity implements MessageViewFragme
|
|||||||
* "move to previous message."
|
* "move to previous message."
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void onSwipeLeftToRight(MotionEvent e1, MotionEvent e2) {
|
public void onSwipeLeftToRight(MotionEvent e1, MotionEvent e2) {
|
||||||
if ((int) e1.getRawX() < BEZEL_SWIPE_THRESHOLD) {
|
if ((int) e1.getRawX() < SwipeGestureDetector.BEZEL_SWIPE_THRESHOLD) {
|
||||||
onPrevious();
|
onPrevious();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,18 +2,23 @@ package com.fsck.k9.activity.misc;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
import android.view.GestureDetector.OnGestureListener;
|
||||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
import android.view.GestureDetector.SimpleOnGestureListener;
|
||||||
|
|
||||||
|
|
||||||
public class SwipeGestureDetector extends SimpleOnGestureListener {
|
public class SwipeGestureDetector extends SimpleOnGestureListener {
|
||||||
|
public static final int BEZEL_SWIPE_THRESHOLD = 20;
|
||||||
|
|
||||||
private static final float SWIPE_MAX_OFF_PATH_DIP = 250f;
|
private static final float SWIPE_MAX_OFF_PATH_DIP = 250f;
|
||||||
private static final float SWIPE_THRESHOLD_VELOCITY_DIP = 325f;
|
private static final float SWIPE_THRESHOLD_VELOCITY_DIP = 325f;
|
||||||
|
|
||||||
|
|
||||||
private final OnSwipeGestureListener mListener;
|
private final OnSwipeGestureListener mListener;
|
||||||
private int mMinVelocity;
|
private int mMinVelocity;
|
||||||
private int mMaxOffPath;
|
private int mMaxOffPath;
|
||||||
private MotionEvent mLastOnDownEvent = null;
|
private MotionEvent mLastOnDownEvent = null;
|
||||||
|
|
||||||
|
|
||||||
public SwipeGestureDetector(Context context, OnSwipeGestureListener listener) {
|
public SwipeGestureDetector(Context context, OnSwipeGestureListener listener) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -80,8 +85,35 @@ public class SwipeGestureDetector extends SimpleOnGestureListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A listener that will be notified when a right to left or left to right swipe has been
|
||||||
|
* detected.
|
||||||
|
*/
|
||||||
public interface OnSwipeGestureListener {
|
public interface OnSwipeGestureListener {
|
||||||
|
/**
|
||||||
|
* Called when a swipe from right to left is handled by {@link MyGestureDetector}.
|
||||||
|
*
|
||||||
|
* <p>See {@link OnGestureListener#onFling(MotionEvent, MotionEvent, float, float)}
|
||||||
|
* for more information on the {@link MotionEvent}s being passed.</p>
|
||||||
|
*
|
||||||
|
* @param e1
|
||||||
|
* First down motion event that started the fling.
|
||||||
|
* @param e2
|
||||||
|
* The move motion event that triggered the current onFling.
|
||||||
|
*/
|
||||||
void onSwipeRightToLeft(final MotionEvent e1, final MotionEvent e2);
|
void onSwipeRightToLeft(final MotionEvent e1, final MotionEvent e2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a swipe from left to right is handled by {@link MyGestureDetector}.
|
||||||
|
*
|
||||||
|
* <p>See {@link OnGestureListener#onFling(MotionEvent, MotionEvent, float, float)}
|
||||||
|
* for more information on the {@link MotionEvent}s being passed.</p>
|
||||||
|
*
|
||||||
|
* @param e1
|
||||||
|
* First down motion event that started the fling.
|
||||||
|
* @param e2
|
||||||
|
* The move motion event that triggered the current onFling.
|
||||||
|
*/
|
||||||
void onSwipeLeftToRight(final MotionEvent e1, final MotionEvent e2);
|
void onSwipeLeftToRight(final MotionEvent e1, final MotionEvent e2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ import android.widget.Toast;
|
|||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
import com.fsck.k9.activity.K9Activity;
|
import com.fsck.k9.activity.K9ActivityCommon.K9ActivityMagic;
|
||||||
import com.fsck.k9.controller.MessagingController;
|
import com.fsck.k9.controller.MessagingController;
|
||||||
import com.fsck.k9.controller.MessagingListener;
|
import com.fsck.k9.controller.MessagingListener;
|
||||||
import com.fsck.k9.crypto.CryptoProvider;
|
import com.fsck.k9.crypto.CryptoProvider;
|
||||||
@ -159,7 +159,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
|
|||||||
mHeaderPlaceHolder.removeView(mHeaderContainer);
|
mHeaderPlaceHolder.removeView(mHeaderContainer);
|
||||||
// the HTC version of WebView tries to force the background of the
|
// the HTC version of WebView tries to force the background of the
|
||||||
// titlebar, which is really unfair.
|
// titlebar, which is really unfair.
|
||||||
// mHeaderContainer.setBackgroundColor(((K9Activity)activity).getThemeBackgroundColor());
|
mHeaderContainer.setBackgroundColor(((K9ActivityMagic)activity).getThemeBackgroundColor());
|
||||||
|
|
||||||
mTitleBarHeaderContainer = new LinearLayout(activity);
|
mTitleBarHeaderContainer = new LinearLayout(activity);
|
||||||
mMessageContentView.setEmbeddedTitleBarCompat(mTitleBarHeaderContainer);
|
mMessageContentView.setEmbeddedTitleBarCompat(mTitleBarHeaderContainer);
|
||||||
|
Loading…
Reference in New Issue
Block a user