lint fixes

updated README
This commit is contained in:
Mariotaku Lee 2014-07-06 07:49:12 +08:00
parent 59db5254ce
commit e0e3da072a
48 changed files with 396 additions and 1732 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
/.idea/workspace.xml
.DS_Store
/build
/signing.properties

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="android-easing-1.0.3">
<CLASSES>
<root url="jar://$PROJECT_DIR$/build/intermediates/exploded-aar/it.sephiroth.android.library.easing/android-easing/1.0.3/classes.jar!/" />
<root url="file://$PROJECT_DIR$/build/intermediates/exploded-aar/it.sephiroth.android.library.easing/android-easing/1.0.3/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="imagezoom-1.0.5">
<CLASSES>
<root url="file://$PROJECT_DIR$/build/intermediates/exploded-aar/it.sephiroth.android.library.imagezoom/imagezoom/1.0.5/res" />
<root url="jar://$PROJECT_DIR$/build/intermediates/exploded-aar/it.sephiroth.android.library.imagezoom/imagezoom/1.0.5/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -57,8 +57,8 @@ Thanks to their excellent design!
* [HttpMime](http://hc.apache.org/httpcomponents-client-ga/httpmime/), Copyright 1999-2013 The Apache Software Foundation
* [ACRA](http://github.com/ACRA/acra), Copyright 2013 Kevin Gaudin
* [drag-sort-listview](https://github.com/bauerca/drag-sort-listview), Copyright 2012 Carl Bauer
* [Android-MenuComponent](https://github.com/mariotaku/Android-MenuComponent), Copyright 2013 Mariotaku Lee
* [RefreshNow](https://github.com/mariotaku/RefreshNow), Copyright 2014 Mariotaku Lee
* [MenuComponent-Android](https://github.com/mariotaku/MenuComponent-Android), Copyright 2014 Mariotaku Lee
* [RefreshNow-Android](https://github.com/mariotaku/RefreshNow-Android), Copyright 2014 Mariotaku Lee
* [AndroidStaggeredGrid](https://github.com/etsy/AndroidStaggeredGrid), Copyright 2013 Etsy
* [cwac-merge](https://github.com/commonsguy/cwac-merge), Copyright 2013 CommonsWare
* [cwac-sacklist](https://github.com/commonsguy/cwac-sacklist), Copyright 2013 CommonsWare
@ -78,9 +78,7 @@ I started a crowdin project, so anyone can do something for Twidere. Visit this
**Donation methods**
PayPal: "mariotaku.lee#gmail.com".replace("#", "@");
AliPay: http://me.alipay.com/mariotaku
PayPal & AliPay: "mariotaku.lee#gmail.com".replace("#", "@");
Bitcoin: 1FHAVAzge7cj1LfCTMfnLL49DgA3mVUCuW

View File

@ -11,6 +11,30 @@ android {
versionCode 95
versionName "0.2.9.14"
}
signingConfigs {
debug {
File signingPropFile = project.rootProject.file('signing.properties')
if (signingPropFile.exists()) {
Properties signingProp = new Properties()
signingProp.load(signingPropFile.newDataInputStream())
storeFile file(signingProp.get("twidere.debug.storeFile"))
storePassword signingProp.get("twidere.debug.storePassword")
keyAlias signingProp.get("twidere.debug.keyAlias")
keyPassword signingProp.get("twidere.debug.keyPassword")
}
}
release {
File signingPropFile = project.rootProject.file('signing.properties')
if (signingPropFile.exists()) {
Properties signingProp = new Properties()
signingProp.load(signingPropFile.newDataInputStream())
storeFile file(signingProp.get("twidere.release.storeFile"))
storePassword signingProp.get("twidere.release.storePassword")
keyAlias signingProp.get("twidere.release.keyAlias")
keyPassword signingProp.get("twidere.release.keyPassword")
}
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
@ -22,8 +46,15 @@ android {
exclude 'META-INF/ASL2.0'
}
buildTypes {
release {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
}
}
lintOptions {
abortOnError false
}
}
@ -33,6 +64,7 @@ dependencies {
compile 'com.negusoft.holoaccent:library:+'
compile 'com.etsy.android.grid:library:1.0.5'
compile 'com.sothree.slidinguppanel:library:2.0.0'
compile 'it.sephiroth.android.library.imagezoom:imagezoom:+'
compile 'com.twitter:twitter-text:1.9.5'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.2'
compile 'org.apache.httpcomponents:httpclient-android:4.3.3'

View File

@ -1,249 +0,0 @@
package it.sephiroth.android.library.imagezoom;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import it.sephiroth.android.library.imagezoom.ScaleGestureDetector.OnScaleGestureListener;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
public class ImageViewTouch extends ImageViewTouchBase implements Constants {
private static final float SCROLL_DELTA_THRESHOLD = 1.0f;
static final float MIN_ZOOM = 0.9f;
protected int mTouchSlop;
protected float mCurrentScaleFactor;
protected float mScaleFactor;
protected int mDoubleTapDirection;
protected GestureDetector mGestureDetector;
protected OnGestureListener mGestureListener;
protected OnScaleGestureListener mScaleListener;
protected ScaleGestureDetector mScaleDetector;
protected boolean mDoubleTapToZoomEnabled = true;
protected boolean mScaleEnabled = true;
protected boolean mScrollEnabled = true;
private OnImageViewTouchDoubleTapListener doubleTapListener;
public ImageViewTouch(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
/**
* Determines whether this ImageViewTouch can be scrolled.
*
* @param direction - positive direction value means scroll from right to
* left, negative value means scroll from left to right
* @return true if there is some more place to scroll, false - otherwise.
*/
public boolean canScroll(final int direction) {
final RectF bitmapRect = getBitmapRect();
updateRect(bitmapRect, mScrollRect);
final Rect imageViewRect = new Rect();
getGlobalVisibleRect(imageViewRect);
if (bitmapRect.right >= imageViewRect.right) {
if (direction < 0) return Math.abs(bitmapRect.right - imageViewRect.right) > SCROLL_DELTA_THRESHOLD;
}
final double bitmapScrollRectDelta = Math.abs(bitmapRect.left - mScrollRect.left);
return bitmapScrollRectDelta > SCROLL_DELTA_THRESHOLD;
}
public boolean getDoubleTapEnabled() {
return mDoubleTapToZoomEnabled;
}
@Override
public boolean onTouchEvent(final MotionEvent event) {
if (mScaleDetector != null) {
mScaleDetector.onTouchEvent(event);
}
if (mScaleDetector != null && !mScaleDetector.isInProgress()) {
mGestureDetector.onTouchEvent(event);
}
final int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
if (getScale() < 1f) {
zoomTo(1f, 50);
}
break;
}
return true;
}
public void setDoubleTapListener(final OnImageViewTouchDoubleTapListener doubleTapListener) {
this.doubleTapListener = doubleTapListener;
}
public void setDoubleTapToZoomEnabled(final boolean value) {
mDoubleTapToZoomEnabled = value;
}
public void setScaleEnabled(final boolean value) {
mScaleEnabled = value;
}
public void setScrollEnabled(final boolean value) {
mScrollEnabled = value;
}
@Override
protected void _setImageDrawable(final Drawable drawable, final boolean reset, final Matrix initial_matrix,
final float maxZoom) {
super._setImageDrawable(drawable, reset, initial_matrix, maxZoom);
mScaleFactor = getMaxZoom() / 3;
}
protected OnGestureListener getGestureListener() {
return new GestureListener();
}
protected OnScaleGestureListener getScaleListener() {
return new ScaleListener();
}
@Override
protected void init() {
super.init();
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
mGestureListener = getGestureListener();
mGestureDetector = new GestureDetector(getContext(), mGestureListener);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
mScaleListener = getScaleListener();
mScaleDetector = new ScaleGestureDetector(getContext(), mScaleListener);
}
mCurrentScaleFactor = 1f;
mDoubleTapDirection = 1;
}
@Override
protected void onBitmapChanged(final Drawable drawable) {
super.onBitmapChanged(drawable);
final float v[] = new float[9];
mSuppMatrix.getValues(v);
mCurrentScaleFactor = v[Matrix.MSCALE_X];
}
protected float onDoubleTapPost(final float scale, final float maxZoom) {
if (mDoubleTapDirection == 1) {
if (scale + mScaleFactor * 2 <= maxZoom)
return scale + mScaleFactor;
else {
mDoubleTapDirection = -1;
return maxZoom;
}
} else {
mDoubleTapDirection = 1;
return 1f;
}
}
@Override
protected void onZoom(final float scale) {
super.onZoom(scale);
if (mScaleDetector != null && !mScaleDetector.isInProgress()) {
mCurrentScaleFactor = scale;
}
}
public class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDoubleTap(final MotionEvent e) {
if (BuildConfig.DEBUG) {
Log.i(LOG_TAG, "onDoubleTap. double tap enabled? " + mDoubleTapToZoomEnabled);
}
if (mDoubleTapToZoomEnabled) {
final float scale = getScale();
float targetScale = scale;
targetScale = onDoubleTapPost(scale, getMaxZoom());
targetScale = Math.min(getMaxZoom(), Math.max(targetScale, MIN_ZOOM));
mCurrentScaleFactor = targetScale;
zoomTo(targetScale, e.getX(), e.getY(), 200);
invalidate();
}
if (null != doubleTapListener) {
doubleTapListener.onDoubleTap();
}
return super.onDoubleTap(e);
}
@Override
public boolean onFling(final MotionEvent e1, final MotionEvent e2, final float velocityX, final float velocityY) {
if (!mScrollEnabled) return false;
// if (e1.getPointerCount() > 1 || e2.getPointerCount() > 1) return
// false;
if (mScaleDetector != null && mScaleDetector.isInProgress()) return false;
final float diffX = e2.getX() - e1.getX();
final float diffY = e2.getY() - e1.getY();
if (Math.abs(velocityX) > 800 || Math.abs(velocityY) > 800) {
scrollBy(diffX / 2, diffY / 2, 300);
invalidate();
}
return super.onFling(e1, e2, velocityX, velocityY);
}
@Override
public void onLongPress(final MotionEvent e) {
if (isLongClickable()) {
if (mScaleDetector != null && !mScaleDetector.isInProgress()) {
setPressed(true);
performLongClick();
}
}
}
@Override
public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX, final float distanceY) {
if (!mScrollEnabled) return false;
if (e1 == null || e2 == null) return false;
// if (e1.getPointerCount() > 1 || e2.getPointerCount() > 1) return
// false;
if (mScaleDetector != null && mScaleDetector.isInProgress()) return false;
if (getScale() == 1f) return false;
scrollBy(-distanceX, -distanceY);
invalidate();
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
public interface OnImageViewTouchDoubleTapListener {
void onDoubleTap();
}
public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(final ScaleGestureDetector detector) {
float targetScale = mCurrentScaleFactor * detector.getScaleFactor();
if (mScaleEnabled) {
targetScale = Math.min(getMaxZoom(), Math.max(targetScale, MIN_ZOOM));
zoomTo(targetScale, detector.getFocusX(), detector.getFocusY());
mCurrentScaleFactor = Math.min(getMaxZoom(), Math.max(targetScale, MIN_ZOOM));
mDoubleTapDirection = 1;
invalidate();
return true;
}
return false;
}
}
}

View File

@ -1,504 +0,0 @@
package it.sephiroth.android.library.imagezoom;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
import it.sephiroth.android.library.imagezoom.easing.Cubic;
import it.sephiroth.android.library.imagezoom.easing.Easing;
import it.sephiroth.android.library.imagezoom.graphics.FastBitmapDrawable;
import it.sephiroth.android.library.imagezoom.utils.IDisposable;
/**
* Base View to manage image zoom/scrool/pinch operations
*
* @author alessandro
*/
public class ImageViewTouchBase extends ImageView implements IDisposable {
public static final String LOG_TAG = "image";
protected Easing mEasing = new Cubic();
protected Matrix mBaseMatrix = new Matrix();
protected Matrix mSuppMatrix = new Matrix();
protected Handler mHandler = new Handler();
protected Runnable mOnLayoutRunnable = null;
protected float mMaxZoom;
protected final Matrix mDisplayMatrix = new Matrix();
protected final float[] mMatrixValues = new float[9];
protected int mThisWidth = -1, mThisHeight = -1;
protected boolean mFitToScreen = false;
final protected float MAX_ZOOM = 2.0f;
protected RectF mBitmapRect = new RectF();
protected RectF mCenterRect = new RectF();
protected RectF mScrollRect = new RectF();
private OnBitmapChangedListener mListener;
public ImageViewTouchBase(final Context context) {
super(context);
init();
}
public ImageViewTouchBase(final Context context, final AttributeSet attrs) {
super(context, attrs);
init();
}
public void clear() {
setImageBitmap(null, true);
}
@Override
public void dispose() {
clear();
}
/**
* Returns the current image display matrix. This matrix can be used in the
* next call to the {@link #setImageBitmap(Bitmap, boolean, Matrix)} to
* restore the same view state of the previous {@link Bitmap}
*
* @return
*/
public Matrix getDisplayMatrix() {
return new Matrix(mSuppMatrix);
}
public Matrix getImageViewMatrix() {
mDisplayMatrix.set(mBaseMatrix);
mDisplayMatrix.postConcat(mSuppMatrix);
return mDisplayMatrix;
}
public float getMaxZoom() {
return mMaxZoom;
}
@Override
public float getRotation() {
return 0;
}
public float getScale() {
return getScale(mSuppMatrix);
}
public void scrollBy(final float x, final float y) {
panBy(x, y);
}
public void setFitToScreen(final boolean value) {
if (value != mFitToScreen) {
mFitToScreen = value;
requestLayout();
}
}
@Override
public void setImageBitmap(final Bitmap bm) {
setImageBitmap(bm, true);
}
/**
* Set the new image to display and reset the internal matrix.
*
* @param bitmap - the {@link Bitmap} to display
* @param reset - if true the image bounds will be recreated, otherwise the
* old {@link Matrix} is used to display the new bitmap
* @see #setImageBitmap(Bitmap)
*/
public void setImageBitmap(final Bitmap bitmap, final boolean reset) {
setImageBitmap(bitmap, reset, null);
}
/**
* Similar to {@link #setImageBitmap(Bitmap, boolean)} but an optional view
* {@link Matrix} can be passed to determine the new bitmap view matrix.<br />
* This method is useful if you need to restore a Bitmap with the same
* zoom/pan values from a previous state
*
* @param bitmap - the {@link Bitmap} to display
* @param reset
* @param matrix - the {@link Matrix} to be used to display the new bitmap
* @see #setImageBitmap(Bitmap, boolean)
* @see #setImageBitmap(Bitmap)
* @see #getImageViewMatrix()
* @see #getDisplayMatrix()
*/
public void setImageBitmap(final Bitmap bitmap, final boolean reset, final Matrix matrix) {
setImageBitmap(bitmap, reset, matrix, -1);
}
/**
* @param bitmap
* @param reset
* @param matrix
* @param maxZoom - maximum zoom allowd during zoom gestures
* @see #setImageBitmap(Bitmap, boolean, Matrix)
*/
public void setImageBitmap(final Bitmap bitmap, final boolean reset, final Matrix matrix, final float maxZoom) {
Log.i(LOG_TAG, "setImageBitmap: " + bitmap);
if (bitmap != null) {
setImageDrawable(new FastBitmapDrawable(bitmap), reset, matrix, maxZoom);
} else {
setImageDrawable(null, reset, matrix, maxZoom);
}
}
@Override
public void setImageDrawable(final Drawable drawable) {
setImageDrawable(drawable, true, null, -1);
}
public void setImageDrawable(final Drawable drawable, final boolean reset, final Matrix initial_matrix,
final float maxZoom) {
final int viewWidth = getWidth();
if (viewWidth <= 0) {
mOnLayoutRunnable = new Runnable() {
@Override
public void run() {
setImageDrawable(drawable, reset, initial_matrix, maxZoom);
}
};
return;
}
_setImageDrawable(drawable, reset, initial_matrix, maxZoom);
}
@Override
public void setImageResource(final int resId) {
setImageDrawable(getContext().getResources().getDrawable(resId));
}
public void setOnBitmapChangedListener(final OnBitmapChangedListener listener) {
mListener = listener;
}
public void zoomTo(final float scale, final float durationMs) {
final float cx = getWidth() / 2F;
final float cy = getHeight() / 2F;
zoomTo(scale, cx, cy, durationMs);
}
protected void _setImageDrawable(final Drawable drawable, final boolean reset, final Matrix initial_matrix,
final float maxZoom) {
if (drawable != null) {
if (mFitToScreen) {
getProperBaseMatrix2(drawable, mBaseMatrix);
} else {
getProperBaseMatrix(drawable, mBaseMatrix);
}
super.setImageDrawable(drawable);
} else {
mBaseMatrix.reset();
super.setImageDrawable(null);
}
if (reset) {
mSuppMatrix.reset();
if (initial_matrix != null) {
mSuppMatrix = new Matrix(initial_matrix);
}
}
setImageMatrix(getImageViewMatrix());
if (maxZoom < 1) {
mMaxZoom = maxZoom();
} else {
mMaxZoom = maxZoom;
}
onBitmapChanged(drawable);
}
protected void center(final boolean horizontal, final boolean vertical) {
// Log.i(LOG_TAG, "center");
final Drawable drawable = getDrawable();
if (drawable == null) return;
final RectF rect = getCenter(horizontal, vertical);
if (rect.left != 0 || rect.top != 0) {
postTranslate(rect.left, rect.top);
}
}
protected RectF getBitmapRect() {
final Drawable drawable = getDrawable();
if (drawable == null) return null;
final Matrix m = getImageViewMatrix();
mBitmapRect.set(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
m.mapRect(mBitmapRect);
return mBitmapRect;
}
protected RectF getCenter(final boolean horizontal, final boolean vertical) {
final Drawable drawable = getDrawable();
if (drawable == null) return new RectF(0, 0, 0, 0);
final RectF rect = getBitmapRect();
final float height = rect.height();
final float width = rect.width();
float deltaX = 0, deltaY = 0;
if (vertical) {
final int viewHeight = getHeight();
if (height < viewHeight) {
deltaY = (viewHeight - height) / 2 - rect.top;
} else if (rect.top > 0) {
deltaY = -rect.top;
} else if (rect.bottom < viewHeight) {
deltaY = getHeight() - rect.bottom;
}
}
if (horizontal) {
final int viewWidth = getWidth();
if (width < viewWidth) {
deltaX = (viewWidth - width) / 2 - rect.left;
} else if (rect.left > 0) {
deltaX = -rect.left;
} else if (rect.right < viewWidth) {
deltaX = viewWidth - rect.right;
}
}
mCenterRect.set(deltaX, deltaY, 0, 0);
return mCenterRect;
}
/**
* Setup the base matrix so that the image is centered and scaled properly.
*
* @param bitmap
* @param matrix
*/
protected void getProperBaseMatrix(final Drawable drawable, final Matrix matrix) {
final float viewWidth = getWidth();
final float viewHeight = getHeight();
final float w = drawable.getIntrinsicWidth();
final float h = drawable.getIntrinsicHeight();
matrix.reset();
if (w > viewWidth || h > viewHeight) {
final float widthScale = Math.min(viewWidth / w, 2.0f);
final float heightScale = Math.min(viewHeight / h, 2.0f);
final float scale = Math.min(widthScale, heightScale);
matrix.postScale(scale, scale);
final float tw = (viewWidth - w * scale) / 2.0f;
final float th = (viewHeight - h * scale) / 2.0f;
matrix.postTranslate(tw, th);
} else {
final float tw = (viewWidth - w) / 2.0f;
final float th = (viewHeight - h) / 2.0f;
matrix.postTranslate(tw, th);
}
}
/**
* Setup the base matrix so that the image is centered and scaled properly.
*
* @param bitmap
* @param matrix
*/
protected void getProperBaseMatrix2(final Drawable bitmap, final Matrix matrix) {
final float viewWidth = getWidth();
final float viewHeight = getHeight();
final float w = bitmap.getIntrinsicWidth();
final float h = bitmap.getIntrinsicHeight();
matrix.reset();
final float widthScale = Math.min(viewWidth / w, MAX_ZOOM);
final float heightScale = Math.min(viewHeight / h, MAX_ZOOM);
final float scale = Math.min(widthScale, heightScale);
matrix.postScale(scale, scale);
matrix.postTranslate((viewWidth - w * scale) / MAX_ZOOM, (viewHeight - h * scale) / MAX_ZOOM);
}
protected float getScale(final Matrix matrix) {
return getValue(matrix, Matrix.MSCALE_X);
}
protected float getValue(final Matrix matrix, final int whichValue) {
matrix.getValues(mMatrixValues);
return mMatrixValues[whichValue];
}
protected void init() {
setScaleType(ImageView.ScaleType.MATRIX);
}
protected float maxZoom() {
final Drawable drawable = getDrawable();
if (drawable == null) return 1F;
final float fw = (float) drawable.getIntrinsicWidth() / (float) mThisWidth;
final float fh = (float) drawable.getIntrinsicHeight() / (float) mThisHeight;
final float max = Math.max(fw, fh) * 4;
return max;
}
protected void onBitmapChanged(final Drawable bitmap) {
if (mListener != null) {
mListener.onBitmapChanged(bitmap);
}
}
@Override
protected void onLayout(final boolean changed, final int left, final int top, final int right, final int bottom) {
super.onLayout(changed, left, top, right, bottom);
mThisWidth = right - left;
mThisHeight = bottom - top;
final Runnable r = mOnLayoutRunnable;
if (r != null) {
mOnLayoutRunnable = null;
r.run();
}
if (getDrawable() != null) {
if (mFitToScreen) {
getProperBaseMatrix2(getDrawable(), mBaseMatrix);
} else {
getProperBaseMatrix(getDrawable(), mBaseMatrix);
}
setImageMatrix(getImageViewMatrix());
}
}
protected void onZoom(final float scale) {
}
protected void panBy(final double dx, final double dy) {
final RectF rect = getBitmapRect();
mScrollRect.set((float) dx, (float) dy, 0, 0);
updateRect(rect, mScrollRect);
postTranslate(mScrollRect.left, mScrollRect.top);
center(true, true);
}
protected void postScale(final float scale, final float centerX, final float centerY) {
mSuppMatrix.postScale(scale, scale, centerX, centerY);
setImageMatrix(getImageViewMatrix());
}
protected void postTranslate(final float deltaX, final float deltaY) {
mSuppMatrix.postTranslate(deltaX, deltaY);
setImageMatrix(getImageViewMatrix());
}
protected void scrollBy(final float distanceX, final float distanceY, final double durationMs) {
final double dx = distanceX;
final double dy = distanceY;
final long startTime = System.currentTimeMillis();
mHandler.post(new Runnable() {
double old_x = 0;
double old_y = 0;
@Override
public void run() {
final long now = System.currentTimeMillis();
final double currentMs = Math.min(durationMs, now - startTime);
final double x = mEasing.easeOut(currentMs, 0, dx, durationMs);
final double y = mEasing.easeOut(currentMs, 0, dy, durationMs);
panBy(x - old_x, y - old_y);
old_x = x;
old_y = y;
if (currentMs < durationMs) {
mHandler.post(this);
} else {
final RectF centerRect = getCenter(true, true);
if (centerRect.left != 0 || centerRect.top != 0) {
scrollBy(centerRect.left, centerRect.top);
}
}
}
});
}
protected void updateRect(final RectF bitmapRect, final RectF scrollRect) {
if (bitmapRect == null || scrollRect == null) return;
final float width = getWidth();
final float height = getHeight();
if (bitmapRect.top >= 0 && bitmapRect.bottom <= height) {
scrollRect.top = 0;
}
if (bitmapRect.left >= 0 && bitmapRect.right <= width) {
scrollRect.left = 0;
}
if (bitmapRect.top + scrollRect.top >= 0 && bitmapRect.bottom > height) {
scrollRect.top = (int) (0 - bitmapRect.top);
}
if (bitmapRect.bottom + scrollRect.top <= height - 0 && bitmapRect.top < 0) {
scrollRect.top = (int) (height - 0 - bitmapRect.bottom);
}
if (bitmapRect.left + scrollRect.left >= 0) {
scrollRect.left = (int) (0 - bitmapRect.left);
}
if (bitmapRect.right + scrollRect.left <= width - 0) {
scrollRect.left = (int) (width - 0 - bitmapRect.right);
// Log.d( LOG_TAG, "scrollRect(2): " + scrollRect.toString() );
}
}
protected void zoomTo(final float scale) {
final float cx = getWidth() / 2F;
final float cy = getHeight() / 2F;
zoomTo(scale, cx, cy);
}
protected void zoomTo(float scale, final float centerX, final float centerY) {
// Log.i(LOG_TAG, "zoomTo");
if (scale > mMaxZoom) {
scale = mMaxZoom;
}
final float oldScale = getScale();
final float deltaScale = scale / oldScale;
postScale(deltaScale, centerX, centerY);
onZoom(getScale());
center(true, true);
}
protected void zoomTo(final float scale, final float centerX, final float centerY, final float durationMs) {
// Log.i( LOG_TAG, "zoomTo: " + scale + ", " + centerX + ": " + centerY
// );
final long startTime = System.currentTimeMillis();
final float incrementPerMs = (scale - getScale()) / durationMs;
final float oldScale = getScale();
mHandler.post(new Runnable() {
@Override
public void run() {
final long now = System.currentTimeMillis();
final float currentMs = Math.min(durationMs, now - startTime);
final float target = oldScale + incrementPerMs * currentMs;
zoomTo(target, centerX, centerY);
if (currentMs < durationMs) {
mHandler.post(this);
} else {
// if ( getScale() < 1f ) {}
}
}
});
}
public interface OnBitmapChangedListener {
void onBitmapChanged(Drawable drawable);
}
}

View File

@ -1,487 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package it.sephiroth.android.library.imagezoom;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.support.v4.view.MotionEventCompat;
import android.util.DisplayMetrics;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
/**
* Detects transformation gestures involving more than one pointer
* ("multitouch") using the supplied {@link MotionEvent}s. The
* {@link OnScaleGestureListener} callback will notify users when a particular
* gesture event has occurred. This class should only be used with
* {@link MotionEvent}s reported via touch. To use this class:
* <ul>
* <li>Create an instance of the {@code ScaleGestureDetector} for your
* {@link View}
* <li>In the {@link View#onTouchEvent(MotionEvent)} method ensure you call
* {@link #onTouchEvent(MotionEvent)}. The methods defined in your callback will
* be executed when the events occur.
* </ul>
*/
@TargetApi(Build.VERSION_CODES.ECLAIR)
public class ScaleGestureDetector {
/**
* This value is the threshold ratio between our previous combined pressure
* and the current combined pressure. We will only fire an onScale event if
* the computed ratio between the current and previous event pressures is
* greater than this value. When pressure decreases rapidly between events
* the position values can often be imprecise, as it usually indicates that
* the user is in the process of lifting a pointer off of the device. Its
* value was tuned experimentally.
*/
private static final float PRESSURE_THRESHOLD = 0.67f;
private final Context mContext;
private final OnScaleGestureListener mListener;
private boolean mGestureInProgress;
private MotionEvent mPrevEvent;
private MotionEvent mCurrEvent;
private float mFocusX;
private float mFocusY;
private float mPrevFingerDiffX;
private float mPrevFingerDiffY;
private float mCurrFingerDiffX;
private float mCurrFingerDiffY;
private float mCurrLen;
private float mPrevLen;
private float mScaleFactor;
private float mCurrPressure;
private float mPrevPressure;
private long mTimeDelta;
private final float mEdgeSlop;
private float mRightSlopEdge;
private float mBottomSlopEdge;
private boolean mSloppyGesture;
public ScaleGestureDetector(final Context context, final OnScaleGestureListener listener) {
final ViewConfiguration config = ViewConfiguration.get(context);
mContext = context;
mListener = listener;
mEdgeSlop = config.getScaledEdgeSlop();
}
/**
* Return the current distance between the two pointers forming the gesture
* in progress.
*
* @return Distance between pointers in pixels.
*/
public float getCurrentSpan() {
if (mCurrLen == -1) {
final float cvx = mCurrFingerDiffX;
final float cvy = mCurrFingerDiffY;
mCurrLen = FloatMath.sqrt(cvx * cvx + cvy * cvy);
}
return mCurrLen;
}
/**
* Return the event time of the current event being processed.
*
* @return Current event time in milliseconds.
*/
public long getEventTime() {
return mCurrEvent.getEventTime();
}
/**
* Get the X coordinate of the current gesture's focal point. If a gesture
* is in progress, the focal point is directly between the two pointers
* forming the gesture. If a gesture is ending, the focal point is the
* location of the remaining pointer on the screen. If
* {@link #isInProgress()} would return false, the result of this function
* is undefined.
*
* @return X coordinate of the focal point in pixels.
*/
public float getFocusX() {
return mFocusX;
}
/**
* Get the Y coordinate of the current gesture's focal point. If a gesture
* is in progress, the focal point is directly between the two pointers
* forming the gesture. If a gesture is ending, the focal point is the
* location of the remaining pointer on the screen. If
* {@link #isInProgress()} would return false, the result of this function
* is undefined.
*
* @return Y coordinate of the focal point in pixels.
*/
public float getFocusY() {
return mFocusY;
}
/**
* Return the previous distance between the two pointers forming the gesture
* in progress.
*
* @return Previous distance between pointers in pixels.
*/
public float getPreviousSpan() {
if (mPrevLen == -1) {
final float pvx = mPrevFingerDiffX;
final float pvy = mPrevFingerDiffY;
mPrevLen = FloatMath.sqrt(pvx * pvx + pvy * pvy);
}
return mPrevLen;
}
/**
* Return the scaling factor from the previous scale event to the current
* event. This value is defined as ({@link #getCurrentSpan()} /
* {@link #getPreviousSpan()}).
*
* @return The current scaling factor.
*/
public float getScaleFactor() {
if (mScaleFactor == -1) {
mScaleFactor = getCurrentSpan() / getPreviousSpan();
}
return mScaleFactor;
}
/**
* Return the time difference in milliseconds between the previous accepted
* scaling event and the current scaling event.
*
* @return Time difference since the last scaling event in milliseconds.
*/
public long getTimeDelta() {
return mTimeDelta;
}
/**
* Returns {@code true} if a two-finger scale gesture is in progress.
*
* @return {@code true} if a scale gesture is in progress, {@code false}
* otherwise.
*/
public boolean isInProgress() {
return mGestureInProgress;
}
public boolean onTouchEvent(final MotionEvent event) {
final int action = event.getAction();
final boolean handled = true;
if (!mGestureInProgress) {
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN: {
// We have a new multi-finger gesture
// as orientation can change, query the metrics in touch
// down
final DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
mRightSlopEdge = metrics.widthPixels - mEdgeSlop;
mBottomSlopEdge = metrics.heightPixels - mEdgeSlop;
// Be paranoid in case we missed an event
reset();
mPrevEvent = MotionEvent.obtain(event);
mTimeDelta = 0;
setContext(event);
// Check if we have a sloppy gesture. If so, delay
// the beginning of the gesture until we're sure that's
// what the user wanted. Sloppy gestures can happen if the
// edge of the user's hand is touching the screen, for
// example.
final float edgeSlop = mEdgeSlop;
final float rightSlop = mRightSlopEdge;
final float bottomSlop = mBottomSlopEdge;
final float x0 = event.getRawX();
final float y0 = event.getRawY();
final float x1 = getRawX(event, 1);
final float y1 = getRawY(event, 1);
final boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > rightSlop || y0 > bottomSlop;
final boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > rightSlop || y1 > bottomSlop;
if (p0sloppy && p1sloppy) {
mFocusX = -1;
mFocusY = -1;
mSloppyGesture = true;
} else if (p0sloppy) {
mFocusX = MotionEventCompat.getX(event, 1);
mFocusY = MotionEventCompat.getY(event, 1);
mSloppyGesture = true;
} else if (p1sloppy) {
mFocusX = MotionEventCompat.getX(event, 0);
mFocusY = MotionEventCompat.getY(event, 0);
mSloppyGesture = true;
} else {
mGestureInProgress = mListener.onScaleBegin(this);
}
}
break;
case MotionEvent.ACTION_MOVE:
if (mSloppyGesture) {
// Initiate sloppy gestures if we've moved outside of
// the slop area.
final float edgeSlop = mEdgeSlop;
final float rightSlop = mRightSlopEdge;
final float bottomSlop = mBottomSlopEdge;
final float x0 = event.getRawX();
final float y0 = event.getRawY();
final float x1 = getRawX(event, 1);
final float y1 = getRawY(event, 1);
final boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > rightSlop || y0 > bottomSlop;
final boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > rightSlop || y1 > bottomSlop;
if (p0sloppy && p1sloppy) {
mFocusX = -1;
mFocusY = -1;
} else if (p0sloppy) {
mFocusX = MotionEventCompat.getX(event, 1);
mFocusY = MotionEventCompat.getY(event, 1);
} else if (p1sloppy) {
mFocusX = MotionEventCompat.getX(event, 0);
mFocusY = MotionEventCompat.getY(event, 0);
} else {
mSloppyGesture = false;
mGestureInProgress = mListener.onScaleBegin(this);
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
if (mSloppyGesture) {
// Set focus point to the remaining finger
final int id = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT == 0 ? 1
: 0;
mFocusX = event.getX(id);
mFocusY = event.getY(id);
}
break;
}
} else {
// Transform gesture in progress - attempt to handle it
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_UP:
// Gesture ended
setContext(event);
// Set focus point to the remaining finger
final int id = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT == 0 ? 1
: 0;
mFocusX = event.getX(id);
mFocusY = event.getY(id);
if (!mSloppyGesture) {
mListener.onScaleEnd(this);
}
reset();
break;
case MotionEvent.ACTION_CANCEL:
if (!mSloppyGesture) {
mListener.onScaleEnd(this);
}
reset();
break;
case MotionEvent.ACTION_MOVE:
setContext(event);
// Only accept the event if our relative pressure is within
// a certain limit - this can help filter shaky data as a
// finger is lifted.
if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) {
final boolean updatePrevious = mListener.onScale(this);
if (updatePrevious) {
mPrevEvent.recycle();
mPrevEvent = MotionEvent.obtain(event);
}
}
break;
}
}
return handled;
}
private void reset() {
if (mPrevEvent != null) {
mPrevEvent.recycle();
mPrevEvent = null;
}
if (mCurrEvent != null) {
mCurrEvent.recycle();
mCurrEvent = null;
}
mSloppyGesture = false;
mGestureInProgress = false;
}
private void setContext(final MotionEvent curr) {
if (mCurrEvent != null) {
mCurrEvent.recycle();
}
mCurrEvent = MotionEvent.obtain(curr);
mCurrLen = -1;
mPrevLen = -1;
mScaleFactor = -1;
final MotionEvent prev = mPrevEvent;
final float px0 = prev.getX(0);
final float py0 = prev.getY(0);
final float px1 = prev.getX(1);
final float py1 = prev.getY(1);
final float cx0 = curr.getX(0);
final float cy0 = curr.getY(0);
final float cx1 = curr.getX(1);
final float cy1 = curr.getY(1);
final float pvx = px1 - px0;
final float pvy = py1 - py0;
final float cvx = cx1 - cx0;
final float cvy = cy1 - cy0;
mPrevFingerDiffX = pvx;
mPrevFingerDiffY = pvy;
mCurrFingerDiffX = cvx;
mCurrFingerDiffY = cvy;
mFocusX = cx0 + cvx * 0.5f;
mFocusY = cy0 + cvy * 0.5f;
mTimeDelta = curr.getEventTime() - prev.getEventTime();
mCurrPressure = curr.getPressure(0) + curr.getPressure(1);
mPrevPressure = prev.getPressure(0) + prev.getPressure(1);
}
/**
* MotionEvent has no getRawX(int) method; simulate it pending future API
* approval.
*/
private static float getRawX(final MotionEvent event, final int pointerIndex) {
final float offset = event.getX() - event.getRawX();
return event.getX(pointerIndex) + offset;
}
/**
* MotionEvent has no getRawY(int) method; simulate it pending future API
* approval.
*/
private static float getRawY(final MotionEvent event, final int pointerIndex) {
final float offset = event.getY() - event.getRawY();
return event.getY(pointerIndex) + offset;
}
/**
* The listener for receiving notifications when gestures occur. If you want
* to listen for all the different gestures then implement this interface.
* If you only want to listen for a subset it might be easier to extend
* {@link SimpleOnScaleGestureListener}. An application will receive events
* in the following order:
* <ul>
* <li>One {@link OnScaleGestureListener#onScaleBegin(ScaleGestureDetector)}
* <li>Zero or more
* {@link OnScaleGestureListener#onScale(ScaleGestureDetector)}
* <li>One {@link OnScaleGestureListener#onScaleEnd(ScaleGestureDetector)}
* </ul>
*/
public static interface OnScaleGestureListener {
/**
* Responds to scaling events for a gesture in progress. Reported by
* pointer motion.
*
* @param detector The detector reporting the event - use this to
* retrieve extended info about event state.
* @return Whether or not the detector should consider this event as
* handled. If an event was not handled, the detector will
* continue to accumulate movement until an event is handled.
* This can be useful if an application, for example, only wants
* to update scaling factors if the change is greater than 0.01.
*/
public boolean onScale(ScaleGestureDetector detector);
/**
* Responds to the beginning of a scaling gesture. Reported by new
* pointers going down.
*
* @param detector The detector reporting the event - use this to
* retrieve extended info about event state.
* @return Whether or not the detector should continue recognizing this
* gesture. For example, if a gesture is beginning with a focal
* point outside of a region where it makes sense,
* onScaleBegin() may return false to ignore the rest of the
* gesture.
*/
public boolean onScaleBegin(ScaleGestureDetector detector);
/**
* Responds to the end of a scale gesture. Reported by existing pointers
* going up. Once a scale has ended,
* {@link ScaleGestureDetector#getFocusX()} and
* {@link ScaleGestureDetector#getFocusY()} will return the location of
* the pointer remaining on the screen.
*
* @param detector The detector reporting the event - use this to
* retrieve extended info about event state.
*/
public void onScaleEnd(ScaleGestureDetector detector);
}
/**
* A convenience class to extend when you only want to listen for a subset
* of scaling-related events. This implements all methods in
* {@link OnScaleGestureListener} but does nothing.
* {@link OnScaleGestureListener#onScale(ScaleGestureDetector)} returns
* {@code false} so that a subclass can retrieve the accumulated scale
* factor in an overridden onScaleEnd.
* {@link OnScaleGestureListener#onScaleBegin(ScaleGestureDetector)} returns
* {@code true}.
*/
public static class SimpleOnScaleGestureListener implements OnScaleGestureListener {
@Override
public boolean onScale(final ScaleGestureDetector detector) {
return false;
}
@Override
public boolean onScaleBegin(final ScaleGestureDetector detector) {
return true;
}
@Override
public void onScaleEnd(final ScaleGestureDetector detector) {
// Intentionally empty
}
}
}

View File

@ -1,20 +0,0 @@
package it.sephiroth.android.library.imagezoom.easing;
public class Cubic implements Easing {
@Override
public double easeIn(double time, final double start, final double end, final double duration) {
return end * (time /= duration) * time * time + start;
}
@Override
public double easeInOut(double time, final double start, final double end, final double duration) {
if ((time /= duration / 2.0) < 1.0) return end / 2.0 * time * time * time + start;
return end / 2.0 * ((time -= 2.0) * time * time + 2.0) + start;
}
@Override
public double easeOut(double time, final double start, final double end, final double duration) {
return end * ((time = time / duration - 1.0) * time * time + 1.0) + start;
}
}

View File

@ -1,10 +0,0 @@
package it.sephiroth.android.library.imagezoom.easing;
public interface Easing {
double easeIn(double time, double start, double end, double duration);
double easeInOut(double time, double start, double end, double duration);
double easeOut(double time, double start, double end, double duration);
}

View File

@ -1,85 +0,0 @@
package it.sephiroth.android.library.imagezoom.graphics;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import java.io.InputStream;
/**
* Fast bitmap drawable. Does not support states. it only support alpha and
* colormatrix
*
* @author alessandro
*/
public class FastBitmapDrawable extends Drawable implements IBitmapDrawable {
protected Bitmap mBitmap;
protected Paint mPaint;
public FastBitmapDrawable(final Bitmap b) {
mBitmap = b;
mPaint = new Paint();
mPaint.setDither(true);
mPaint.setFilterBitmap(true);
}
public FastBitmapDrawable(final Resources res, final InputStream is) {
this(BitmapFactory.decodeStream(is));
}
@Override
public void draw(final Canvas canvas) {
canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
}
@Override
public Bitmap getBitmap() {
return mBitmap;
}
@Override
public int getIntrinsicHeight() {
return mBitmap.getHeight();
}
@Override
public int getIntrinsicWidth() {
return mBitmap.getWidth();
}
@Override
public int getMinimumHeight() {
return mBitmap.getHeight();
}
@Override
public int getMinimumWidth() {
return mBitmap.getWidth();
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public void setAlpha(final int alpha) {
mPaint.setAlpha(alpha);
}
public void setAntiAlias(final boolean value) {
mPaint.setAntiAlias(value);
invalidateSelf();
}
@Override
public void setColorFilter(final ColorFilter cf) {
mPaint.setColorFilter(cf);
}
}

View File

@ -1,15 +0,0 @@
package it.sephiroth.android.library.imagezoom.graphics;
import android.graphics.Bitmap;
import it.sephiroth.android.library.imagezoom.ImageViewTouchBase;
/**
* Base interface used in the {@link ImageViewTouchBase} view
*
* @author alessandro
*/
public interface IBitmapDrawable {
Bitmap getBitmap();
}

View File

@ -1,6 +0,0 @@
package it.sephiroth.android.library.imagezoom.utils;
public interface IDisposable {
void dispose();
}

View File

@ -335,7 +335,7 @@ public class SwipeBackLayout extends FrameLayout {
* Set a drawable used for edge shadow.
*
* @param shadow Drawable to use
* @param edgeFlags Combination of edge flags describing the edge to set
* @param edgeFlag Combination of edge flags describing the edge to set
* @see #EDGE_LEFT
* @see #EDGE_RIGHT
* @see #EDGE_BOTTOM
@ -355,7 +355,7 @@ public class SwipeBackLayout extends FrameLayout {
* Set a drawable used for edge shadow.
*
* @param resId Resource of drawable to use
* @param edgeFlags Combination of edge flags describing the edge to set
* @param edgeFlag Combination of edge flags describing the edge to set
* @see #EDGE_LEFT
* @see #EDGE_RIGHT
* @see #EDGE_BOTTOM

View File

@ -19,16 +19,12 @@
package org.mariotaku.twidere.activity;
import static org.mariotaku.twidere.util.ContentValuesCreator.makeFilterdUserContentValues;
import static org.mariotaku.twidere.util.Utils.getDefaultAccountId;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.ContentResolver;
import android.content.ContentValues;
@ -39,6 +35,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v4.widget.SimpleCursorAdapter;
@ -50,227 +47,231 @@ import android.widget.AutoCompleteTextView;
import org.mariotaku.querybuilder.Where;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
import org.mariotaku.twidere.adapter.SourceAutoCompleteAdapter;
import org.mariotaku.twidere.adapter.TabsAdapter;
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
import org.mariotaku.twidere.fragment.BaseDialogFragment;
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
import org.mariotaku.twidere.fragment.BaseFiltersFragment;
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredKeywordsFragment;
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredLinksFragment;
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredSourcesFragment;
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredUsersFragment;
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.provider.TweetStore.Filters;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.ThemeUtils;
public class FiltersActivity extends BaseActivity implements TabListener, OnPageChangeListener {
import static org.mariotaku.twidere.util.ContentValuesCreator.makeFilterdUserContentValues;
import static org.mariotaku.twidere.util.Utils.getDefaultAccountId;
private static final String EXTRA_AUTO_COMPLETE_TYPE = "auto_complete_type";
private static final int AUTO_COMPLETE_TYPE_SOURCES = 2;
public class FiltersActivity extends BaseSupportActivity implements TabListener, OnPageChangeListener {
private ViewPager mViewPager;
private TabsAdapter mAdapter;
private static final String EXTRA_AUTO_COMPLETE_TYPE = "auto_complete_type";
private static final int AUTO_COMPLETE_TYPE_SOURCES = 2;
private ActionBar mActionBar;
private SharedPreferences mPreferences;
private ViewPager mViewPager;
private SupportTabsAdapter mAdapter;
@Override
public void onContentChanged() {
mViewPager = (ViewPager) findViewById(R.id.pager);
}
private ActionBar mActionBar;
private SharedPreferences mPreferences;
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
setContentView(R.layout.activity_filters);
mActionBar = getActionBar();
mAdapter = new TabsAdapter(this, getFragmentManager(), null);
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
addTab(FilteredUsersFragment.class, R.string.users, 0);
addTab(FilteredKeywordsFragment.class, R.string.keywords, 1);
addTab(FilteredSourcesFragment.class, R.string.sources, 2);
addTab(FilteredLinksFragment.class, R.string.links, 3);
mViewPager.setAdapter(mAdapter);
mViewPager.setOnPageChangeListener(this);
}
@Override
public void onContentChanged() {
mViewPager = (ViewPager) findViewById(R.id.pager);
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu_filters, menu);
return true;
}
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
setContentView(R.layout.activity_filters);
mActionBar = getActionBar();
mAdapter = new SupportTabsAdapter(this, getSupportFragmentManager(), null);
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
addTab(FilteredUsersFragment.class, R.string.users, 0);
addTab(FilteredKeywordsFragment.class, R.string.keywords, 1);
addTab(FilteredSourcesFragment.class, R.string.sources, 2);
addTab(FilteredLinksFragment.class, R.string.links, 3);
mViewPager.setAdapter(mAdapter);
mViewPager.setOnPageChangeListener(this);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case MENU_HOME: {
navigateUpFromSameTask();
return true;
}
case MENU_ADD: {
final Fragment f = mAdapter.getItem(mViewPager.getCurrentItem());
if (!(f instanceof BaseFiltersFragment)) return true;
final Bundle args = new Bundle();
if (f instanceof FilteredUsersFragment) {
final Intent intent = new Intent(INTENT_ACTION_SELECT_USER);
intent.setClass(this, UserListSelectorActivity.class);
intent.putExtra(EXTRA_ACCOUNT_ID, getDefaultAccountId(this));
startActivityForResult(intent, REQUEST_SELECT_USER);
return true;
}
if (f instanceof FilteredSourcesFragment) {
args.putInt(EXTRA_AUTO_COMPLETE_TYPE, AUTO_COMPLETE_TYPE_SOURCES);
}
args.putParcelable(EXTRA_URI, ((BaseFiltersFragment) f).getContentUri());
final AddItemFragment dialog = new AddItemFragment();
dialog.setArguments(args);
dialog.show(getFragmentManager(), "add_rule");
return true;
}
case R.id.enable_in_home_timeline: {
final SharedPreferences.Editor editor = mPreferences.edit();
editor.putBoolean(KEY_FILTERS_IN_HOME_TIMELINE, !item.isChecked());
editor.apply();
break;
}
case R.id.enable_in_mentions: {
final SharedPreferences.Editor editor = mPreferences.edit();
editor.putBoolean(KEY_FILTERS_IN_MENTIONS, !item.isChecked());
editor.apply();
break;
}
case R.id.enable_for_rts: {
final SharedPreferences.Editor editor = mPreferences.edit();
editor.putBoolean(KEY_FILTERS_FOR_RTS, !item.isChecked());
editor.apply();
break;
}
}
return false;
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu_filters, menu);
return true;
}
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case MENU_HOME: {
navigateUpFromSameTask();
return true;
}
case MENU_ADD: {
final Fragment f = mAdapter.getItem(mViewPager.getCurrentItem());
if (!(f instanceof BaseFiltersFragment)) return true;
final Bundle args = new Bundle();
if (f instanceof FilteredUsersFragment) {
final Intent intent = new Intent(INTENT_ACTION_SELECT_USER);
intent.setClass(this, UserListSelectorActivity.class);
intent.putExtra(EXTRA_ACCOUNT_ID, getDefaultAccountId(this));
startActivityForResult(intent, REQUEST_SELECT_USER);
return true;
}
if (f instanceof FilteredSourcesFragment) {
args.putInt(EXTRA_AUTO_COMPLETE_TYPE, AUTO_COMPLETE_TYPE_SOURCES);
}
args.putParcelable(EXTRA_URI, ((BaseFiltersFragment) f).getContentUri());
final AddItemFragment dialog = new AddItemFragment();
dialog.setArguments(args);
dialog.show(getSupportFragmentManager(), "add_rule");
return true;
}
case R.id.enable_in_home_timeline: {
final SharedPreferences.Editor editor = mPreferences.edit();
editor.putBoolean(KEY_FILTERS_IN_HOME_TIMELINE, !item.isChecked());
editor.apply();
break;
}
case R.id.enable_in_mentions: {
final SharedPreferences.Editor editor = mPreferences.edit();
editor.putBoolean(KEY_FILTERS_IN_MENTIONS, !item.isChecked());
editor.apply();
break;
}
case R.id.enable_for_rts: {
final SharedPreferences.Editor editor = mPreferences.edit();
editor.putBoolean(KEY_FILTERS_FOR_RTS, !item.isChecked());
editor.apply();
break;
}
}
return false;
}
@Override
public void onPageScrollStateChanged(final int state) {
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
}
}
@Override
public void onPageScrollStateChanged(final int state) {
@Override
public void onPageSelected(final int position) {
if (mActionBar == null) return;
mActionBar.setSelectedNavigationItem(position);
}
}
@Override
public boolean onPrepareOptionsMenu(final Menu menu) {
final boolean enable_in_home_timeline = mPreferences.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true);
final boolean enable_in_mentions = mPreferences.getBoolean(KEY_FILTERS_IN_MENTIONS, true);
final boolean enable_for_rts = mPreferences.getBoolean(KEY_FILTERS_FOR_RTS, true);
menu.findItem(R.id.enable_in_home_timeline).setChecked(enable_in_home_timeline);
menu.findItem(R.id.enable_in_mentions).setChecked(enable_in_mentions);
menu.findItem(R.id.enable_for_rts).setChecked(enable_for_rts);
return true;
}
@Override
public void onPageSelected(final int position) {
if (mActionBar == null) return;
mActionBar.setSelectedNavigationItem(position);
}
@Override
public void onTabReselected(final Tab tab, final FragmentTransaction ft) {
@Override
public boolean onPrepareOptionsMenu(final Menu menu) {
final boolean enable_in_home_timeline = mPreferences.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true);
final boolean enable_in_mentions = mPreferences.getBoolean(KEY_FILTERS_IN_MENTIONS, true);
final boolean enable_for_rts = mPreferences.getBoolean(KEY_FILTERS_FOR_RTS, true);
menu.findItem(R.id.enable_in_home_timeline).setChecked(enable_in_home_timeline);
menu.findItem(R.id.enable_in_mentions).setChecked(enable_in_mentions);
menu.findItem(R.id.enable_for_rts).setChecked(enable_for_rts);
return true;
}
}
@Override
public void onTabReselected(final Tab tab, final FragmentTransaction ft) {
@Override
public void onTabSelected(final Tab tab, final FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
}
@Override
public void onTabUnselected(final Tab tab, final FragmentTransaction ft) {
@Override
public void onTabSelected(final Tab tab, final FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
}
@Override
public void onTabUnselected(final Tab tab, final FragmentTransaction ft) {
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_SELECT_USER: {
final Fragment filter = mAdapter.getItem(mViewPager.getCurrentItem());
if (resultCode != RESULT_OK || !(filter instanceof FilteredUsersFragment) || !data.hasExtra(EXTRA_USER))
return;
final ParcelableUser user = data.getParcelableExtra(EXTRA_USER);
final ContentValues values = makeFilterdUserContentValues(user);
final ContentResolver resolver = getContentResolver();
resolver.delete(Filters.Users.CONTENT_URI, Where.equals(Filters.Users.USER_ID, user.id).getSQL(), null);
resolver.insert(Filters.Users.CONTENT_URI, values);
break;
}
}
}
}
private void addTab(final Class<? extends Fragment> cls, final int name, final int position) {
if (mActionBar == null || mAdapter == null) return;
mActionBar.addTab(mActionBar.newTab().setText(name).setTabListener(this));
mAdapter.addTab(cls, null, getString(name), null, position);
}
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_SELECT_USER: {
final Fragment filter = mAdapter.getItem(mViewPager.getCurrentItem());
if (resultCode != RESULT_OK || !(filter instanceof FilteredUsersFragment) || !data.hasExtra(EXTRA_USER))
return;
final ParcelableUser user = data.getParcelableExtra(EXTRA_USER);
final ContentValues values = makeFilterdUserContentValues(user);
final ContentResolver resolver = getContentResolver();
resolver.delete(Filters.Users.CONTENT_URI, Where.equals(Filters.Users.USER_ID, user.id).getSQL(), null);
resolver.insert(Filters.Users.CONTENT_URI, values);
break;
}
}
}
public static final class AddItemFragment extends BaseDialogFragment implements OnClickListener {
private void addTab(final Class<? extends Fragment> cls, final int name, final int position) {
if (mActionBar == null || mAdapter == null) return;
mActionBar.addTab(mActionBar.newTab().setText(name).setTabListener(this));
mAdapter.addTab(cls, null, getString(name), null, position);
}
private AutoCompleteTextView mEditText;
public static final class AddItemFragment extends BaseSupportDialogFragment implements OnClickListener {
private SimpleCursorAdapter mUserAutoCompleteAdapter;
private AutoCompleteTextView mEditText;
@Override
public void onClick(final DialogInterface dialog, final int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
if (mEditText.length() <= 0) return;
final ContentValues values = new ContentValues();
values.put(Filters.VALUE, getText());
final Bundle args = getArguments();
final Uri uri = args.getParcelable(EXTRA_URI);
getContentResolver().insert(uri, values);
break;
}
private SimpleCursorAdapter mUserAutoCompleteAdapter;
}
@Override
public void onClick(final DialogInterface dialog, final int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
if (mEditText.length() <= 0) return;
final ContentValues values = new ContentValues();
values.put(Filters.VALUE, getText());
final Bundle args = getArguments();
final Uri uri = args.getParcelable(EXTRA_URI);
getContentResolver().insert(uri, values);
break;
}
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
buildDialog(builder);
final View view = LayoutInflater.from(wrapped).inflate(R.layout.auto_complete_textview, null);
builder.setView(view);
mEditText = (AutoCompleteTextView) view.findViewById(R.id.edit_text);
final Bundle args = getArguments();
final int auto_complete_type = args != null ? args.getInt(EXTRA_AUTO_COMPLETE_TYPE, 0) : 0;
if (auto_complete_type != 0) {
if (auto_complete_type == AUTO_COMPLETE_TYPE_SOURCES) {
mUserAutoCompleteAdapter = new SourceAutoCompleteAdapter(getActivity());
} else {
mUserAutoCompleteAdapter = new UserHashtagAutoCompleteAdapter(getActivity());
}
mEditText.setAdapter(mUserAutoCompleteAdapter);
mEditText.setThreshold(1);
}
builder.setTitle(R.string.add_rule);
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(android.R.string.cancel, this);
return builder.create();
}
}
protected String getText() {
return ParseUtils.parseString(mEditText.getText());
}
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
buildDialog(builder);
final View view = LayoutInflater.from(wrapped).inflate(R.layout.auto_complete_textview, null);
builder.setView(view);
mEditText = (AutoCompleteTextView) view.findViewById(R.id.edit_text);
final Bundle args = getArguments();
final int auto_complete_type = args != null ? args.getInt(EXTRA_AUTO_COMPLETE_TYPE, 0) : 0;
if (auto_complete_type != 0) {
if (auto_complete_type == AUTO_COMPLETE_TYPE_SOURCES) {
mUserAutoCompleteAdapter = new SourceAutoCompleteAdapter(getActivity());
} else {
mUserAutoCompleteAdapter = new UserHashtagAutoCompleteAdapter(getActivity());
}
mEditText.setAdapter(mUserAutoCompleteAdapter);
mEditText.setThreshold(1);
}
builder.setTitle(R.string.add_rule);
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(android.R.string.cancel, this);
return builder.create();
}
private void buildDialog(final Builder builder) {
// TODO Auto-generated method stub
protected String getText() {
return ParseUtils.parseString(mEditText.getText());
}
}
}
private void buildDialog(final Builder builder) {
// TODO Auto-generated method stub
}
}
}

View File

@ -19,9 +19,6 @@
package org.mariotaku.twidere.adapter.support;
import static org.mariotaku.twidere.util.CustomTabUtils.getTabIconDrawable;
import static org.mariotaku.twidere.util.Utils.announceForAccessibilityCompat;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@ -39,105 +36,113 @@ import org.mariotaku.twidere.view.TabPageIndicator.TabProvider;
import java.util.ArrayList;
import java.util.Collection;
import static org.mariotaku.twidere.util.CustomTabUtils.getTabIconDrawable;
import static org.mariotaku.twidere.util.Utils.announceForAccessibilityCompat;
public class SupportTabsAdapter extends SupportFixedFragmentStatePagerAdapter implements TabProvider, TabListener,
Constants {
Constants {
private final ArrayList<SupportTabSpec> mTabs = new ArrayList<SupportTabSpec>();
private final ArrayList<SupportTabSpec> mTabs = new ArrayList<SupportTabSpec>();
private final Context mContext;
private final TabPageIndicator mIndicator;
private final Context mContext;
private final TabPageIndicator mIndicator;
private final int mColumns;
private final int mColumns;
public SupportTabsAdapter(final Context context, final FragmentManager fm, final TabPageIndicator indicator,
final int columns) {
super(fm);
mContext = context;
mIndicator = indicator;
mColumns = columns;
clear();
}
public SupportTabsAdapter(final Context context, final FragmentManager fm, final TabPageIndicator indicator) {
this(context, fm, indicator, 1);
}
public void addTab(final Class<? extends Fragment> cls, final Bundle args, final String name, final Integer icon,
final int position) {
addTab(new SupportTabSpec(name, icon, cls, args, position));
}
public SupportTabsAdapter(final Context context, final FragmentManager fm, final TabPageIndicator indicator,
final int columns) {
super(fm);
mContext = context;
mIndicator = indicator;
mColumns = columns;
clear();
}
public void addTab(final SupportTabSpec spec) {
mTabs.add(spec);
notifyDataSetChanged();
}
public void addTab(final Class<? extends Fragment> cls, final Bundle args, final String name, final Integer icon,
final int position) {
addTab(new SupportTabSpec(name, icon, cls, args, position));
}
public void addTabs(final Collection<? extends SupportTabSpec> specs) {
mTabs.addAll(specs);
notifyDataSetChanged();
}
public void addTab(final SupportTabSpec spec) {
mTabs.add(spec);
notifyDataSetChanged();
}
public void clear() {
mTabs.clear();
notifyDataSetChanged();
}
public void addTabs(final Collection<? extends SupportTabSpec> specs) {
mTabs.addAll(specs);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
public void clear() {
mTabs.clear();
notifyDataSetChanged();
}
@Override
public Fragment getItem(final int position) {
final Fragment fragment = Fragment.instantiate(mContext, mTabs.get(position).cls.getName());
fragment.setArguments(mTabs.get(position).args);
return fragment;
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Drawable getPageIcon(final int position) {
return getTabIconDrawable(mContext, mTabs.get(position).icon);
}
@Override
public Fragment getItem(final int position) {
final Fragment fragment = Fragment.instantiate(mContext, mTabs.get(position).cls.getName());
fragment.setArguments(mTabs.get(position).args);
return fragment;
}
@Override
public CharSequence getPageTitle(final int position) {
return mTabs.get(position).name;
}
@Override
public Drawable getPageIcon(final int position) {
return getTabIconDrawable(mContext, mTabs.get(position).icon);
}
@Override
public float getPageWidth(final int position) {
return 1.0f / mColumns;
}
@Override
public CharSequence getPageTitle(final int position) {
return mTabs.get(position).name;
}
public SupportTabSpec getTab(final int position) {
return position >= 0 && position < mTabs.size() ? mTabs.get(position) : null;
}
@Override
public float getPageWidth(final int position) {
return 1.0f / mColumns;
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
if (mIndicator != null) {
mIndicator.notifyDataSetChanged();
}
}
public SupportTabSpec getTab(final int position) {
return position >= 0 && position < mTabs.size() ? mTabs.get(position) : null;
}
@Override
public void onPageReselected(final int position) {
if (!(mContext instanceof SupportFragmentCallback)) return;
final Fragment f = ((SupportFragmentCallback) mContext).getCurrentVisibleFragment();
if (f instanceof RefreshScrollTopInterface) {
((RefreshScrollTopInterface) f).scrollToStart();
}
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
if (mIndicator != null) {
mIndicator.notifyDataSetChanged();
}
}
@Override
public void onPageSelected(final int position) {
if (mIndicator == null) return;
announceForAccessibilityCompat(mContext, mIndicator, getPageTitle(position), getClass());
}
@Override
public void onPageReselected(final int position) {
if (!(mContext instanceof SupportFragmentCallback)) return;
final Fragment f = ((SupportFragmentCallback) mContext).getCurrentVisibleFragment();
if (f instanceof RefreshScrollTopInterface) {
((RefreshScrollTopInterface) f).scrollToStart();
}
}
@Override
public boolean onTabLongClick(final int position) {
if (!(mContext instanceof SupportFragmentCallback)) return false;
if (((SupportFragmentCallback) mContext).triggerRefresh(position)) return true;
final Fragment f = ((SupportFragmentCallback) mContext).getCurrentVisibleFragment();
if (f instanceof RefreshScrollTopInterface) return ((RefreshScrollTopInterface) f).triggerRefresh();
return false;
}
@Override
public void onPageSelected(final int position) {
if (mIndicator == null) return;
announceForAccessibilityCompat(mContext, mIndicator, getPageTitle(position), getClass());
}
@Override
public boolean onTabLongClick(final int position) {
if (!(mContext instanceof SupportFragmentCallback)) return false;
if (((SupportFragmentCallback) mContext).triggerRefresh(position)) return true;
final Fragment f = ((SupportFragmentCallback) mContext).getCurrentVisibleFragment();
if (f instanceof RefreshScrollTopInterface)
return ((RefreshScrollTopInterface) f).triggerRefresh();
return false;
}
}

View File

@ -21,19 +21,19 @@ package org.mariotaku.twidere.fragment;
import static org.mariotaku.twidere.util.Utils.getDisplayName;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Loader;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
@ -49,9 +49,10 @@ import org.mariotaku.querybuilder.Columns.Column;
import org.mariotaku.querybuilder.RawItemArray;
import org.mariotaku.querybuilder.Where;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.support.BaseSupportListFragment;
import org.mariotaku.twidere.provider.TweetStore.Filters;
public abstract class BaseFiltersFragment extends BaseListFragment implements LoaderCallbacks<Cursor>,
public abstract class BaseFiltersFragment extends BaseSupportListFragment implements LoaderManager.LoaderCallbacks<Cursor>,
MultiChoiceModeListener {
private ListView mListView;

View File

@ -19,9 +19,11 @@
package org.mariotaku.twidere.service;
import android.annotation.TargetApi;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
import android.os.Build;
import android.service.dreams.DreamService;
import android.view.View;
import android.view.View.OnSystemUiVisibilityChangeListener;
@ -30,6 +32,7 @@ import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.view.NyanDaydreamView;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public class NyanDaydreamService extends DreamService implements Constants, OnSharedPreferenceChangeListener,
OnSystemUiVisibilityChangeListener {

View File

@ -202,23 +202,18 @@ public final class TwidereLinkify implements Constants {
* @param highlightColor
* @param highlightOption
* @param listener
*
* @param description TextView whose text is to be marked-up with links
* @param pattern Regex pattern to be used for finding links
* @param scheme Url scheme string (eg <code>http://</code> to be prepended
* to the url of links that do not have a scheme specified in the
* link text
*
*/
private final void addLinks(final SpannableString string, final long account_id, final int type,
private final void addLinks(final SpannableString string, final long accountId, final int type,
final boolean sensitive, final OnLinkClickListener listener, final int highlightOption,
final int highlightColor) {
switch (type) {
case LINK_TYPE_MENTION: {
addMentionOrListLinks(string, account_id, listener, highlightOption, highlightColor);
addMentionOrListLinks(string, accountId, listener, highlightOption, highlightColor);
break;
}
case LINK_TYPE_HASHTAG: {
addHashtagLinks(string, account_id, listener, highlightOption, highlightColor);
addHashtagLinks(string, accountId, listener, highlightOption, highlightColor);
break;
}
case LINK_TYPE_LINK: {
@ -230,7 +225,7 @@ public final class TwidereLinkify implements Constants {
continue;
}
string.removeSpan(span);
applyLink(span.getURL(), start, end, string, account_id, LINK_TYPE_LINK, sensitive, listener,
applyLink(span.getURL(), start, end, string, accountId, LINK_TYPE_LINK, sensitive, listener,
highlightOption, highlightColor);
}
final List<Extractor.Entity> urls = mExtractor.extractURLsWithIndices(ParseUtils.parseString(string));
@ -240,7 +235,7 @@ public final class TwidereLinkify implements Constants {
|| string.getSpans(start, end, URLSpan.class).length > 0) {
continue;
}
applyLink(entity.getValue(), start, end, string, account_id, LINK_TYPE_LINK, sensitive, listener,
applyLink(entity.getValue(), start, end, string, accountId, LINK_TYPE_LINK, sensitive, listener,
highlightOption, highlightColor);
}
break;
@ -254,14 +249,14 @@ public final class TwidereLinkify implements Constants {
final int end = string.getSpanEnd(span);
final String url = matcherGroup(matcher, GROUP_ID_TWITTER_STATUS_STATUS_ID);
string.removeSpan(span);
applyLink(url, start, end, string, account_id, LINK_TYPE_STATUS, sensitive, listener,
applyLink(url, start, end, string, accountId, LINK_TYPE_STATUS, sensitive, listener,
highlightOption, highlightColor);
}
}
break;
}
case LINK_TYPE_CASHTAG: {
addCashtagLinks(string, account_id, listener, highlightOption, highlightColor);
addCashtagLinks(string, accountId, listener, highlightOption, highlightColor);
break;
}
default: {

View File

@ -21,10 +21,12 @@ package org.mariotaku.twidere.util.content;
import static android.text.TextUtils.isEmpty;
import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.CancellationSignal;
import org.mariotaku.twidere.util.ArrayUtils;
@ -98,7 +100,8 @@ public class ContentResolverUtils {
return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
}
public static Cursor query(final ContentResolver resolver, final Uri uri, final String[] projection,
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static Cursor query(final ContentResolver resolver, final Uri uri, final String[] projection,
final String selection, final String[] selectionArgs, final String sortOrder,
final CancellationSignal cancellationSignal) {
StrictModeUtils.checkDiskIO();

View File

@ -118,9 +118,6 @@ public final class CursorPaging {
* This method also Validates the preset parameters, and throws
* IllegalStateException if any unsupported parameter is set.
*
* @param supportedParams char array representation of supported parameters
* @param perPageParamName name used for per-page parameter.
* getUserListStatuses() requires "per_page" instead of "count".
* @return list of PostParameter
*/
/* package */List<HttpParameter> asPostParameterList() {

View File

@ -175,7 +175,7 @@ public interface ListsResources {
* This method calls http://api.twitter.com/1.1/lists/members.json
*
* @param listId The id of the list
* @param cursor Breaks the results into pages. A single page contains 20
* @param paging Breaks the results into pages. A single page contains 20
* lists. Provide a value of -1 to begin paging. Provide values
* as returned to in the response body's next_cursor and
* previous_cursor attributes to page back and forth in the list.
@ -359,7 +359,7 @@ public interface ListsResources {
* This method calls http://api.twitter.com/1.1/lists/subscribers.json
*
* @param listId The id of the list
* @param cursor Breaks the results into pages. A single page contains 20
* @param paging Breaks the results into pages. A single page contains 20
* lists. Provide a value of -1 to begin paging. Provide values
* as returned to in the response body's next_cursor and
* previous_cursor attributes to page back and forth in the list.

View File

@ -21,15 +21,13 @@ import java.util.Map;
/**
* Simple MBean interface for APIStatistics. Method-level statistics are exposed
* as a Map of formatted strings
*
*
* @author Nick Dellamaggiore (nick.dellamaggiore <at> gmail.com)
* @see APIStatisticsOpenMBean for a dynamic version of this mbean with tabular
* representation
*/
public interface APIStatisticsMBean extends InvocationStatistics {
public Iterable<? extends InvocationStatistics> getInvocationStatistics();
public Iterable<? extends InvocationStatistics> getInvocationStatistics();
public Map<String, String> getMethodLevelSummariesAsString();
public Map<String, String> getMethodLevelSummariesAsString();
public String getMethodLevelSummary(String methodName);
public String getMethodLevelSummary(String methodName);
}

View File

@ -10,7 +10,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.viewpagerindicator.CirclePageIndicator
<org.mariotaku.twidere.view.LinePageIndicator
android:id="@+id/search_pager_indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -444,7 +444,6 @@
<string name="no_close_after_status_updated_summary">Un regalet per a «chatterbox»</string>
<string name="status_saved_to_draft">S\'ha desat la piulada com a esborrany.</string>
<string name="default_account">Compte per defecte</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (<xliff:g id="daily_tweet">%2$d</xliff:g> piulada/es al dia)</string>
<string name="empty_content">No hi ha contingut</string>
<string name="fast_image_loading">Càrrega ràpida de les imatges</string>
<string name="fast_image_loading_summary">Habilita-ho per a carregar més ràpidament les imatges, però inhabilita-ho si no se\'t mostra alguna imatge.</string>

View File

@ -445,7 +445,6 @@
<string name="no_close_after_status_updated_summary">Ein kleines Geschenk an die Chatterbox</string>
<string name="status_saved_to_draft">Tweet als Entwurf gespeichert.</string>
<string name="default_account">Standard-Account</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (<xliff:g id="daily_tweet">%2$d</xliff:g> Tweet(s) pro Tag)</string>
<string name="empty_content">Leerer Inhalt</string>
<string name="fast_image_loading">Schnelleres Bilder laden</string>
<string name="fast_image_loading_summary">Aktivieren um Bilder schneller zu laden, deaktiveren falls einige Bilder nicht angezeigt werden können.</string>

View File

@ -447,7 +447,6 @@
<string name="no_close_after_status_updated_summary">Un pequeño regalo para chatterbox</string>
<string name="status_saved_to_draft">Tuit salvado como borrador.</string>
<string name="default_account">Cuenta predeterminada</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (<xliff:g id="daily_tweet">%2$d</xliff:g> tweet(s) por dia)</string>
<string name="empty_content">Contenido vacío</string>
<string name="fast_image_loading">Carga rápida de imágenes</string>
<string name="fast_image_loading_summary">Habilitar para acelerar la carga de imágenes, deshabilitar si algunas imágenes no se muestran.</string>

View File

@ -447,7 +447,6 @@
<string name="no_close_after_status_updated_summary">Pieni lisä chatterboxiin</string>
<string name="status_saved_to_draft">Twiitti tallennettu luonnoksiin.</string>
<string name="default_account">Oletustili</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (<xliff:g id="daily_tweet">%2$d</xliff:g> twiittiä päivää kohden)</string>
<string name="empty_content">Tyhjennä sisältö</string>
<string name="fast_image_loading">Kuvien nopea lataus</string>
<string name="fast_image_loading_summary">Ota käyttöön, jotta kuvat latautuvat nopeammin. Ota pois käytöstä, jos jotkin kuvat eivät näy.</string>

View File

@ -444,7 +444,6 @@
<string name="no_close_after_status_updated_summary">Un petit cadeau pour Chatterbox</string>
<string name="status_saved_to_draft">Tweet sauvegardé dans les brouillons.</string>
<string name="default_account">Compte par défault</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (<xliff:g id="daily_tweet">%2$d</xliff:g> tweet(s) par jour)</string>
<string name="empty_content">Contenu vide</string>
<string name="fast_image_loading">Chargement de l\'image rapide</string>
<string name="fast_image_loading_summary">Activer pour permettre aux images de se charger plus rapidement, désactiver si des images ne s\'affichent pas.</string>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="profile_image_size" translatable="false">bigger</string>
</resources>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="profile_image_size">bigger</string>
</resources>

View File

@ -444,7 +444,6 @@
<string name="no_close_after_status_updated_summary">Pemberian kecil untuk chatterbox</string>
<string name="status_saved_to_draft">Twit disimpan di draf.</string>
<string name="default_account">Pengguna utama</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (<xliff:g id="daily_tweet">%2$d</xliff:g> tweet per hari)</string>
<string name="empty_content">Konten kosong</string>
<string name="fast_image_loading">Memuat gambar dengan cepat</string>
<string name="fast_image_loading_summary">Aktifkan untuk membuat gambar dimuat dengan cepat, nonaktifkan ini jika beberapa gambar tidak bisa ditampilkan.</string>

View File

@ -442,7 +442,6 @@
<string name="no_close_after_status_updated_summary">Un piccolo regalo per i chiacchieroni</string>
<string name="status_saved_to_draft">Tweet salvato in bozze.</string>
<string name="default_account">Account principale</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (<xliff:g id="daily_tweet">%2$d</xliff:g>tweet al giorno)</string>
<string name="empty_content">Contenuto vuoto</string>
<string name="fast_image_loading">Caricamento veloce immagini</string>
<string name="fast_image_loading_summary">Seleziona per far caricare più velocemente le immagini, disattivalo se alcune immagini non sono mostrate correttamente.</string>

View File

@ -447,7 +447,6 @@
<string name="no_close_after_status_updated_summary">ツイート編集画面の動作を変更します。</string>
<string name="status_saved_to_draft">ツイートは下書きに保存されました。</string>
<string name="default_account">デフォルト</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (一日に平均<xliff:g id="daily_tweet">%2$d</xliff:g>回ツイート)</string>
<string name="empty_content">コンテンツなし</string>
<string name="fast_image_loading">高速画像読み込み</string>
<string name="fast_image_loading_summary">有効にすると画像を高速に読み込みます。\n画像が読み込めない場合は無効にしてください。</string>

View File

@ -444,7 +444,6 @@
<string name="no_close_after_status_updated_summary">트윗 입력창에 작은 특전이 있습니다.</string>
<string name="status_saved_to_draft">트윗이 보관함에 저장되었습니다.</string>
<string name="default_account">기본 계정</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (하루에 <xliff:g id="daily_tweet">%2$d</xliff:g> 트윗)</string>
<string name="empty_content">내용 없음</string>
<string name="fast_image_loading">빠른 이미지 불러오기</string>
<string name="fast_image_loading_summary">이미지를 빨리 불러오려면 설정하고 이미지가 보이지 않으면 체크를 해재해 주십시오.</string>
@ -529,7 +528,7 @@
<string name="no_tab_hint">탭 없음</string>
<string name="delete_user"><xliff:g id="name">%s</xliff:g>님을 삭제하기</string>
<string name="delete_users">사용자 삭제하기</string>
<string name="delete_user_confirm_message"> <xliff:g id="name">%s</xliff:g>?님을 삭제하겠습니까? 되돌릴 수 없습니다.</string>
<string name="delete_user_confirm_message"> <xliff:g id="name">%s</xliff:g>님을 삭제하겠습니까? 되돌릴 수 없습니다.</string>
<string name="toggle">토글</string>
<string name="general">일반</string>
<string name="hints">힌트</string>

View File

@ -444,7 +444,6 @@
<string name="no_close_after_status_updated_summary">Een klein cadeau voor chatterbox</string>
<string name="status_saved_to_draft">Tweet opgeslagen als ontwerp.</string>
<string name="default_account">Standaard account</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g>(<xliff:g id="daily_tweet">%2$d</xliff:g> tweet(s) per dag)</string>
<string name="empty_content">Lege inhoud</string>
<string name="fast_image_loading">Snel foto\'s laden</string>
<string name="fast_image_loading_summary">Schakel in om foto\'s sneller te laten laden, schakel uit als sommige foto\'s niet worden weergegeven.</string>

View File

@ -442,7 +442,6 @@ Twidere używa znacznie prostszego mechanizmu logowania, bez otwierania okna prz
<string name="no_close_after_status_updated_summary">Drobny prezent dla gaduł</string>
<string name="status_saved_to_draft">Ćwierk zapisany jako szkic.</string>
<string name="default_account">Domyślne konto</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (<xliff:g id="daily_tweet">%2$d</xliff:g> ćwierknięć na dzień)</string>
<string name="empty_content">Pusta zawartość</string>
<string name="fast_image_loading">Szybkie ładowanie obrazów</string>
<string name="fast_image_loading_summary">Włącz aby ładować obrazy szybciej, wyłącz w przypadku błędów wyświetlania.</string>

View File

@ -449,7 +449,6 @@
<string name="no_close_after_status_updated_summary">Um presentinho para os tagarelas</string>
<string name="status_saved_to_draft">Tweet salvo como rascunho.</string>
<string name="default_account">Conta padrão</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (<xliff:g id="daily_tweet">%2$d</xliff:g> tweet(s) por dia)</string>
<string name="empty_content">Nenhum conteúdo</string>
<string name="fast_image_loading">Carregamento rápido de imagens</string>
<string name="fast_image_loading_summary">Ative para fazer as imagens carregarem mais rápido, desative se alguma apresentar problemas ao carregar.</string>

View File

@ -447,7 +447,6 @@
<string name="no_close_after_status_updated_summary">Небольшой подарок для любителей поболтать</string>
<string name="status_saved_to_draft">Твит сохранен в черновик.</string>
<string name="default_account">Аккаунт по умолчанию</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g>(<xliff:g id="daily_tweet">%2$d</xliff:g>твитов за день)</string>
<string name="empty_content">Пустое содержимое</string>
<string name="fast_image_loading">Быстрая загрузка изображений</string>
<string name="fast_image_loading_summary">Включите, для более быстрой загрузки изображений, отключите, если некоторые изображения не показываются.</string>

View File

@ -376,7 +376,6 @@
<string name="ask">ถาม</string>
<string name="status_saved_to_draft">บันทึกข้อความร่างแล้ว</string>
<string name="default_account">บัญชีหลัก</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (ทวีต <xliff:g id="daily_tweet">%2$d</xliff:g> ต่อวัน)</string>
<string name="select_user">เลือกผู้ใช้</string>
<string name="add_to_list">เพิ่มไปยังรายการ</string>
<string name="account_delete_confirm_title">ลบบัญชี</string>

View File

@ -444,7 +444,6 @@
<string name="no_close_after_status_updated_summary">Маленький подарунок для базіки</string>
<string name="status_saved_to_draft">Твіт збережено у чернетці.</string>
<string name="default_account">Типовий профіль</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (<xliff:g id="daily_tweet">%2$d</xliff:g> твіт(ів) на день)</string>
<string name="empty_content">Порожній вміст</string>
<string name="fast_image_loading">Швидке завантаження зображення</string>
<string name="fast_image_loading_summary">Вмикання робить завантаження зображень швидшим, вимкніть це, якщо деякі малюнки не відображаються.</string>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="profile_image_size" translatable="false">reasonably_small</string>
</resources>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="profile_image_size">reasonably_small</string>
</resources>

View File

@ -444,7 +444,6 @@
<string name="no_close_after_status_updated_summary">給不二的小禮物</string>
<string name="status_saved_to_draft">推文已經儲存到草稿箱</string>
<string name="default_account">預設帳號</string>
<string name="daily_statuses_count"><xliff:g id="created_at">%1$s</xliff:g> (每天<xliff:g id="daily_tweet">%2$d</xliff:g>推)</string>
<string name="empty_content">空內容</string>
<string name="fast_image_loading">快速圖像載入</string>
<string name="fast_image_loading_summary">啟用可以使圖片載入更快,如果一些圖片不能顯示的話則可以把它關閉</string>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="default_tab_display_option">icon</string>
<string name="default_tab_display_option" translatable="false">icon</string>
<string name="profile_image_size" translatable="false">normal</string>
</resources>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">Twidere</string>
<string name="theme_twidere">@string/app_name</string>
<string name="nyan_sakamoto" translatable="false">Nyan Sakamoto!</string>
<string name="kuma_union" translatable="false">熊孩子联盟</string>
<string name="developer_name" translatable="false">Mariotaku Lee</string>
<string name="project_name" translatable="false">Twidere Project</string>
<string name="font_family_regular" translatable="false">Regular</string>
<string name="font_family_condensed" translatable="false">Condensed</string>
<string name="font_family_light" translatable="false">Light</string>
<string name="font_family_thin" translatable="false">Thin</string>
<string name="easter_egg_triggered_message" translatable="false">不二对你的膝盖发动了会心一击!</string>
</resources>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Twidere</string>
<string name="theme_twidere">@string/app_name</string>
<string name="nyan_sakamoto">Nyan Sakamoto!</string>
<string name="kuma_union">熊孩子联盟</string>
<string name="developer_name">Mariotaku Lee</string>
<string name="project_name">Twidere Project</string>
<string name="font_family_regular">Regular</string>
<string name="font_family_condensed">Condensed</string>
<string name="font_family_light">Light</string>
<string name="font_family_thin">Thin</string>
<string name="profile_image_size">normal</string>
<string name="easter_egg_triggered_message">不二对你的膝盖发动了会心一击!</string>
</resources>

View File

@ -16,7 +16,7 @@
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/../app/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
@ -63,7 +63,9 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="support-v13-20.0.0" level="project" />
<orderEntry type="library" exported="" name="library-2.0.0" level="project" />
<orderEntry type="library" exported="" name="android-easing-1.0.3" level="project" />
<orderEntry type="library" exported="" name="httpclient-android-4.3.3" level="project" />
<orderEntry type="library" exported="" name="imagezoom-1.0.5" level="project" />
<orderEntry type="library" exported="" name="play-services-5.0.77" level="project" />
<orderEntry type="library" exported="" name="merge-1.0.1" level="project" />
<orderEntry type="library" exported="" name="library-1.0.5" level="project" />