diff --git a/src/com/fsck/k9/activity/K9Activity.java b/src/com/fsck/k9/activity/K9Activity.java
index afd9c5bf8..c1b35ce79 100644
--- a/src/com/fsck/k9/activity/K9Activity.java
+++ b/src/com/fsck/k9/activity/K9Activity.java
@@ -1,230 +1,37 @@
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.util.Log;
-import android.view.GestureDetector;
-import android.view.GestureDetector.SimpleOnGestureListener;
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.fsck.k9.K9;
+import com.fsck.k9.activity.K9ActivityCommon.K9ActivityMagic;
+import com.fsck.k9.activity.misc.SwipeGestureDetector.OnSwipeGestureListener;
-public class K9Activity extends SherlockActivity {
- protected static final int BEZEL_SWIPE_THRESHOLD = 20;
+public class K9Activity extends SherlockActivity implements K9ActivityMagic {
+
+ private K9ActivityCommon mBase;
- protected GestureDetector mGestureDetector;
@Override
- public void onCreate(Bundle icicle) {
- setLanguage(this, K9.getK9Language());
- setTheme(K9.getK9ThemeResourceId());
- 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());
+ public void onCreate(Bundle savedInstanceState) {
+ mBase = K9ActivityCommon.newInstance(this);
+ super.onCreate(savedInstanceState);
}
@Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (mGestureDetector != null) {
- mGestureDetector.onTouchEvent(ev);
- }
- return super.dispatchTouchEvent(ev);
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ mBase.preDispatchTouchEvent(event);
+ return super.dispatchTouchEvent(event);
}
@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 true
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() {
- TypedArray array = getTheme().obtainStyledAttributes(new int[] {
- android.R.attr.colorBackground,
- });
- int backgroundColor = array.getColor(0, 0xFF00FF);
- array.recycle();
- return backgroundColor;
+ return mBase.getThemeBackgroundColor();
}
+ @Override
+ public void setupGestureDetector(OnSwipeGestureListener listener) {
+ mBase.setupGestureDetector(listener);
+ }
}
diff --git a/src/com/fsck/k9/activity/K9ActivityCommon.java b/src/com/fsck/k9/activity/K9ActivityCommon.java
new file mode 100644
index 000000000..2dd65e9b7
--- /dev/null
+++ b/src/com/fsck/k9/activity/K9ActivityCommon.java
@@ -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.
+ *
+ *
The implementing class simply has to call through to the implementation of these methods + * in {@link K9ActivityCommon}.
+ */ + 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)); + } +} diff --git a/src/com/fsck/k9/activity/K9FragmentActivity.java b/src/com/fsck/k9/activity/K9FragmentActivity.java index b27db1ca6..289765b0c 100644 --- a/src/com/fsck/k9/activity/K9FragmentActivity.java +++ b/src/com/fsck/k9/activity/K9FragmentActivity.java @@ -1,230 +1,37 @@ 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.util.Log; -import android.view.GestureDetector; -import android.view.GestureDetector.SimpleOnGestureListener; 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.fsck.k9.K9; +import com.fsck.k9.activity.K9ActivityCommon.K9ActivityMagic; +import com.fsck.k9.activity.misc.SwipeGestureDetector.OnSwipeGestureListener; -public class K9FragmentActivity extends SherlockFragmentActivity { - protected static final int BEZEL_SWIPE_THRESHOLD = 20; +public class K9FragmentActivity extends SherlockFragmentActivity implements K9ActivityMagic { + + private K9ActivityCommon mBase; - protected GestureDetector mGestureDetector; @Override - public void onCreate(Bundle icicle) { - setLanguage(this, K9.getK9Language()); - setTheme(K9.getK9ThemeResourceId()); - 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()); + public void onCreate(Bundle savedInstanceState) { + mBase = K9ActivityCommon.newInstance(this); + super.onCreate(savedInstanceState); } @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - if (mGestureDetector != null) { - mGestureDetector.onTouchEvent(ev); - } - return super.dispatchTouchEvent(ev); + public boolean dispatchTouchEvent(MotionEvent event) { + mBase.preDispatchTouchEvent(event); + return super.dispatchTouchEvent(event); } @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 totrue
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() {
- TypedArray array = getTheme().obtainStyledAttributes(new int[] {
- android.R.attr.colorBackground,
- });
- int backgroundColor = array.getColor(0, 0xFF00FF);
- array.recycle();
- return backgroundColor;
+ return mBase.getThemeBackgroundColor();
}
+ @Override
+ public void setupGestureDetector(OnSwipeGestureListener listener) {
+ mBase.setupGestureDetector(listener);
+ }
}
diff --git a/src/com/fsck/k9/activity/K9ListActivity.java b/src/com/fsck/k9/activity/K9ListActivity.java
index 91427e505..9c37a58e6 100644
--- a/src/com/fsck/k9/activity/K9ListActivity.java
+++ b/src/com/fsck/k9/activity/K9ListActivity.java
@@ -1,7 +1,7 @@
package com.fsck.k9.activity;
-import android.util.Log;
-import android.view.GestureDetector;
+import java.text.DateFormat;
+
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.AdapterView;
@@ -10,94 +10,96 @@ import android.os.Bundle;
import com.actionbarsherlock.app.SherlockListActivity;
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;
-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
- public void onCreate(Bundle icicle) {
- K9Activity.setLanguage(this, K9.getK9Language());
- setTheme(K9.getK9ThemeResourceId());
- super.onCreate(icicle);
+ public void onCreate(Bundle savedInstanceState) {
+ mBase = K9ActivityCommon.newInstance(this);
+ super.onCreate(savedInstanceState);
setupFormats();
}
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ mBase.preDispatchTouchEvent(event);
+ return super.dispatchTouchEvent(event);
+ }
+
@Override
public void onResume() {
super.onResume();
setupFormats();
}
- private java.text.DateFormat mDateFormat;
- private java.text.DateFormat mTimeFormat;
-
- private void setupFormats() {
- mDateFormat = DateFormatter.getDateFormat(this);
- mTimeFormat = android.text.format.DateFormat.getTimeFormat(this); // 12/24 date format
+ public DateFormat getDateFormat() {
+ return mDateFormat;
}
- public java.text.DateFormat getTimeFormat() {
+ public DateFormat getTimeFormat() {
return mTimeFormat;
}
- public java.text.DateFormat getDateFormat() {
- return mDateFormat;
+ private void setupFormats() {
+ 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
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Shortcuts that work no matter what is selected
- switch (keyCode) {
- case KeyEvent.KEYCODE_VOLUME_UP: {
- 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();
- if (currentPosition == AdapterView.INVALID_POSITION || listView.isInTouchMode()) {
- currentPosition = listView.getFirstVisiblePosition();
- }
+ if (K9.useVolumeKeysForListNavigationEnabled() &&
+ (keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
+ keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
- if (currentPosition < listView.getCount()) {
- listView.setSelection(currentPosition + 1);
- }
- return true;
+ final ListView listView = getListView();
+
+ int currentPosition = listView.getSelectedItemPosition();
+ if (currentPosition == AdapterView.INVALID_POSITION || listView.isInTouchMode()) {
+ currentPosition = listView.getFirstVisiblePosition();
}
+
+ 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);
+ }
+
+ return true;
}
- }
+
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// Swallow these events too to avoid the audible notification of a volume change
- if (K9.useVolumeKeysForListNavigationEnabled()) {
- if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
- if (K9.DEBUG)
- Log.v(K9.LOG_TAG, "Swallowed key up.");
- return true;
- }
+ if (K9.useVolumeKeysForListNavigationEnabled() &&
+ (keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
+ keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
+ return true;
}
+
return super.onKeyUp(keyCode, event);
}
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (mGestureDetector != null) {
- mGestureDetector.onTouchEvent(ev);
- }
- return super.dispatchTouchEvent(ev);
- }
}
diff --git a/src/com/fsck/k9/activity/K9PreferenceActivity.java b/src/com/fsck/k9/activity/K9PreferenceActivity.java
index 1b83b68f4..d30cf9d63 100644
--- a/src/com/fsck/k9/activity/K9PreferenceActivity.java
+++ b/src/com/fsck/k9/activity/K9PreferenceActivity.java
@@ -12,7 +12,7 @@ import android.preference.Preference;
public class K9PreferenceActivity extends SherlockPreferenceActivity {
@Override
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) {
// 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;
}
}
-
}
diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java
index ca5d3f261..dee923870 100644
--- a/src/com/fsck/k9/activity/MessageList.java
+++ b/src/com/fsck/k9/activity/MessageList.java
@@ -30,22 +30,23 @@ import android.util.Log;
import android.util.TypedValue;
import android.view.*;
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.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.internal.view.menu.MenuBuilder;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
@@ -59,14 +60,12 @@ import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.R;
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.setup.AccountSettings;
import com.fsck.k9.activity.setup.FolderSettings;
import com.fsck.k9.activity.setup.Prefs;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.controller.MessagingListener;
-import com.fsck.k9.helper.MenuPopup;
import com.fsck.k9.helper.MessageHelper;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Flag;
@@ -724,7 +723,7 @@ public class MessageList extends K9ListActivity implements OnItemClickListener,
mListView.setVerticalFadingEdgeEnabled(false);
// Enable gesture detection for MessageLists
- mGestureDetector = new GestureDetector(new SwipeGestureDetector(this, this));
+ setupGestureDetector(this);
// Correcting for screen rotation when in ActionMode
mSelectedCount = getSelectionFromCheckboxes().size();
diff --git a/src/com/fsck/k9/activity/MessageView.java b/src/com/fsck/k9/activity/MessageView.java
index 7be0ddc50..760e37fac 100644
--- a/src/com/fsck/k9/activity/MessageView.java
+++ b/src/com/fsck/k9/activity/MessageView.java
@@ -12,6 +12,8 @@ import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
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.fragment.MessageViewFragment;
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.FragmentTransaction;
import android.util.Log;
-import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
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_REFERENCES = "com.fsck.k9.MessageView_messageReferences";
@@ -71,15 +73,11 @@ public class MessageView extends K9FragmentActivity implements MessageViewFragme
private Menu mMenu;
/**
- * Screen width in pixels.
- *
- * * Used to detect right-to-left bezel swipes. - *
* * @see #onSwipeRightToLeft(MotionEvent, MotionEvent) */ - private int mScreenWidthInPixels; + private int mRightBezelThreshold; @Override @@ -92,10 +90,13 @@ public class MessageView extends K9FragmentActivity implements MessageViewFragme initializeActionBar(); setTitle(""); - mScreenWidthInPixels = getResources().getDisplayMetrics().widthPixels; + int screenWidth = getResources().getDisplayMetrics().widthPixels; + mRightBezelThreshold = screenWidth - SwipeGestureDetector.BEZEL_SWIPE_THRESHOLD; // Enable gesture detection for MessageViews - mGestureDetector = new GestureDetector(new MyGestureDetector(false)); + if (K9.gesturesEnabled()) { + setupGestureDetector(this); + } 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." */ @Override - protected void onSwipeRightToLeft(MotionEvent e1, MotionEvent e2) { - if ((int) e1.getRawX() > mScreenWidthInPixels - BEZEL_SWIPE_THRESHOLD) { + public void onSwipeRightToLeft(MotionEvent e1, MotionEvent e2) { + if ((int) e1.getRawX() > mRightBezelThreshold) { onNext(); } } @@ -420,8 +421,8 @@ public class MessageView extends K9FragmentActivity implements MessageViewFragme * "move to previous message." */ @Override - protected void onSwipeLeftToRight(MotionEvent e1, MotionEvent e2) { - if ((int) e1.getRawX() < BEZEL_SWIPE_THRESHOLD) { + public void onSwipeLeftToRight(MotionEvent e1, MotionEvent e2) { + if ((int) e1.getRawX() < SwipeGestureDetector.BEZEL_SWIPE_THRESHOLD) { onPrevious(); } } diff --git a/src/com/fsck/k9/activity/misc/SwipeGestureDetector.java b/src/com/fsck/k9/activity/misc/SwipeGestureDetector.java index f020e41fc..db77ee5d9 100644 --- a/src/com/fsck/k9/activity/misc/SwipeGestureDetector.java +++ b/src/com/fsck/k9/activity/misc/SwipeGestureDetector.java @@ -2,18 +2,23 @@ package com.fsck.k9.activity.misc; import android.content.Context; import android.view.MotionEvent; +import android.view.GestureDetector.OnGestureListener; import android.view.GestureDetector.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_THRESHOLD_VELOCITY_DIP = 325f; + private final OnSwipeGestureListener mListener; private int mMinVelocity; private int mMaxOffPath; private MotionEvent mLastOnDownEvent = null; + public SwipeGestureDetector(Context context, OnSwipeGestureListener listener) { 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 { + /** + * Called when a swipe from right to left is handled by {@link MyGestureDetector}. + * + *See {@link OnGestureListener#onFling(MotionEvent, 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. + */ void onSwipeRightToLeft(final MotionEvent e1, final MotionEvent e2); + + /** + * Called when a swipe from left to right is handled by {@link MyGestureDetector}. + * + *See {@link OnGestureListener#onFling(MotionEvent, 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. + */ void onSwipeLeftToRight(final MotionEvent e1, final MotionEvent e2); } } diff --git a/src/com/fsck/k9/view/SingleMessageView.java b/src/com/fsck/k9/view/SingleMessageView.java index c7ccdff8e..2344782cf 100644 --- a/src/com/fsck/k9/view/SingleMessageView.java +++ b/src/com/fsck/k9/view/SingleMessageView.java @@ -32,7 +32,7 @@ import android.widget.Toast; import com.fsck.k9.Account; import com.fsck.k9.K9; 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.MessagingListener; import com.fsck.k9.crypto.CryptoProvider; @@ -159,7 +159,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, mHeaderPlaceHolder.removeView(mHeaderContainer); // the HTC version of WebView tries to force the background of the // titlebar, which is really unfair. -// mHeaderContainer.setBackgroundColor(((K9Activity)activity).getThemeBackgroundColor()); + mHeaderContainer.setBackgroundColor(((K9ActivityMagic)activity).getThemeBackgroundColor()); mTitleBarHeaderContainer = new LinearLayout(activity); mMessageContentView.setEmbeddedTitleBarCompat(mTitleBarHeaderContainer);