Merge branch 'master' into fsvideo-test
This commit is contained in:
commit
2b6c8116b8
@ -27,7 +27,6 @@ dependencies {
|
|||||||
compile files('libs/dashclock-api-r1.1.jar')
|
compile files('libs/dashclock-api-r1.1.jar')
|
||||||
compile files('libs/jsoup-1.6.1.jar')
|
compile files('libs/jsoup-1.6.1.jar')
|
||||||
compile files('libs/universal-image-loader-1.9.3.jar')
|
compile files('libs/universal-image-loader-1.9.3.jar')
|
||||||
compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
|
|
||||||
compile 'com.viewpagerindicator:library:2.4.1'
|
compile 'com.viewpagerindicator:library:2.4.1'
|
||||||
compile 'com.android.support:cardview-v7:21.0.0'
|
compile 'com.android.support:cardview-v7:21.0.0'
|
||||||
compile 'com.android.support:support-v4:21.0.0'
|
compile 'com.android.support:support-v4:21.0.0'
|
||||||
|
@ -85,7 +85,6 @@
|
|||||||
<orderEntry type="library" exported="" name="jsoup-1.6.1" level="project" />
|
<orderEntry type="library" exported="" name="jsoup-1.6.1" level="project" />
|
||||||
<orderEntry type="library" exported="" name="library-2.4.1" level="project" />
|
<orderEntry type="library" exported="" name="library-2.4.1" level="project" />
|
||||||
<orderEntry type="library" exported="" name="support-v4-21.0.0" level="project" />
|
<orderEntry type="library" exported="" name="support-v4-21.0.0" level="project" />
|
||||||
<orderEntry type="library" exported="" name="systembartint-1.0.3" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="universal-image-loader-1.9.3" level="project" />
|
<orderEntry type="library" exported="" name="universal-image-loader-1.9.3" level="project" />
|
||||||
<orderEntry type="library" exported="" name="appcompat-v7-21.0.0" level="project" />
|
<orderEntry type="library" exported="" name="appcompat-v7-21.0.0" level="project" />
|
||||||
<orderEntry type="library" exported="" name="dashclock-api-r1.1" level="project" />
|
<orderEntry type="library" exported="" name="dashclock-api-r1.1" level="project" />
|
||||||
|
@ -0,0 +1,268 @@
|
|||||||
|
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.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.GestureDetector;
|
||||||
|
import android.view.GestureDetector.OnGestureListener;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.ScaleGestureDetector;
|
||||||
|
import android.view.ScaleGestureDetector.OnScaleGestureListener;
|
||||||
|
import android.view.ViewConfiguration;
|
||||||
|
|
||||||
|
public class ImageViewTouch extends ImageViewTouchBase {
|
||||||
|
|
||||||
|
private static final float SCROLL_DELTA_THRESHOLD = 1.0f;
|
||||||
|
static final float MIN_ZOOM = 0.9f;
|
||||||
|
protected ScaleGestureDetector mScaleDetector;
|
||||||
|
protected GestureDetector mGestureDetector;
|
||||||
|
protected int mTouchSlop;
|
||||||
|
protected float mCurrentScaleFactor;
|
||||||
|
protected float mScaleFactor;
|
||||||
|
protected int mDoubleTapDirection;
|
||||||
|
protected OnGestureListener mGestureListener;
|
||||||
|
protected OnScaleGestureListener mScaleListener;
|
||||||
|
protected boolean mDoubleTapToZoomEnabled = true;
|
||||||
|
protected boolean mScaleEnabled = true;
|
||||||
|
protected boolean mScrollEnabled = true;
|
||||||
|
|
||||||
|
private OnImageViewTouchDoubleTapListener doubleTapListener;
|
||||||
|
|
||||||
|
public interface OnScaleChangedListener {
|
||||||
|
public void onScaleChanged(float scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected OnScaleChangedListener mScaleChangedListener;
|
||||||
|
|
||||||
|
public ImageViewTouch( Context context, AttributeSet attrs ) {
|
||||||
|
super( context, attrs );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
|
||||||
|
mGestureListener = getGestureListener();
|
||||||
|
mScaleListener = getScaleListener();
|
||||||
|
|
||||||
|
mScaleDetector = new ScaleGestureDetector( getContext(), mScaleListener );
|
||||||
|
mGestureDetector = new GestureDetector( getContext(), mGestureListener, null, true );
|
||||||
|
|
||||||
|
mCurrentScaleFactor = 1f;
|
||||||
|
mDoubleTapDirection = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDoubleTapListener( OnImageViewTouchDoubleTapListener doubleTapListener ){
|
||||||
|
this.doubleTapListener = doubleTapListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDoubleTapToZoomEnabled( boolean value ) {
|
||||||
|
mDoubleTapToZoomEnabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScaleEnabled( boolean value ) {
|
||||||
|
mScaleEnabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScrollEnabled( boolean value ) {
|
||||||
|
mScrollEnabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getDoubleTapEnabled() {
|
||||||
|
return mDoubleTapToZoomEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected OnGestureListener getGestureListener() {
|
||||||
|
return new GestureListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected OnScaleGestureListener getScaleListener() {
|
||||||
|
return new ScaleListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBitmapChanged( Drawable drawable ) {
|
||||||
|
super.onBitmapChanged( drawable );
|
||||||
|
|
||||||
|
float v[] = new float[9];
|
||||||
|
mSuppMatrix.getValues( v );
|
||||||
|
mCurrentScaleFactor = v[Matrix.MSCALE_X];
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent( MotionEvent event ) {
|
||||||
|
mScaleDetector.onTouchEvent( event );
|
||||||
|
if ( !mScaleDetector.isInProgress() ) mGestureDetector.onTouchEvent( event );
|
||||||
|
int action = event.getAction();
|
||||||
|
switch ( action & MotionEvent.ACTION_MASK ) {
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
if ( getScale() < 1f ) {
|
||||||
|
zoomTo( 1f, 50 );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onZoom( float scale ) {
|
||||||
|
super.onZoom( scale );
|
||||||
|
if ( !mScaleDetector.isInProgress() ) mCurrentScaleFactor = scale;
|
||||||
|
|
||||||
|
if (mScaleChangedListener != null) {
|
||||||
|
mScaleChangedListener.onScaleChanged(mCurrentScaleFactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float onDoubleTapPost( float scale, float maxZoom ) {
|
||||||
|
if ( mDoubleTapDirection == 1 ) {
|
||||||
|
if (mCurrentScaleFactor - 1.0f < 0.01) { //( scale + ( mScaleFactor * 2 ) ) <= maxZoom
|
||||||
|
|
||||||
|
float scaleFactor = mScaleFactor;
|
||||||
|
|
||||||
|
RectF bitmapRect = getBitmapRect();
|
||||||
|
|
||||||
|
float w = bitmapRect.right - bitmapRect.left;
|
||||||
|
float h = bitmapRect.bottom - bitmapRect.top;
|
||||||
|
|
||||||
|
if (w < getWidth()) {
|
||||||
|
scaleFactor = (float)getWidth() / w - scale;
|
||||||
|
} else if (h < getHeight()) {
|
||||||
|
scaleFactor = (float)getHeight() / h - scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scale + scaleFactor;
|
||||||
|
} else {
|
||||||
|
mDoubleTapDirection = -1;
|
||||||
|
return maxZoom;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mDoubleTapDirection = 1;
|
||||||
|
return 1f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(int direction) {
|
||||||
|
RectF bitmapRect = getBitmapRect();
|
||||||
|
updateRect(bitmapRect, mScrollRect);
|
||||||
|
Rect imageViewRect = new Rect();
|
||||||
|
getGlobalVisibleRect(imageViewRect);
|
||||||
|
|
||||||
|
if (bitmapRect.right >= imageViewRect.right) {
|
||||||
|
if (direction < 0) {
|
||||||
|
return Math.abs(bitmapRect.right - imageViewRect.right) > SCROLL_DELTA_THRESHOLD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double bitmapScrollRectDelta = Math.abs(bitmapRect.left - mScrollRect.left);
|
||||||
|
return bitmapScrollRectDelta > SCROLL_DELTA_THRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GestureListener extends GestureDetector.SimpleOnGestureListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onDoubleTap( MotionEvent e ) {
|
||||||
|
Log.i( LOG_TAG, "onDoubleTap. double tap enabled? " + mDoubleTapToZoomEnabled);
|
||||||
|
if (mDoubleTapToZoomEnabled) {
|
||||||
|
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 void onLongPress( MotionEvent e ) {
|
||||||
|
if ( isLongClickable() ) {
|
||||||
|
if ( !mScaleDetector.isInProgress() ) {
|
||||||
|
setPressed( true );
|
||||||
|
performLongClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onScroll( MotionEvent e1, MotionEvent e2, float distanceX, float distanceY ) {
|
||||||
|
if ( !mScrollEnabled ) return false;
|
||||||
|
|
||||||
|
if ( e1 == null || e2 == null ) return false;
|
||||||
|
if ( e1.getPointerCount() > 1 || e2.getPointerCount() > 1 ) return false;
|
||||||
|
if ( mScaleDetector.isInProgress() ) return false;
|
||||||
|
if ( getScale() == 1f ) return false;
|
||||||
|
scrollBy( -distanceX, -distanceY );
|
||||||
|
invalidate();
|
||||||
|
return super.onScroll( e1, e2, distanceX, distanceY );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onFling( MotionEvent e1, MotionEvent e2, float velocityX, float velocityY ) {
|
||||||
|
if ( !mScrollEnabled ) return false;
|
||||||
|
|
||||||
|
if ( e1.getPointerCount() > 1 || e2.getPointerCount() > 1 ) return false;
|
||||||
|
if ( mScaleDetector.isInProgress() ) return false;
|
||||||
|
|
||||||
|
float diffX = e2.getX() - e1.getX();
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
|
public boolean onScale( ScaleGestureDetector detector ) {
|
||||||
|
float span = detector.getCurrentSpan() - detector.getPreviousSpan();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnImageViewTouchDoubleTapListener {
|
||||||
|
void onDoubleTap();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnScaleChangedListener(OnScaleChangedListener listener) {
|
||||||
|
mScaleChangedListener = listener;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,509 @@
|
|||||||
|
package it.sephiroth.android.library.imagezoom;
|
||||||
|
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base View to manage image zoom/scrool/pinch operations
|
||||||
|
*
|
||||||
|
* @author alessandro
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ImageViewTouchBase extends ImageView implements IDisposable {
|
||||||
|
|
||||||
|
public interface OnBitmapChangedListener {
|
||||||
|
|
||||||
|
void onBitmapChanged( Drawable drawable );
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
protected boolean mFitToWidth = false;
|
||||||
|
final protected float MAX_ZOOM = 3.0f;
|
||||||
|
|
||||||
|
protected RectF mBitmapRect = new RectF();
|
||||||
|
protected RectF mCenterRect = new RectF();
|
||||||
|
protected RectF mScrollRect = new RectF();
|
||||||
|
|
||||||
|
private OnBitmapChangedListener mListener;
|
||||||
|
|
||||||
|
public ImageViewTouchBase( Context context ) {
|
||||||
|
super( context );
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageViewTouchBase( Context context, AttributeSet attrs ) {
|
||||||
|
super( context, attrs );
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnBitmapChangedListener( OnBitmapChangedListener listener ) {
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void init() {
|
||||||
|
setScaleType( ImageView.ScaleType.MATRIX );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
setImageBitmap( null, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFitToScreen( boolean value ) {
|
||||||
|
if ( value != mFitToScreen ) {
|
||||||
|
mFitToScreen = value;
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFitToWidth( boolean value ) {
|
||||||
|
if ( value != mFitToWidth ) {
|
||||||
|
mFitToWidth = value;
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout( boolean changed, int left, int top, int right, int bottom ) {
|
||||||
|
super.onLayout( changed, left, top, right, bottom );
|
||||||
|
mThisWidth = right - left;
|
||||||
|
mThisHeight = bottom - top;
|
||||||
|
Runnable r = mOnLayoutRunnable;
|
||||||
|
if ( r != null ) {
|
||||||
|
mOnLayoutRunnable = null;
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
if ( getDrawable() != null ) {
|
||||||
|
if ( mFitToScreen )
|
||||||
|
getProperBaseMatrix2( getDrawable(), mBaseMatrix );
|
||||||
|
else
|
||||||
|
getProperBaseMatrix( getDrawable(), mBaseMatrix );
|
||||||
|
setImageMatrix( getImageViewMatrix() );
|
||||||
|
|
||||||
|
if (mFitToWidth) zoomToWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setImageBitmap( Bitmap bm ) {
|
||||||
|
setImageBitmap( bm, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setImageResource( int resId ) {
|
||||||
|
setImageDrawable( getContext().getResources().getDrawable( resId ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, 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, Matrix matrix, 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( 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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
if (mFitToWidth) zoomToWidth();
|
||||||
|
|
||||||
|
} 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 onBitmapChanged( final Drawable bitmap ) {
|
||||||
|
if ( mListener != null ) {
|
||||||
|
mListener.onBitmapChanged( bitmap );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float maxZoom() {
|
||||||
|
final Drawable drawable = getDrawable();
|
||||||
|
|
||||||
|
if ( drawable == null ) {
|
||||||
|
return 1F;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fw = (float) drawable.getIntrinsicWidth() / (float) mThisWidth;
|
||||||
|
float fh = (float) drawable.getIntrinsicHeight() / (float) mThisHeight;
|
||||||
|
float max = Math.max( fw, fh ) * 4;
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMaxZoom() {
|
||||||
|
return mMaxZoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matrix getImageViewMatrix() {
|
||||||
|
mDisplayMatrix.set( mBaseMatrix );
|
||||||
|
mDisplayMatrix.postConcat( mSuppMatrix );
|
||||||
|
return mDisplayMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the base matrix so that the image is centered and scaled properly.
|
||||||
|
*
|
||||||
|
* @param bitmap
|
||||||
|
* @param matrix
|
||||||
|
*/
|
||||||
|
protected void getProperBaseMatrix( Drawable drawable, Matrix matrix ) {
|
||||||
|
float viewWidth = getWidth();
|
||||||
|
float viewHeight = getHeight();
|
||||||
|
float w = drawable.getIntrinsicWidth();
|
||||||
|
float h = drawable.getIntrinsicHeight();
|
||||||
|
matrix.reset();
|
||||||
|
|
||||||
|
if ( w > viewWidth || h > viewHeight ) {
|
||||||
|
float widthScale = Math.min( viewWidth / w, 2.0f );
|
||||||
|
float heightScale = Math.min( viewHeight / h, 2.0f );
|
||||||
|
float scale = Math.min( widthScale, heightScale );
|
||||||
|
matrix.postScale( scale, scale );
|
||||||
|
float tw = ( viewWidth - w * scale ) / 2.0f;
|
||||||
|
float th = ( viewHeight - h * scale ) / 2.0f;
|
||||||
|
matrix.postTranslate( tw, th );
|
||||||
|
} else {
|
||||||
|
float tw = ( viewWidth - w ) / 2.0f;
|
||||||
|
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( Drawable bitmap, Matrix matrix ) {
|
||||||
|
float viewWidth = getWidth();
|
||||||
|
float viewHeight = getHeight();
|
||||||
|
float w = bitmap.getIntrinsicWidth();
|
||||||
|
float h = bitmap.getIntrinsicHeight();
|
||||||
|
matrix.reset();
|
||||||
|
float widthScale = Math.min( viewWidth / w, MAX_ZOOM );
|
||||||
|
float heightScale = Math.min( viewHeight / h, MAX_ZOOM );
|
||||||
|
float scale = Math.min( widthScale, heightScale );
|
||||||
|
matrix.postScale( scale, scale );
|
||||||
|
matrix.postTranslate( ( viewWidth - w * scale ) / 2.0f, ( viewHeight - h * scale ) / 2.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float getValue( Matrix matrix, int whichValue ) {
|
||||||
|
matrix.getValues( mMatrixValues );
|
||||||
|
return mMatrixValues[whichValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RectF getBitmapRect() {
|
||||||
|
final Drawable drawable = getDrawable();
|
||||||
|
|
||||||
|
if ( drawable == null ) return null;
|
||||||
|
Matrix m = getImageViewMatrix();
|
||||||
|
mBitmapRect.set( 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight() );
|
||||||
|
m.mapRect( mBitmapRect );
|
||||||
|
return mBitmapRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float getScale( Matrix matrix ) {
|
||||||
|
return getValue( matrix, Matrix.MSCALE_X );
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getRotation() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getScale() {
|
||||||
|
return getScale( mSuppMatrix );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void center( boolean horizontal, boolean vertical ) {
|
||||||
|
// Log.i(LOG_TAG, "center");
|
||||||
|
final Drawable drawable = getDrawable();
|
||||||
|
|
||||||
|
if ( drawable == null ) return;
|
||||||
|
RectF rect = getCenter( horizontal, vertical );
|
||||||
|
if ( rect.left != 0 || rect.top != 0 ) {
|
||||||
|
postTranslate( rect.left, rect.top );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RectF getCenter( boolean horizontal, boolean vertical ) {
|
||||||
|
final Drawable drawable = getDrawable();
|
||||||
|
|
||||||
|
if ( drawable == null ) return new RectF( 0, 0, 0, 0 );
|
||||||
|
|
||||||
|
RectF rect = getBitmapRect();
|
||||||
|
float height = rect.height();
|
||||||
|
float width = rect.width();
|
||||||
|
float deltaX = 0, deltaY = 0;
|
||||||
|
if ( vertical ) {
|
||||||
|
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 ) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void postTranslate( float deltaX, float deltaY ) {
|
||||||
|
mSuppMatrix.postTranslate( deltaX, deltaY );
|
||||||
|
setImageMatrix( getImageViewMatrix() );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void postScale( float scale, float centerX, float centerY ) {
|
||||||
|
mSuppMatrix.postScale( scale, scale, centerX, centerY );
|
||||||
|
setImageMatrix( getImageViewMatrix() );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void zoomTo( float scale ) {
|
||||||
|
float cx = getWidth() / 2F;
|
||||||
|
float cy = getHeight() / 2F;
|
||||||
|
zoomTo( scale, cx, cy );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void zoomTo( float scale, float durationMs ) {
|
||||||
|
float cx = getWidth() / 2F;
|
||||||
|
float cy = getHeight() / 2F;
|
||||||
|
zoomTo( scale, cx, cy, durationMs );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void zoomTo( float scale, float centerX, float centerY ) {
|
||||||
|
if ( scale > mMaxZoom ) scale = mMaxZoom;
|
||||||
|
float oldScale = getScale();
|
||||||
|
float deltaScale = scale / oldScale;
|
||||||
|
postScale( deltaScale, centerX, centerY );
|
||||||
|
onZoom( getScale() );
|
||||||
|
center( true, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onZoom( float scale ) {}
|
||||||
|
|
||||||
|
public void scrollBy( float x, float y ) {
|
||||||
|
panBy( x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void panBy( double dx, double dy ) {
|
||||||
|
RectF rect = getBitmapRect();
|
||||||
|
mScrollRect.set( (float) dx, (float) dy, 0, 0 );
|
||||||
|
updateRect( rect, mScrollRect );
|
||||||
|
postTranslate( mScrollRect.left, mScrollRect.top );
|
||||||
|
center( true, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateRect( RectF bitmapRect, RectF scrollRect ) {
|
||||||
|
float width = getWidth();
|
||||||
|
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 scrollBy( float distanceX, 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() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
double currentMs = Math.min( durationMs, now - startTime );
|
||||||
|
double x = mEasing.easeOut( currentMs, 0, dx, durationMs );
|
||||||
|
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 {
|
||||||
|
RectF centerRect = getCenter( true, true );
|
||||||
|
if ( centerRect.left != 0 || centerRect.top != 0 ) scrollBy( centerRect.left, centerRect.top );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void zoomTo( 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() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
float currentMs = Math.min( durationMs, now - startTime );
|
||||||
|
float target = oldScale + ( incrementPerMs * currentMs );
|
||||||
|
zoomTo( target, centerX, centerY );
|
||||||
|
if ( currentMs < durationMs ) {
|
||||||
|
mHandler.post( this );
|
||||||
|
} else {
|
||||||
|
// if ( getScale() < 1f ) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void zoomToWidth() {
|
||||||
|
RectF bitmapRect = getBitmapRect();
|
||||||
|
|
||||||
|
float w = bitmapRect.right - bitmapRect.left;
|
||||||
|
|
||||||
|
if (w < getWidth()) {
|
||||||
|
float scale = (float)getWidth() / w;
|
||||||
|
|
||||||
|
zoomTo(scale, 0f, 0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package it.sephiroth.android.library.imagezoom.easing;
|
||||||
|
|
||||||
|
public class Cubic implements Easing {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double easeOut( double time, double start, double end, double duration ) {
|
||||||
|
return end * ( ( time = time / duration - 1.0 ) * time * time + 1.0 ) + start;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double easeIn( double time, double start, double end, double duration ) {
|
||||||
|
return end * ( time /= duration ) * time * time + start;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double easeInOut( double time, double start, double end, 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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package it.sephiroth.android.library.imagezoom.easing;
|
||||||
|
|
||||||
|
public interface Easing {
|
||||||
|
|
||||||
|
double easeOut( double time, double start, double end, double duration );
|
||||||
|
|
||||||
|
double easeIn( double time, double start, double end, double duration );
|
||||||
|
|
||||||
|
double easeInOut( double time, double start, double end, double duration );
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package it.sephiroth.android.library.imagezoom.graphics;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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( Bitmap b ) {
|
||||||
|
mBitmap = b;
|
||||||
|
mPaint = new Paint();
|
||||||
|
mPaint.setDither( true );
|
||||||
|
mPaint.setFilterBitmap( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
public FastBitmapDrawable( Resources res, InputStream is ){
|
||||||
|
this(BitmapFactory.decodeStream(is));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw( Canvas canvas ) {
|
||||||
|
canvas.drawBitmap( mBitmap, 0.0f, 0.0f, mPaint );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacity() {
|
||||||
|
return PixelFormat.TRANSLUCENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlpha( int alpha ) {
|
||||||
|
mPaint.setAlpha( alpha );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColorFilter( ColorFilter cf ) {
|
||||||
|
mPaint.setColorFilter( cf );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIntrinsicWidth() {
|
||||||
|
return mBitmap.getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIntrinsicHeight() {
|
||||||
|
return mBitmap.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumWidth() {
|
||||||
|
return mBitmap.getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumHeight() {
|
||||||
|
return mBitmap.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAntiAlias( boolean value ){
|
||||||
|
mPaint.setAntiAlias( value );
|
||||||
|
invalidateSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bitmap getBitmap() {
|
||||||
|
return mBitmap;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package it.sephiroth.android.library.imagezoom.graphics;
|
||||||
|
|
||||||
|
import it.sephiroth.android.library.imagezoom.ImageViewTouchBase;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base interface used in the {@link ImageViewTouchBase} view
|
||||||
|
* @author alessandro
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface IBitmapDrawable {
|
||||||
|
|
||||||
|
Bitmap getBitmap();
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package it.sephiroth.android.library.imagezoom.utils;
|
||||||
|
|
||||||
|
public interface IDisposable {
|
||||||
|
|
||||||
|
void dispose();
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package org.fox.ttrss;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import it.sephiroth.android.library.imagezoom.ImageViewTouch;
|
||||||
|
|
||||||
|
public class ArticleImagesPager extends android.support.v4.view.ViewPager {
|
||||||
|
public ArticleImagesPager(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
|
||||||
|
if (v instanceof ImageViewTouch) {
|
||||||
|
ImageViewTouch ivt = (ImageViewTouch) v;
|
||||||
|
try {
|
||||||
|
return ivt.canScroll(dx);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// bad image, etc
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return super.canScroll(v, checkV, dx, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||||
|
return super.onInterceptTouchEvent(event);
|
||||||
|
}
|
||||||
|
}
|
@ -11,16 +11,18 @@ import android.os.Bundle;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.v4.view.PagerAdapter;
|
import android.support.v4.view.PagerAdapter;
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.support.v7.app.ActionBar;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
|
import android.view.GestureDetector;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@ -38,7 +40,9 @@ import org.jsoup.select.Elements;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ArticleImagesPagerActivity extends CommonActivity {
|
import it.sephiroth.android.library.imagezoom.ImageViewTouch;
|
||||||
|
|
||||||
|
public class ArticleImagesPagerActivity extends CommonActivity implements GestureDetector.OnDoubleTapListener {
|
||||||
private final String TAG = this.getClass().getSimpleName();
|
private final String TAG = this.getClass().getSimpleName();
|
||||||
|
|
||||||
private ArrayList<String> m_urls;
|
private ArrayList<String> m_urls;
|
||||||
@ -46,6 +50,30 @@ public class ArticleImagesPagerActivity extends CommonActivity {
|
|||||||
private String m_title;
|
private String m_title;
|
||||||
private ArticleImagesPagerAdapter m_adapter;
|
private ArticleImagesPagerAdapter m_adapter;
|
||||||
private String m_content;
|
private String m_content;
|
||||||
|
private GestureDetector m_detector;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
|
||||||
|
ActionBar bar = getSupportActionBar();
|
||||||
|
|
||||||
|
if (bar.isShowing()) {
|
||||||
|
bar.hide();
|
||||||
|
} else {
|
||||||
|
bar.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onDoubleTap(MotionEvent motionEvent) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onDoubleTapEvent(MotionEvent motionEvent) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private class ArticleImagesPagerAdapter extends PagerAdapter {
|
private class ArticleImagesPagerAdapter extends PagerAdapter {
|
||||||
private List<String> m_urls;
|
private List<String> m_urls;
|
||||||
@ -80,8 +108,21 @@ public class ArticleImagesPagerActivity extends CommonActivity {
|
|||||||
|
|
||||||
View view = inflater.inflate(R.layout.article_images_image, null);
|
View view = inflater.inflate(R.layout.article_images_image, null);
|
||||||
|
|
||||||
ImageView imgView = (ImageView) view.findViewById(R.id.flavor_image);
|
m_detector = new GestureDetector(ArticleImagesPagerActivity.this, new GestureDetector.SimpleOnGestureListener());
|
||||||
//imgView.setOnClickListener(this);
|
|
||||||
|
m_detector.setOnDoubleTapListener(ArticleImagesPagerActivity.this);
|
||||||
|
|
||||||
|
ImageViewTouch imgView = (ImageViewTouch) view.findViewById(R.id.flavor_image);
|
||||||
|
|
||||||
|
imgView.setFitToScreen(true);
|
||||||
|
imgView.setFitToWidth(true);
|
||||||
|
|
||||||
|
imgView.setOnTouchListener(new View.OnTouchListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View view, MotionEvent event) {
|
||||||
|
return m_detector.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
registerForContextMenu(imgView);
|
registerForContextMenu(imgView);
|
||||||
|
|
||||||
@ -196,8 +237,6 @@ public class ArticleImagesPagerActivity extends CommonActivity {
|
|||||||
|
|
||||||
setContentView(R.layout.article_images_pager);
|
setContentView(R.layout.article_images_pager);
|
||||||
|
|
||||||
setStatusBarTint();
|
|
||||||
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
@ -241,10 +280,6 @@ public class ArticleImagesPagerActivity extends CommonActivity {
|
|||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
/* if (isCompatMode() && m_prefs.getBoolean("dim_status_bar", false)) {
|
|
||||||
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
|
|
||||||
} */
|
|
||||||
|
|
||||||
if (m_prefs.getBoolean("full_screen_mode", false)) {
|
if (m_prefs.getBoolean("full_screen_mode", false)) {
|
||||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
@ -52,10 +52,6 @@ public class ArticlePager extends Fragment {
|
|||||||
ArticleFragment af = new ArticleFragment();
|
ArticleFragment af = new ArticleFragment();
|
||||||
af.initialize(article);
|
af.initialize(article);
|
||||||
|
|
||||||
if (m_prefs.getBoolean("dim_status_bar", false) && getView() != null && !m_activity.isCompatMode()) {
|
|
||||||
getView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return af;
|
return af;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -281,10 +277,6 @@ public class ArticlePager extends Fragment {
|
|||||||
|
|
||||||
m_activity.invalidateOptionsMenu();
|
m_activity.invalidateOptionsMenu();
|
||||||
|
|
||||||
if (!m_activity.isCompatMode() && m_prefs.getBoolean("dim_status_bar", false)) {
|
|
||||||
getView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_prefs.getBoolean("full_screen_mode", false)) {
|
if (m_prefs.getBoolean("full_screen_mode", false)) {
|
||||||
m_activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
m_activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
@ -9,14 +9,10 @@ import android.os.Bundle;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.v7.app.ActionBarActivity;
|
import android.support.v7.app.ActionBarActivity;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.readystatesoftware.systembartint.SystemBarTintManager;
|
|
||||||
|
|
||||||
import org.fox.ttrss.util.DatabaseHelper;
|
import org.fox.ttrss.util.DatabaseHelper;
|
||||||
|
|
||||||
public class CommonActivity extends ActionBarActivity {
|
public class CommonActivity extends ActionBarActivity {
|
||||||
@ -155,24 +151,6 @@ public class CommonActivity extends ActionBarActivity {
|
|||||||
return Math.round((float)dp * density);
|
return Math.round((float)dp * density);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStatusBarTint() {
|
|
||||||
if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.KITKAT &&
|
|
||||||
!m_prefs.getBoolean("full_screen_mode", false)) {
|
|
||||||
|
|
||||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
|
|
||||||
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
|
||||||
|
|
||||||
SystemBarTintManager tintManager = new SystemBarTintManager(this);
|
|
||||||
// enable status bar tint
|
|
||||||
tintManager.setStatusBarTintEnabled(true);
|
|
||||||
|
|
||||||
TypedValue tv = new TypedValue();
|
|
||||||
getTheme().resolveAttribute(R.attr.statusBarHintColor, tv, true);
|
|
||||||
|
|
||||||
tintManager.setStatusBarTintColor(tv.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle out) {
|
public void onSaveInstanceState(Bundle out) {
|
||||||
super.onSaveInstanceState(out);
|
super.onSaveInstanceState(out);
|
||||||
|
@ -55,7 +55,6 @@ public class FeedsActivity extends OnlineActivity implements HeadlinesEventListe
|
|||||||
|
|
||||||
setContentView(R.layout.headlines);
|
setContentView(R.layout.headlines);
|
||||||
|
|
||||||
setStatusBarTint();
|
|
||||||
setSmallScreen(findViewById(R.id.sw600dp_anchor) == null);
|
setSmallScreen(findViewById(R.id.sw600dp_anchor) == null);
|
||||||
|
|
||||||
GlobalState.getInstance().load(savedInstanceState);
|
GlobalState.getInstance().load(savedInstanceState);
|
||||||
|
@ -7,11 +7,8 @@ import android.os.Bundle;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
import android.support.v4.widget.DrawerLayout;
|
|
||||||
import android.support.v7.app.ActionBarDrawerToggle;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import org.fox.ttrss.types.Article;
|
import org.fox.ttrss.types.Article;
|
||||||
import org.fox.ttrss.types.ArticleList;
|
import org.fox.ttrss.types.ArticleList;
|
||||||
@ -37,7 +34,6 @@ public class HeadlinesActivity extends OnlineActivity implements HeadlinesEventL
|
|||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
getSupportActionBar().setHomeButtonEnabled(true);
|
getSupportActionBar().setHomeButtonEnabled(true);
|
||||||
|
|
||||||
setStatusBarTint();
|
|
||||||
setSmallScreen(findViewById(R.id.sw600dp_anchor) == null);
|
setSmallScreen(findViewById(R.id.sw600dp_anchor) == null);
|
||||||
|
|
||||||
GlobalState.getInstance().load(savedInstanceState);
|
GlobalState.getInstance().load(savedInstanceState);
|
||||||
|
@ -165,8 +165,6 @@ public class OnlineActivity extends CommonActivity {
|
|||||||
|
|
||||||
setContentView(R.layout.login);
|
setContentView(R.layout.login);
|
||||||
|
|
||||||
setStatusBarTint();
|
|
||||||
|
|
||||||
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
|
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
|
||||||
.diskCache(
|
.diskCache(
|
||||||
new LimitedAgeDiscCache(new File(StorageUtils.getCacheDirectory(getApplicationContext()), "article-images"),
|
new LimitedAgeDiscCache(new File(StorageUtils.getCacheDirectory(getApplicationContext()), "article-images"),
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
package org.fox.ttrss.offline;
|
package org.fox.ttrss.offline;
|
||||||
|
|
||||||
import org.fox.ttrss.R;
|
|
||||||
|
|
||||||
import com.viewpagerindicator.UnderlinePageIndicator;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
@ -20,6 +16,10 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
|
import com.viewpagerindicator.UnderlinePageIndicator;
|
||||||
|
|
||||||
|
import org.fox.ttrss.R;
|
||||||
|
|
||||||
public class OfflineArticlePager extends Fragment {
|
public class OfflineArticlePager extends Fragment {
|
||||||
private final String TAG = this.getClass().getSimpleName();
|
private final String TAG = this.getClass().getSimpleName();
|
||||||
|
|
||||||
@ -119,10 +119,6 @@ public class OfflineArticlePager extends Fragment {
|
|||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
if (!m_activity.isCompatMode() && m_prefs.getBoolean("dim_status_bar", false)) {
|
|
||||||
getView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_prefs.getBoolean("full_screen_mode", false)) {
|
if (m_prefs.getBoolean("full_screen_mode", false)) {
|
||||||
m_activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
m_activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
@ -46,7 +46,6 @@ public class OfflineFeedsActivity extends OfflineActivity implements OfflineHead
|
|||||||
|
|
||||||
setContentView(R.layout.headlines);
|
setContentView(R.layout.headlines);
|
||||||
|
|
||||||
setStatusBarTint();
|
|
||||||
setSmallScreen(findViewById(R.id.sw600dp_anchor) == null);
|
setSmallScreen(findViewById(R.id.sw600dp_anchor) == null);
|
||||||
|
|
||||||
GlobalState.getInstance().load(savedInstanceState);
|
GlobalState.getInstance().load(savedInstanceState);
|
||||||
|
@ -67,7 +67,6 @@ public class OfflineHeadlinesActivity extends OfflineActivity implements Offline
|
|||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
getSupportActionBar().setHomeButtonEnabled(true);
|
getSupportActionBar().setHomeButtonEnabled(true);
|
||||||
|
|
||||||
setStatusBarTint();
|
|
||||||
setSmallScreen(findViewById(R.id.sw600dp_anchor) == null);
|
setSmallScreen(findViewById(R.id.sw600dp_anchor) == null);
|
||||||
|
|
||||||
/* if (isPortrait() || m_prefs.getBoolean("headlines_hide_sidebar", false)) {
|
/* if (isPortrait() || m_prefs.getBoolean("headlines_hide_sidebar", false)) {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:id="@+id/flavor_image_progress" />
|
android:id="@+id/flavor_image_progress" />
|
||||||
|
|
||||||
<org.fox.ttrss.util.EnlargingImageView
|
<it.sephiroth.android.library.imagezoom.ImageViewTouch
|
||||||
android:id="@+id/flavor_image"
|
android:id="@+id/flavor_image"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -10,12 +10,11 @@
|
|||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"> */
|
android:paddingBottom="@dimen/activity_vertical_margin"> */
|
||||||
|
|
||||||
<android.support.v4.view.ViewPager
|
<org.fox.ttrss.ArticleImagesPager
|
||||||
android:id="@+id/article_images_pager"
|
android:id="@+id/article_images_pager"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent" >
|
android:layout_height="fill_parent" />
|
||||||
</android.support.v4.view.ViewPager>
|
|
||||||
|
|
||||||
<com.viewpagerindicator.UnderlinePageIndicator
|
<com.viewpagerindicator.UnderlinePageIndicator
|
||||||
android:id="@+id/article_images_indicator"
|
android:id="@+id/article_images_indicator"
|
||||||
|
@ -143,11 +143,6 @@
|
|||||||
android:key="use_volume_keys"
|
android:key="use_volume_keys"
|
||||||
android:summary="@string/use_volume_keys_long"
|
android:summary="@string/use_volume_keys_long"
|
||||||
android:title="@string/use_volume_keys" />
|
android:title="@string/use_volume_keys" />
|
||||||
<CheckBoxPreference
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:key="dim_status_bar"
|
|
||||||
android:summary="@string/prefs_dim_status_bar_long"
|
|
||||||
android:title="@string/prefs_dim_status_bar" />
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="full_screen_mode"
|
android:key="full_screen_mode"
|
||||||
|
Loading…
Reference in New Issue
Block a user