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 /.idea/workspace.xml
.DS_Store .DS_Store
/build /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 * [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 * [ACRA](http://github.com/ACRA/acra), Copyright 2013 Kevin Gaudin
* [drag-sort-listview](https://github.com/bauerca/drag-sort-listview), Copyright 2012 Carl Bauer * [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 * [MenuComponent-Android](https://github.com/mariotaku/MenuComponent-Android), Copyright 2014 Mariotaku Lee
* [RefreshNow](https://github.com/mariotaku/RefreshNow), 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 * [AndroidStaggeredGrid](https://github.com/etsy/AndroidStaggeredGrid), Copyright 2013 Etsy
* [cwac-merge](https://github.com/commonsguy/cwac-merge), Copyright 2013 CommonsWare * [cwac-merge](https://github.com/commonsguy/cwac-merge), Copyright 2013 CommonsWare
* [cwac-sacklist](https://github.com/commonsguy/cwac-sacklist), 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** **Donation methods**
PayPal: "mariotaku.lee#gmail.com".replace("#", "@"); PayPal & AliPay: "mariotaku.lee#gmail.com".replace("#", "@");
AliPay: http://me.alipay.com/mariotaku
Bitcoin: 1FHAVAzge7cj1LfCTMfnLL49DgA3mVUCuW Bitcoin: 1FHAVAzge7cj1LfCTMfnLL49DgA3mVUCuW

View File

@ -11,6 +11,30 @@ android {
versionCode 95 versionCode 95
versionName "0.2.9.14" 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 { packagingOptions {
exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE' exclude 'META-INF/LICENSE'
@ -22,8 +46,15 @@ android {
exclude 'META-INF/ASL2.0' exclude 'META-INF/ASL2.0'
} }
buildTypes { 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.negusoft.holoaccent:library:+'
compile 'com.etsy.android.grid:library:1.0.5' compile 'com.etsy.android.grid:library:1.0.5'
compile 'com.sothree.slidinguppanel:library:2.0.0' 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.twitter:twitter-text:1.9.5'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.2' compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.2'
compile 'org.apache.httpcomponents:httpclient-android:4.3.3' 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. * Set a drawable used for edge shadow.
* *
* @param shadow Drawable to use * @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_LEFT
* @see #EDGE_RIGHT * @see #EDGE_RIGHT
* @see #EDGE_BOTTOM * @see #EDGE_BOTTOM
@ -355,7 +355,7 @@ public class SwipeBackLayout extends FrameLayout {
* Set a drawable used for edge shadow. * Set a drawable used for edge shadow.
* *
* @param resId Resource of drawable to use * @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_LEFT
* @see #EDGE_RIGHT * @see #EDGE_RIGHT
* @see #EDGE_BOTTOM * @see #EDGE_BOTTOM

View File

@ -19,16 +19,12 @@
package org.mariotaku.twidere.activity; 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;
import android.app.ActionBar.Tab; import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener; import android.app.ActionBar.TabListener;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.AlertDialog.Builder; import android.app.AlertDialog.Builder;
import android.app.Dialog; import android.app.Dialog;
import android.app.Fragment;
import android.app.FragmentTransaction; import android.app.FragmentTransaction;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.ContentValues; import android.content.ContentValues;
@ -39,6 +35,7 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener; import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v4.widget.SimpleCursorAdapter; import android.support.v4.widget.SimpleCursorAdapter;
@ -50,227 +47,231 @@ import android.widget.AutoCompleteTextView;
import org.mariotaku.querybuilder.Where; import org.mariotaku.querybuilder.Where;
import org.mariotaku.twidere.R; import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
import org.mariotaku.twidere.activity.support.UserListSelectorActivity; import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
import org.mariotaku.twidere.adapter.SourceAutoCompleteAdapter; import org.mariotaku.twidere.adapter.SourceAutoCompleteAdapter;
import org.mariotaku.twidere.adapter.TabsAdapter;
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter; 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;
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredKeywordsFragment; import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredKeywordsFragment;
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredLinksFragment; import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredLinksFragment;
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredSourcesFragment; import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredSourcesFragment;
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredUsersFragment; import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredUsersFragment;
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.provider.TweetStore.Filters; import org.mariotaku.twidere.provider.TweetStore.Filters;
import org.mariotaku.twidere.util.ParseUtils; import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.ThemeUtils; 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"; public class FiltersActivity extends BaseSupportActivity implements TabListener, OnPageChangeListener {
private static final int AUTO_COMPLETE_TYPE_SOURCES = 2;
private ViewPager mViewPager; private static final String EXTRA_AUTO_COMPLETE_TYPE = "auto_complete_type";
private TabsAdapter mAdapter; private static final int AUTO_COMPLETE_TYPE_SOURCES = 2;
private ActionBar mActionBar; private ViewPager mViewPager;
private SharedPreferences mPreferences; private SupportTabsAdapter mAdapter;
@Override private ActionBar mActionBar;
public void onContentChanged() { private SharedPreferences mPreferences;
mViewPager = (ViewPager) findViewById(R.id.pager);
}
@Override @Override
public void onCreate(final Bundle savedInstanceState) { public void onContentChanged() {
super.onCreate(savedInstanceState); mViewPager = (ViewPager) findViewById(R.id.pager);
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 @Override
public boolean onCreateOptionsMenu(final Menu menu) { public void onCreate(final Bundle savedInstanceState) {
getMenuInflater().inflate(R.menu.menu_filters, menu); super.onCreate(savedInstanceState);
return true; 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 @Override
public boolean onOptionsItemSelected(final MenuItem item) { public boolean onCreateOptionsMenu(final Menu menu) {
switch (item.getItemId()) { getMenuInflater().inflate(R.menu.menu_filters, menu);
case MENU_HOME: { return true;
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 @Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) { 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 @Override
public void onPageScrollStateChanged(final int state) { 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 @Override
public boolean onPrepareOptionsMenu(final Menu menu) { public void onPageSelected(final int position) {
final boolean enable_in_home_timeline = mPreferences.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true); if (mActionBar == null) return;
final boolean enable_in_mentions = mPreferences.getBoolean(KEY_FILTERS_IN_MENTIONS, true); mActionBar.setSelectedNavigationItem(position);
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 @Override
public void onTabReselected(final Tab tab, final FragmentTransaction ft) { 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 @Override
public void onTabUnselected(final Tab tab, final FragmentTransaction ft) { 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) { @Override
if (mActionBar == null || mAdapter == null) return; protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
mActionBar.addTab(mActionBar.newTab().setText(name).setTabListener(this)); switch (requestCode) {
mAdapter.addTab(cls, null, getString(name), null, position); 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 private SimpleCursorAdapter mUserAutoCompleteAdapter;
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 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() { @Override
return ParseUtils.parseString(mEditText.getText()); 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) { protected String getText() {
// TODO Auto-generated method stub 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; 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.content.Context;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
@ -39,105 +36,113 @@ import org.mariotaku.twidere.view.TabPageIndicator.TabProvider;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; 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, 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 Context mContext;
private final TabPageIndicator mIndicator; private final TabPageIndicator mIndicator;
private final int mColumns; private final int mColumns;
public SupportTabsAdapter(final Context context, final FragmentManager fm, final TabPageIndicator indicator, public SupportTabsAdapter(final Context context, final FragmentManager fm, final TabPageIndicator indicator) {
final int columns) { this(context, fm, indicator, 1);
super(fm); }
mContext = context;
mIndicator = indicator;
mColumns = columns;
clear();
}
public void addTab(final Class<? extends Fragment> cls, final Bundle args, final String name, final Integer icon, public SupportTabsAdapter(final Context context, final FragmentManager fm, final TabPageIndicator indicator,
final int position) { final int columns) {
addTab(new SupportTabSpec(name, icon, cls, args, position)); super(fm);
} mContext = context;
mIndicator = indicator;
mColumns = columns;
clear();
}
public void addTab(final SupportTabSpec spec) { public void addTab(final Class<? extends Fragment> cls, final Bundle args, final String name, final Integer icon,
mTabs.add(spec); final int position) {
notifyDataSetChanged(); addTab(new SupportTabSpec(name, icon, cls, args, position));
} }
public void addTabs(final Collection<? extends SupportTabSpec> specs) { public void addTab(final SupportTabSpec spec) {
mTabs.addAll(specs); mTabs.add(spec);
notifyDataSetChanged(); notifyDataSetChanged();
} }
public void clear() { public void addTabs(final Collection<? extends SupportTabSpec> specs) {
mTabs.clear(); mTabs.addAll(specs);
notifyDataSetChanged(); notifyDataSetChanged();
} }
@Override public void clear() {
public int getCount() { mTabs.clear();
return mTabs.size(); notifyDataSetChanged();
} }
@Override @Override
public Fragment getItem(final int position) { public int getCount() {
final Fragment fragment = Fragment.instantiate(mContext, mTabs.get(position).cls.getName()); return mTabs.size();
fragment.setArguments(mTabs.get(position).args); }
return fragment;
}
@Override @Override
public Drawable getPageIcon(final int position) { public Fragment getItem(final int position) {
return getTabIconDrawable(mContext, mTabs.get(position).icon); final Fragment fragment = Fragment.instantiate(mContext, mTabs.get(position).cls.getName());
} fragment.setArguments(mTabs.get(position).args);
return fragment;
}
@Override @Override
public CharSequence getPageTitle(final int position) { public Drawable getPageIcon(final int position) {
return mTabs.get(position).name; return getTabIconDrawable(mContext, mTabs.get(position).icon);
} }
@Override @Override
public float getPageWidth(final int position) { public CharSequence getPageTitle(final int position) {
return 1.0f / mColumns; return mTabs.get(position).name;
} }
public SupportTabSpec getTab(final int position) { @Override
return position >= 0 && position < mTabs.size() ? mTabs.get(position) : null; public float getPageWidth(final int position) {
} return 1.0f / mColumns;
}
@Override public SupportTabSpec getTab(final int position) {
public void notifyDataSetChanged() { return position >= 0 && position < mTabs.size() ? mTabs.get(position) : null;
super.notifyDataSetChanged(); }
if (mIndicator != null) {
mIndicator.notifyDataSetChanged();
}
}
@Override @Override
public void onPageReselected(final int position) { public void notifyDataSetChanged() {
if (!(mContext instanceof SupportFragmentCallback)) return; super.notifyDataSetChanged();
final Fragment f = ((SupportFragmentCallback) mContext).getCurrentVisibleFragment(); if (mIndicator != null) {
if (f instanceof RefreshScrollTopInterface) { mIndicator.notifyDataSetChanged();
((RefreshScrollTopInterface) f).scrollToStart(); }
} }
}
@Override @Override
public void onPageSelected(final int position) { public void onPageReselected(final int position) {
if (mIndicator == null) return; if (!(mContext instanceof SupportFragmentCallback)) return;
announceForAccessibilityCompat(mContext, mIndicator, getPageTitle(position), getClass()); final Fragment f = ((SupportFragmentCallback) mContext).getCurrentVisibleFragment();
} if (f instanceof RefreshScrollTopInterface) {
((RefreshScrollTopInterface) f).scrollToStart();
}
}
@Override @Override
public boolean onTabLongClick(final int position) { public void onPageSelected(final int position) {
if (!(mContext instanceof SupportFragmentCallback)) return false; if (mIndicator == null) return;
if (((SupportFragmentCallback) mContext).triggerRefresh(position)) return true; announceForAccessibilityCompat(mContext, mIndicator, getPageTitle(position), getClass());
final Fragment f = ((SupportFragmentCallback) mContext).getCurrentVisibleFragment(); }
if (f instanceof RefreshScrollTopInterface) return ((RefreshScrollTopInterface) f).triggerRefresh();
return false; @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 static org.mariotaku.twidere.util.Utils.getDisplayName;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.Loader;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; 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.ActionMode;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@ -49,9 +49,10 @@ import org.mariotaku.querybuilder.Columns.Column;
import org.mariotaku.querybuilder.RawItemArray; import org.mariotaku.querybuilder.RawItemArray;
import org.mariotaku.querybuilder.Where; import org.mariotaku.querybuilder.Where;
import org.mariotaku.twidere.R; import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.support.BaseSupportListFragment;
import org.mariotaku.twidere.provider.TweetStore.Filters; 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 { MultiChoiceModeListener {
private ListView mListView; private ListView mListView;

View File

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

View File

@ -202,23 +202,18 @@ public final class TwidereLinkify implements Constants {
* @param highlightColor * @param highlightColor
* @param highlightOption * @param highlightOption
* @param listener * @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 boolean sensitive, final OnLinkClickListener listener, final int highlightOption,
final int highlightColor) { final int highlightColor) {
switch (type) { switch (type) {
case LINK_TYPE_MENTION: { case LINK_TYPE_MENTION: {
addMentionOrListLinks(string, account_id, listener, highlightOption, highlightColor); addMentionOrListLinks(string, accountId, listener, highlightOption, highlightColor);
break; break;
} }
case LINK_TYPE_HASHTAG: { case LINK_TYPE_HASHTAG: {
addHashtagLinks(string, account_id, listener, highlightOption, highlightColor); addHashtagLinks(string, accountId, listener, highlightOption, highlightColor);
break; break;
} }
case LINK_TYPE_LINK: { case LINK_TYPE_LINK: {
@ -230,7 +225,7 @@ public final class TwidereLinkify implements Constants {
continue; continue;
} }
string.removeSpan(span); 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); highlightOption, highlightColor);
} }
final List<Extractor.Entity> urls = mExtractor.extractURLsWithIndices(ParseUtils.parseString(string)); 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) { || string.getSpans(start, end, URLSpan.class).length > 0) {
continue; 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); highlightOption, highlightColor);
} }
break; break;
@ -254,14 +249,14 @@ public final class TwidereLinkify implements Constants {
final int end = string.getSpanEnd(span); final int end = string.getSpanEnd(span);
final String url = matcherGroup(matcher, GROUP_ID_TWITTER_STATUS_STATUS_ID); final String url = matcherGroup(matcher, GROUP_ID_TWITTER_STATUS_STATUS_ID);
string.removeSpan(span); 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); highlightOption, highlightColor);
} }
} }
break; break;
} }
case LINK_TYPE_CASHTAG: { case LINK_TYPE_CASHTAG: {
addCashtagLinks(string, account_id, listener, highlightOption, highlightColor); addCashtagLinks(string, accountId, listener, highlightOption, highlightColor);
break; break;
} }
default: { default: {

View File

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

View File

@ -118,9 +118,6 @@ public final class CursorPaging {
* This method also Validates the preset parameters, and throws * This method also Validates the preset parameters, and throws
* IllegalStateException if any unsupported parameter is set. * 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 * @return list of PostParameter
*/ */
/* package */List<HttpParameter> asPostParameterList() { /* 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 * This method calls http://api.twitter.com/1.1/lists/members.json
* *
* @param listId The id of the list * @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 * lists. Provide a value of -1 to begin paging. Provide values
* as returned to in the response body's next_cursor and * as returned to in the response body's next_cursor and
* previous_cursor attributes to page back and forth in the list. * 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 * This method calls http://api.twitter.com/1.1/lists/subscribers.json
* *
* @param listId The id of the list * @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 * lists. Provide a value of -1 to begin paging. Provide values
* as returned to in the response body's next_cursor and * as returned to in the response body's next_cursor and
* previous_cursor attributes to page back and forth in the list. * 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 * Simple MBean interface for APIStatistics. Method-level statistics are exposed
* as a Map of formatted strings * as a Map of formatted strings
* *
* @author Nick Dellamaggiore (nick.dellamaggiore <at> gmail.com) * @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 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_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent"/>
<com.viewpagerindicator.CirclePageIndicator <org.mariotaku.twidere.view.LinePageIndicator
android:id="@+id/search_pager_indicator" android:id="@+id/search_pager_indicator"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" 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="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="status_saved_to_draft">S\'ha desat la piulada com a esborrany.</string>
<string name="default_account">Compte per defecte</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="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">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> <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="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="status_saved_to_draft">Tweet als Entwurf gespeichert.</string>
<string name="default_account">Standard-Account</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="empty_content">Leerer Inhalt</string>
<string name="fast_image_loading">Schnelleres Bilder laden</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> <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="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="status_saved_to_draft">Tuit salvado como borrador.</string>
<string name="default_account">Cuenta predeterminada</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="empty_content">Contenido vacío</string>
<string name="fast_image_loading">Carga rápida de imágenes</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> <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="no_close_after_status_updated_summary">Pieni lisä chatterboxiin</string>
<string name="status_saved_to_draft">Twiitti tallennettu luonnoksiin.</string> <string name="status_saved_to_draft">Twiitti tallennettu luonnoksiin.</string>
<string name="default_account">Oletustili</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="empty_content">Tyhjennä sisältö</string>
<string name="fast_image_loading">Kuvien nopea lataus</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> <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="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="status_saved_to_draft">Tweet sauvegardé dans les brouillons.</string>
<string name="default_account">Compte par défault</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="empty_content">Contenu vide</string>
<string name="fast_image_loading">Chargement de l\'image rapide</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> <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="no_close_after_status_updated_summary">Pemberian kecil untuk chatterbox</string>
<string name="status_saved_to_draft">Twit disimpan di draf.</string> <string name="status_saved_to_draft">Twit disimpan di draf.</string>
<string name="default_account">Pengguna utama</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="empty_content">Konten kosong</string>
<string name="fast_image_loading">Memuat gambar dengan cepat</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> <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="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="status_saved_to_draft">Tweet salvato in bozze.</string>
<string name="default_account">Account principale</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="empty_content">Contenuto vuoto</string>
<string name="fast_image_loading">Caricamento veloce immagini</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> <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="no_close_after_status_updated_summary">ツイート編集画面の動作を変更します。</string>
<string name="status_saved_to_draft">ツイートは下書きに保存されました。</string> <string name="status_saved_to_draft">ツイートは下書きに保存されました。</string>
<string name="default_account">デフォルト</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="empty_content">コンテンツなし</string>
<string name="fast_image_loading">高速画像読み込み</string> <string name="fast_image_loading">高速画像読み込み</string>
<string name="fast_image_loading_summary">有効にすると画像を高速に読み込みます。\n画像が読み込めない場合は無効にしてください。</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="no_close_after_status_updated_summary">트윗 입력창에 작은 특전이 있습니다.</string>
<string name="status_saved_to_draft">트윗이 보관함에 저장되었습니다.</string> <string name="status_saved_to_draft">트윗이 보관함에 저장되었습니다.</string>
<string name="default_account">기본 계정</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="empty_content">내용 없음</string>
<string name="fast_image_loading">빠른 이미지 불러오기</string> <string name="fast_image_loading">빠른 이미지 불러오기</string>
<string name="fast_image_loading_summary">이미지를 빨리 불러오려면 설정하고 이미지가 보이지 않으면 체크를 해재해 주십시오.</string> <string name="fast_image_loading_summary">이미지를 빨리 불러오려면 설정하고 이미지가 보이지 않으면 체크를 해재해 주십시오.</string>
@ -529,7 +528,7 @@
<string name="no_tab_hint">탭 없음</string> <string name="no_tab_hint">탭 없음</string>
<string name="delete_user"><xliff:g id="name">%s</xliff:g>님을 삭제하기</string> <string name="delete_user"><xliff:g id="name">%s</xliff:g>님을 삭제하기</string>
<string name="delete_users">사용자 삭제하기</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="toggle">토글</string>
<string name="general">일반</string> <string name="general">일반</string>
<string name="hints">힌트</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="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="status_saved_to_draft">Tweet opgeslagen als ontwerp.</string>
<string name="default_account">Standaard account</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="empty_content">Lege inhoud</string>
<string name="fast_image_loading">Snel foto\'s laden</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> <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="no_close_after_status_updated_summary">Drobny prezent dla gaduł</string>
<string name="status_saved_to_draft">Ćwierk zapisany jako szkic.</string> <string name="status_saved_to_draft">Ćwierk zapisany jako szkic.</string>
<string name="default_account">Domyślne konto</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="empty_content">Pusta zawartość</string>
<string name="fast_image_loading">Szybkie ładowanie obrazów</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> <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="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="status_saved_to_draft">Tweet salvo como rascunho.</string>
<string name="default_account">Conta padrão</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="empty_content">Nenhum conteúdo</string>
<string name="fast_image_loading">Carregamento rápido de imagens</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> <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="no_close_after_status_updated_summary">Небольшой подарок для любителей поболтать</string>
<string name="status_saved_to_draft">Твит сохранен в черновик.</string> <string name="status_saved_to_draft">Твит сохранен в черновик.</string>
<string name="default_account">Аккаунт по умолчанию</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="empty_content">Пустое содержимое</string>
<string name="fast_image_loading">Быстрая загрузка изображений</string> <string name="fast_image_loading">Быстрая загрузка изображений</string>
<string name="fast_image_loading_summary">Включите, для более быстрой загрузки изображений, отключите, если некоторые изображения не показываются.</string> <string name="fast_image_loading_summary">Включите, для более быстрой загрузки изображений, отключите, если некоторые изображения не показываются.</string>

View File

@ -376,7 +376,6 @@
<string name="ask">ถาม</string> <string name="ask">ถาม</string>
<string name="status_saved_to_draft">บันทึกข้อความร่างแล้ว</string> <string name="status_saved_to_draft">บันทึกข้อความร่างแล้ว</string>
<string name="default_account">บัญชีหลัก</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="select_user">เลือกผู้ใช้</string>
<string name="add_to_list">เพิ่มไปยังรายการ</string> <string name="add_to_list">เพิ่มไปยังรายการ</string>
<string name="account_delete_confirm_title">ลบบัญชี</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="no_close_after_status_updated_summary">Маленький подарунок для базіки</string>
<string name="status_saved_to_draft">Твіт збережено у чернетці.</string> <string name="status_saved_to_draft">Твіт збережено у чернетці.</string>
<string name="default_account">Типовий профіль</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="empty_content">Порожній вміст</string>
<string name="fast_image_loading">Швидке завантаження зображення</string> <string name="fast_image_loading">Швидке завантаження зображення</string>
<string name="fast_image_loading_summary">Вмикання робить завантаження зображень швидшим, вимкніть це, якщо деякі малюнки не відображаються.</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="no_close_after_status_updated_summary">給不二的小禮物</string>
<string name="status_saved_to_draft">推文已經儲存到草稿箱</string> <string name="status_saved_to_draft">推文已經儲存到草稿箱</string>
<string name="default_account">預設帳號</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="empty_content">空內容</string>
<string name="fast_image_loading">快速圖像載入</string> <string name="fast_image_loading">快速圖像載入</string>
<string name="fast_image_loading_summary">啟用可以使圖片載入更快,如果一些圖片不能顯示的話則可以把它關閉</string> <string name="fast_image_loading_summary">啟用可以使圖片載入更快,如果一些圖片不能顯示的話則可以把它關閉</string>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <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> </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="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> <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" /> <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration> </configuration>
</facet> </facet>
@ -63,7 +63,9 @@
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="support-v13-20.0.0" level="project" /> <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="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="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="play-services-5.0.77" level="project" />
<orderEntry type="library" exported="" name="merge-1.0.1" level="project" /> <orderEntry type="library" exported="" name="merge-1.0.1" level="project" />
<orderEntry type="library" exported="" name="library-1.0.5" level="project" /> <orderEntry type="library" exported="" name="library-1.0.5" level="project" />