mirror of https://github.com/kurisufriend/Clover
Now using Ion to load the images, with a custom file cache. This allows downloads bigger than the available ram, and a progressbar. The subsampling-scale-image-view allows huge images to be displayed, even when there's not a lot of ram.captchafix
parent
0db08433c7
commit
f8878f8fbb
@ -0,0 +1,55 @@ |
||||
/* |
||||
Copyright 2014 David Morrissey |
||||
|
||||
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 com.davemorrissey.labs.subscaleview; |
||||
|
||||
import android.graphics.PointF; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* Wraps the scale, center and orientation of a displayed image for easy restoration on screen rotate. |
||||
*/ |
||||
public class ImageViewState implements Serializable { |
||||
|
||||
private float scale; |
||||
|
||||
private float centerX; |
||||
|
||||
private float centerY; |
||||
|
||||
private int orientation; |
||||
|
||||
public ImageViewState(float scale, PointF center, int orientation) { |
||||
this.scale = scale; |
||||
this.centerX = center.x; |
||||
this.centerY = center.y; |
||||
this.orientation = orientation; |
||||
} |
||||
|
||||
public float getScale() { |
||||
return scale; |
||||
} |
||||
|
||||
public PointF getCenter() { |
||||
return new PointF(centerX, centerY); |
||||
} |
||||
|
||||
public int getOrientation() { |
||||
return orientation; |
||||
} |
||||
|
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,59 +0,0 @@ |
||||
/* |
||||
* Clover - 4chan browser https://github.com/Floens/Clover/
|
||||
* Copyright (C) 2014 Floens |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
package org.floens.chan.core.net; |
||||
|
||||
import android.content.Context; |
||||
|
||||
import com.android.volley.NetworkResponse; |
||||
import com.android.volley.ParseError; |
||||
import com.android.volley.Request; |
||||
import com.android.volley.Response; |
||||
import com.android.volley.Response.ErrorListener; |
||||
import com.android.volley.Response.Listener; |
||||
import com.android.volley.toolbox.HttpHeaderParser; |
||||
|
||||
import org.floens.chan.ui.view.GIFView; |
||||
|
||||
public class GIFRequest extends Request<GIFView> { |
||||
protected final Listener<GIFView> listener; |
||||
private final Context context; |
||||
|
||||
public GIFRequest(String url, Listener<GIFView> listener, ErrorListener errorListener, Context context) { |
||||
super(Method.GET, url, errorListener); |
||||
|
||||
this.listener = listener; |
||||
this.context = context; |
||||
} |
||||
|
||||
@Override |
||||
protected void deliverResponse(GIFView response) { |
||||
listener.onResponse(response); |
||||
} |
||||
|
||||
@Override |
||||
protected Response<GIFView> parseNetworkResponse(NetworkResponse response) { |
||||
GIFView gifView = new GIFView(context); |
||||
boolean success = gifView.setData(response.data); |
||||
|
||||
if (success) { |
||||
return Response.success(gifView, HttpHeaderParser.parseCacheHeaders(response)); |
||||
} else { |
||||
return Response.error(new ParseError()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,86 @@ |
||||
package org.floens.chan.utils; |
||||
|
||||
import android.util.Log; |
||||
|
||||
import java.io.File; |
||||
|
||||
public class FileCache { |
||||
private static final String TAG = "FileCache"; |
||||
|
||||
private final File directory; |
||||
private final long maxSize; |
||||
|
||||
private long size; |
||||
|
||||
public FileCache(File directory, long maxSize) { |
||||
this.directory = directory; |
||||
this.maxSize = maxSize; |
||||
|
||||
if (!directory.exists() && !directory.mkdirs()) { |
||||
Logger.e(TAG, "Unable to create file cache dir " + directory.getAbsolutePath()); |
||||
} |
||||
|
||||
calculateSize(); |
||||
} |
||||
|
||||
public File get(String key) { |
||||
return new File(directory, Integer.toString(key.hashCode())); |
||||
} |
||||
|
||||
public void put(File file) { |
||||
size += file.length(); |
||||
|
||||
trim(); |
||||
} |
||||
|
||||
public boolean delete(File file) { |
||||
size -= file.length(); |
||||
|
||||
return file.delete(); |
||||
} |
||||
|
||||
private void trim() { |
||||
int tries = 0; |
||||
while (size > maxSize && tries++ < 10) { |
||||
File[] files = directory.listFiles(); |
||||
if (files == null) { |
||||
break; |
||||
} |
||||
long age = Long.MAX_VALUE; |
||||
long last; |
||||
File oldest = null; |
||||
for (File file : files) { |
||||
last = file.lastModified(); |
||||
if (last < age && last != 0L) { |
||||
age = last; |
||||
oldest = file; |
||||
} |
||||
} |
||||
|
||||
if (oldest == null) { |
||||
Log.e(TAG, "No files to trim"); |
||||
break; |
||||
} else { |
||||
Log.d(TAG, "Deleting " + oldest.getAbsolutePath()); |
||||
if (!delete(oldest)) { |
||||
Log.e(TAG, "Cannot delete cache file"); |
||||
calculateSize(); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
calculateSize(); |
||||
} |
||||
} |
||||
|
||||
private void calculateSize() { |
||||
size = 0; |
||||
|
||||
File[] files = directory.listFiles(); |
||||
if (files != null) { |
||||
for (File file : files) { |
||||
size += file.length(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,60 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.os.Build; |
||||
import android.os.Build.VERSION; |
||||
import android.os.Build.VERSION_CODES; |
||||
import android.view.MotionEvent; |
||||
import android.view.View; |
||||
|
||||
public class Compat { |
||||
|
||||
private static final int SIXTY_FPS_INTERVAL = 1000 / 60; |
||||
|
||||
public static void postOnAnimation(View view, Runnable runnable) { |
||||
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { |
||||
postOnAnimationJellyBean(view, runnable); |
||||
} else { |
||||
view.postDelayed(runnable, SIXTY_FPS_INTERVAL); |
||||
} |
||||
} |
||||
|
||||
@TargetApi(16) |
||||
private static void postOnAnimationJellyBean(View view, Runnable runnable) { |
||||
view.postOnAnimation(runnable); |
||||
} |
||||
|
||||
public static int getPointerIndex(int action) { |
||||
if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) |
||||
return getPointerIndexHoneyComb(action); |
||||
else |
||||
return getPointerIndexEclair(action); |
||||
} |
||||
|
||||
@SuppressWarnings("deprecation") |
||||
@TargetApi(Build.VERSION_CODES.ECLAIR) |
||||
private static int getPointerIndexEclair(int action) { |
||||
return (action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT; |
||||
} |
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB) |
||||
private static int getPointerIndexHoneyComb(int action) { |
||||
return (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; |
||||
} |
||||
|
||||
} |
@ -1,98 +0,0 @@ |
||||
package uk.co.senab.photoview; |
||||
|
||||
import android.graphics.RectF; |
||||
import android.view.GestureDetector; |
||||
import android.view.MotionEvent; |
||||
import android.widget.ImageView; |
||||
|
||||
/** |
||||
* Provided default implementation of GestureDetector.OnDoubleTapListener, to be overriden with custom behavior, if needed |
||||
* <p> </p> |
||||
* To be used via {@link uk.co.senab.photoview.PhotoViewAttacher#setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener)} |
||||
*/ |
||||
public class DefaultOnDoubleTapListener implements GestureDetector.OnDoubleTapListener { |
||||
|
||||
private PhotoViewAttacher photoViewAttacher; |
||||
|
||||
/** |
||||
* Default constructor |
||||
* |
||||
* @param photoViewAttacher PhotoViewAttacher to bind to |
||||
*/ |
||||
public DefaultOnDoubleTapListener(PhotoViewAttacher photoViewAttacher) { |
||||
setPhotoViewAttacher(photoViewAttacher); |
||||
} |
||||
|
||||
/** |
||||
* Allows to change PhotoViewAttacher within range of single instance |
||||
* |
||||
* @param newPhotoViewAttacher PhotoViewAttacher to bind to |
||||
*/ |
||||
public void setPhotoViewAttacher(PhotoViewAttacher newPhotoViewAttacher) { |
||||
this.photoViewAttacher = newPhotoViewAttacher; |
||||
} |
||||
|
||||
@Override |
||||
public boolean onSingleTapConfirmed(MotionEvent e) { |
||||
if (this.photoViewAttacher == null) |
||||
return false; |
||||
|
||||
ImageView imageView = photoViewAttacher.getImageView(); |
||||
|
||||
if (null != photoViewAttacher.getOnPhotoTapListener()) { |
||||
final RectF displayRect = photoViewAttacher.getDisplayRect(); |
||||
|
||||
if (null != displayRect) { |
||||
final float x = e.getX(), y = e.getY(); |
||||
|
||||
// Check to see if the user tapped on the photo
|
||||
if (displayRect.contains(x, y)) { |
||||
|
||||
float xResult = (x - displayRect.left) |
||||
/ displayRect.width(); |
||||
float yResult = (y - displayRect.top) |
||||
/ displayRect.height(); |
||||
|
||||
photoViewAttacher.getOnPhotoTapListener().onPhotoTap(imageView, xResult, yResult); |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
if (null != photoViewAttacher.getOnViewTapListener()) { |
||||
photoViewAttacher.getOnViewTapListener().onViewTap(imageView, e.getX(), e.getY()); |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public boolean onDoubleTap(MotionEvent ev) { |
||||
if (photoViewAttacher == null) |
||||
return false; |
||||
|
||||
try { |
||||
float scale = photoViewAttacher.getScale(); |
||||
float x = ev.getX(); |
||||
float y = ev.getY(); |
||||
|
||||
if (scale < photoViewAttacher.getMediumScale()) { |
||||
photoViewAttacher.setScale(photoViewAttacher.getMediumScale(), x, y, true); |
||||
} else if (scale >= photoViewAttacher.getMediumScale() && scale < photoViewAttacher.getMaximumScale()) { |
||||
photoViewAttacher.setScale(photoViewAttacher.getMaximumScale(), x, y, true); |
||||
} else { |
||||
photoViewAttacher.setScale(photoViewAttacher.getMinimumScale(), x, y, true); |
||||
} |
||||
} catch (ArrayIndexOutOfBoundsException e) { |
||||
// Can sometimes happen when getX() and getY() is called
|
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public boolean onDoubleTapEvent(MotionEvent e) { |
||||
// Wait for the confirmed onDoubleTap() instead
|
||||
return false; |
||||
} |
||||
|
||||
} |
@ -1,260 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview; |
||||
|
||||
import android.graphics.Bitmap; |
||||
import android.graphics.Matrix; |
||||
import android.graphics.RectF; |
||||
import android.view.View; |
||||
import android.widget.ImageView; |
||||
|
||||
|
||||
public interface IPhotoView { |
||||
/** |
||||
* Returns true if the PhotoView is set to allow zooming of Photos. |
||||
* |
||||
* @return true if the PhotoView allows zooming. |
||||
*/ |
||||
boolean canZoom(); |
||||
|
||||
/** |
||||
* Gets the Display Rectangle of the currently displayed Drawable. The |
||||
* Rectangle is relative to this View and includes all scaling and |
||||
* translations. |
||||
* |
||||
* @return - RectF of Displayed Drawable |
||||
*/ |
||||
RectF getDisplayRect(); |
||||
|
||||
/** |
||||
* Sets the Display Matrix of the currently displayed Drawable. The |
||||
* Rectangle is considered relative to this View and includes all scaling and |
||||
* translations. |
||||
* |
||||
* @return - true if rectangle was applied successfully |
||||
*/ |
||||
boolean setDisplayMatrix(Matrix finalMatrix); |
||||
|
||||
/** |
||||
* Gets the Display Matrix of the currently displayed Drawable. The |
||||
* Rectangle is considered relative to this View and includes all scaling and |
||||
* translations. |
||||
* |
||||
* @return - true if rectangle was applied successfully |
||||
*/ |
||||
Matrix getDisplayMatrix(); |
||||
|
||||
/** |
||||
* Use {@link #getMinimumScale()} instead, this will be removed in future release |
||||
* |
||||
* @return The current minimum scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
@Deprecated |
||||
float getMinScale(); |
||||
|
||||
/** |
||||
* @return The current minimum scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
float getMinimumScale(); |
||||
|
||||
/** |
||||
* Use {@link #getMediumScale()} instead, this will be removed in future release |
||||
* |
||||
* @return The current middle scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
@Deprecated |
||||
float getMidScale(); |
||||
|
||||
/** |
||||
* @return The current medium scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
float getMediumScale(); |
||||
|
||||
/** |
||||
* Use {@link #getMaximumScale()} instead, this will be removed in future release |
||||
* |
||||
* @return The current maximum scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
@Deprecated |
||||
float getMaxScale(); |
||||
|
||||
/** |
||||
* @return The current maximum scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
float getMaximumScale(); |
||||
|
||||
/** |
||||
* Returns the current scale value |
||||
* |
||||
* @return float - current scale value |
||||
*/ |
||||
float getScale(); |
||||
|
||||
/** |
||||
* Return the current scale type in use by the ImageView. |
||||
*/ |
||||
ImageView.ScaleType getScaleType(); |
||||
|
||||
/** |
||||
* Whether to allow the ImageView's parent to intercept the touch event when the photo is scroll to it's horizontal edge. |
||||
*/ |
||||
void setAllowParentInterceptOnEdge(boolean allow); |
||||
|
||||
/** |
||||
* Use {@link #setMinimumScale(float minimumScale)} instead, this will be removed in future release |
||||
* <p/> |
||||
* Sets the minimum scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
@Deprecated |
||||
void setMinScale(float minScale); |
||||
|
||||
/** |
||||
* Sets the minimum scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
void setMinimumScale(float minimumScale); |
||||
|
||||
/** |
||||
* Use {@link #setMediumScale(float mediumScale)} instead, this will be removed in future release |
||||
* <p/> |
||||
* Sets the middle scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
@Deprecated |
||||
void setMidScale(float midScale); |
||||
|
||||
/* |
||||
* Sets the medium scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
void setMediumScale(float mediumScale); |
||||
|
||||
/** |
||||
* Use {@link #setMaximumScale(float maximumScale)} instead, this will be removed in future release |
||||
* <p/> |
||||
* Sets the maximum scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
@Deprecated |
||||
void setMaxScale(float maxScale); |
||||
|
||||
/** |
||||
* Sets the maximum scale level. What this value represents depends on the current {@link android.widget.ImageView.ScaleType}. |
||||
*/ |
||||
void setMaximumScale(float maximumScale); |
||||
|
||||
/** |
||||
* Register a callback to be invoked when the Photo displayed by this view is long-pressed. |
||||
* |
||||
* @param listener - Listener to be registered. |
||||
*/ |
||||
void setOnLongClickListener(View.OnLongClickListener listener); |
||||
|
||||
/** |
||||
* Register a callback to be invoked when the Matrix has changed for this |
||||
* View. An example would be the user panning or scaling the Photo. |
||||
* |
||||
* @param listener - Listener to be registered. |
||||
*/ |
||||
void setOnMatrixChangeListener(PhotoViewAttacher.OnMatrixChangedListener listener); |
||||
|
||||
/** |
||||
* Register a callback to be invoked when the Photo displayed by this View |
||||
* is tapped with a single tap. |
||||
* |
||||
* @param listener - Listener to be registered. |
||||
*/ |
||||
void setOnPhotoTapListener(PhotoViewAttacher.OnPhotoTapListener listener); |
||||
|
||||
/** |
||||
* Returns a listener to be invoked when the Photo displayed by this View |
||||
* is tapped with a single tap. |
||||
* |
||||
* @return PhotoViewAttacher.OnPhotoTapListener currently set, may be null |
||||
*/ |
||||
PhotoViewAttacher.OnPhotoTapListener getOnPhotoTapListener(); |
||||
|
||||
/** |
||||
* Register a callback to be invoked when the View is tapped with a single |
||||
* tap. |
||||
* |
||||
* @param listener - Listener to be registered. |
||||
*/ |
||||
void setOnViewTapListener(PhotoViewAttacher.OnViewTapListener listener); |
||||
|
||||
/** |
||||
* Returns a callback listener to be invoked when the View is tapped with a single |
||||
* tap. |
||||
* |
||||
* @return PhotoViewAttacher.OnViewTapListener currently set, may be null |
||||
*/ |
||||
PhotoViewAttacher.OnViewTapListener getOnViewTapListener(); |
||||
|
||||
/** |
||||
* Changes the current scale to the specified value. |
||||
* |
||||
* @param scale - Value to scale to |
||||
*/ |
||||
void setScale(float scale); |
||||
|
||||
/** |
||||
* Changes the current scale to the specified value. |
||||
* |
||||
* @param scale - Value to scale to |
||||
* @param animate - Whether to animate the scale |
||||
*/ |
||||
void setScale(float scale, boolean animate); |
||||
|
||||
/** |
||||
* Changes the current scale to the specified value, around the given focal point. |
||||
* |
||||
* @param scale - Value to scale to |
||||
* @param focalX - X Focus Point |
||||
* @param focalY - Y Focus Point |
||||
* @param animate - Whether to animate the scale |
||||
*/ |
||||
void setScale(float scale, float focalX, float focalY, boolean animate); |
||||
|
||||
/** |
||||
* Controls how the image should be resized or moved to match the size of |
||||
* the ImageView. Any scaling or panning will happen within the confines of |
||||
* this {@link android.widget.ImageView.ScaleType}. |
||||
* |
||||
* @param scaleType - The desired scaling mode. |
||||
*/ |
||||
void setScaleType(ImageView.ScaleType scaleType); |
||||
|
||||
/** |
||||
* Allows you to enable/disable the zoom functionality on the ImageView. |
||||
* When disable the ImageView reverts to using the FIT_CENTER matrix. |
||||
* |
||||
* @param zoomable - Whether the zoom functionality is enabled. |
||||
*/ |
||||
void setZoomable(boolean zoomable); |
||||
|
||||
/** |
||||
* Enables rotation via PhotoView internal functions. |
||||
* Name is chosen so it won't collide with View.setRotation(float) in API since 11 |
||||
* |
||||
* @param rotationDegree - Degree to rotate PhotoView by, should be in range 0 to 360 |
||||
*/ |
||||
void setPhotoViewRotation(float rotationDegree); |
||||
|
||||
/** |
||||
* Extracts currently visible area to Bitmap object, if there is no image loaded yet or the |
||||
* ImageView is already destroyed, returns {@code null} |
||||
* |
||||
* @return currently visible area as bitmap or null |
||||
*/ |
||||
public Bitmap getVisibleRectangleBitmap(); |
||||
|
||||
} |
@ -1,256 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview; |
||||
|
||||
import uk.co.senab.photoview.PhotoViewAttacher.OnMatrixChangedListener; |
||||
import uk.co.senab.photoview.PhotoViewAttacher.OnPhotoTapListener; |
||||
import uk.co.senab.photoview.PhotoViewAttacher.OnViewTapListener; |
||||
import android.content.Context; |
||||
import android.graphics.Bitmap; |
||||
import android.graphics.Matrix; |
||||
import android.graphics.RectF; |
||||
import android.graphics.drawable.Drawable; |
||||
import android.net.Uri; |
||||
import android.util.AttributeSet; |
||||
import android.widget.ImageView; |
||||
|
||||
public class PhotoView extends ImageView implements IPhotoView { |
||||
|
||||
private final PhotoViewAttacher mAttacher; |
||||
|
||||
private ScaleType mPendingScaleType; |
||||
|
||||
public PhotoView(Context context) { |
||||
this(context, null); |
||||
} |
||||
|
||||
public PhotoView(Context context, AttributeSet attr) { |
||||
this(context, attr, 0); |
||||
} |
||||
|
||||
public PhotoView(Context context, AttributeSet attr, int defStyle) { |
||||
super(context, attr, defStyle); |
||||
super.setScaleType(ScaleType.MATRIX); |
||||
mAttacher = new PhotoViewAttacher(this); |
||||
|
||||
if (null != mPendingScaleType) { |
||||
setScaleType(mPendingScaleType); |
||||
mPendingScaleType = null; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void setPhotoViewRotation(float rotationDegree) { |
||||
mAttacher.setPhotoViewRotation(rotationDegree); |
||||
} |
||||
|
||||
@Override |
||||
public boolean canZoom() { |
||||
return mAttacher.canZoom(); |
||||
} |
||||
|
||||
@Override |
||||
public RectF getDisplayRect() { |
||||
return mAttacher.getDisplayRect(); |
||||
} |
||||
|
||||
@Override |
||||
public Matrix getDisplayMatrix() { |
||||
return mAttacher.getDrawMatrix(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean setDisplayMatrix(Matrix finalRectangle) { |
||||
return mAttacher.setDisplayMatrix(finalRectangle); |
||||
} |
||||
|
||||
@Override |
||||
@Deprecated |
||||
public float getMinScale() { |
||||
return getMinimumScale(); |
||||
} |
||||
|
||||
@Override |
||||
public float getMinimumScale() { |
||||
return mAttacher.getMinimumScale(); |
||||
} |
||||
|
||||
@Override |
||||
@Deprecated |
||||
public float getMidScale() { |
||||
return getMediumScale(); |
||||
} |
||||
|
||||
@Override |
||||
public float getMediumScale() { |
||||
return mAttacher.getMediumScale(); |
||||
} |
||||
|
||||
@Override |
||||
@Deprecated |
||||
public float getMaxScale() { |
||||
return getMaximumScale(); |
||||
} |
||||
|
||||
@Override |
||||
public float getMaximumScale() { |
||||
return mAttacher.getMaximumScale(); |
||||
} |
||||
|
||||
@Override |
||||
public float getScale() { |
||||
return mAttacher.getScale(); |
||||
} |
||||
|
||||
@Override |
||||
public ScaleType getScaleType() { |
||||
return mAttacher.getScaleType(); |
||||
} |
||||
|
||||
@Override |
||||
public void setAllowParentInterceptOnEdge(boolean allow) { |
||||
mAttacher.setAllowParentInterceptOnEdge(allow); |
||||
} |
||||
|
||||
@Override |
||||
@Deprecated |
||||
public void setMinScale(float minScale) { |
||||
setMinimumScale(minScale); |
||||
} |
||||
|
||||
@Override |
||||
public void setMinimumScale(float minimumScale) { |
||||
mAttacher.setMinimumScale(minimumScale); |
||||
} |
||||
|
||||
@Override |
||||
@Deprecated |
||||
public void setMidScale(float midScale) { |
||||
setMediumScale(midScale); |
||||
} |
||||
|
||||
@Override |
||||
public void setMediumScale(float mediumScale) { |
||||
mAttacher.setMediumScale(mediumScale); |
||||
} |
||||
|
||||
@Override |
||||
@Deprecated |
||||
public void setMaxScale(float maxScale) { |
||||
setMaximumScale(maxScale); |
||||
} |
||||
|
||||
@Override |
||||
public void setMaximumScale(float maximumScale) { |
||||
mAttacher.setMaximumScale(maximumScale); |
||||
} |
||||
|
||||
@Override |
||||
// setImageBitmap calls through to this method
|
||||
public void setImageDrawable(Drawable drawable) { |
||||
super.setImageDrawable(drawable); |
||||
if (null != mAttacher) { |
||||
mAttacher.update(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void setImageResource(int resId) { |
||||
super.setImageResource(resId); |
||||
if (null != mAttacher) { |
||||
mAttacher.update(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void setImageURI(Uri uri) { |
||||
super.setImageURI(uri); |
||||
if (null != mAttacher) { |
||||
mAttacher.update(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void setOnMatrixChangeListener(OnMatrixChangedListener listener) { |
||||
mAttacher.setOnMatrixChangeListener(listener); |
||||
} |
||||
|
||||
@Override |
||||
public void setOnLongClickListener(OnLongClickListener l) { |
||||
mAttacher.setOnLongClickListener(l); |
||||
} |
||||
|
||||
@Override |
||||
public void setOnPhotoTapListener(OnPhotoTapListener listener) { |
||||
mAttacher.setOnPhotoTapListener(listener); |
||||
} |
||||
|
||||
@Override |
||||
public OnPhotoTapListener getOnPhotoTapListener() { |
||||
return mAttacher.getOnPhotoTapListener(); |
||||
} |
||||
|
||||
@Override |
||||
public void setOnViewTapListener(OnViewTapListener listener) { |
||||
mAttacher.setOnViewTapListener(listener); |
||||
} |
||||
|
||||
@Override |
||||
public OnViewTapListener getOnViewTapListener() { |
||||
return mAttacher.getOnViewTapListener(); |
||||
} |
||||
|
||||
@Override |
||||
public void setScale(float scale) { |
||||
mAttacher.setScale(scale); |
||||
} |
||||
|
||||
@Override |
||||
public void setScale(float scale, boolean animate) { |
||||
mAttacher.setScale(scale, animate); |
||||
} |
||||
|
||||
@Override |
||||
public void setScale(float scale, float focalX, float focalY, boolean animate) { |
||||
mAttacher.setScale(scale, focalX, focalY, animate); |
||||
} |
||||
|
||||
@Override |
||||
public void setScaleType(ScaleType scaleType) { |
||||
if (null != mAttacher) { |
||||
mAttacher.setScaleType(scaleType); |
||||
} else { |
||||
mPendingScaleType = scaleType; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void setZoomable(boolean zoomable) { |
||||
mAttacher.setZoomable(zoomable); |
||||
} |
||||
|
||||
@Override |
||||
public Bitmap getVisibleRectangleBitmap() { |
||||
return mAttacher.getVisibleRectangleBitmap(); |
||||
} |
||||
|
||||
@Override |
||||
protected void onDetachedFromWindow() { |
||||
mAttacher.cleanup(); |
||||
super.onDetachedFromWindow(); |
||||
} |
||||
|
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,143 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.gestures; |
||||
|
||||
import android.content.Context; |
||||
import android.util.Log; |
||||
import android.view.MotionEvent; |
||||
import android.view.VelocityTracker; |
||||
import android.view.ViewConfiguration; |
||||
|
||||
public class CupcakeGestureDetector implements GestureDetector { |
||||
|
||||
protected OnGestureListener mListener; |
||||
private static final String LOG_TAG = "CupcakeGestureDetector"; |
||||
float mLastTouchX; |
||||
float mLastTouchY; |
||||
final float mTouchSlop; |
||||
final float mMinimumVelocity; |
||||
|
||||
@Override |
||||
public void setOnGestureListener(OnGestureListener listener) { |
||||
this.mListener = listener; |
||||
} |
||||
|
||||
public CupcakeGestureDetector(Context context) { |
||||
final ViewConfiguration configuration = ViewConfiguration |
||||
.get(context); |
||||
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); |
||||
mTouchSlop = configuration.getScaledTouchSlop(); |
||||
} |
||||
|
||||
private VelocityTracker mVelocityTracker; |
||||
private boolean mIsDragging; |
||||
|
||||
float getActiveX(MotionEvent ev) { |
||||
return ev.getX(); |
||||
} |
||||
|
||||
float getActiveY(MotionEvent ev) { |
||||
return ev.getY(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isScaling() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public boolean onTouchEvent(MotionEvent ev) { |
||||
switch (ev.getAction()) { |
||||
case MotionEvent.ACTION_DOWN: { |
||||
mVelocityTracker = VelocityTracker.obtain(); |
||||
if (null != mVelocityTracker) { |
||||
mVelocityTracker.addMovement(ev); |
||||
} else { |
||||
Log.i(LOG_TAG, "Velocity tracker is null"); |
||||
} |
||||
|
||||
mLastTouchX = getActiveX(ev); |
||||
mLastTouchY = getActiveY(ev); |
||||
mIsDragging = false; |
||||
break; |
||||
} |
||||
|
||||
case MotionEvent.ACTION_MOVE: { |
||||
final float x = getActiveX(ev); |
||||
final float y = getActiveY(ev); |
||||
final float dx = x - mLastTouchX, dy = y - mLastTouchY; |
||||
|
||||
if (!mIsDragging) { |
||||
// Use Pythagoras to see if drag length is larger than
|
||||
// touch slop
|
||||
mIsDragging = Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop; |
||||
} |
||||
|
||||
if (mIsDragging) { |
||||
mListener.onDrag(dx, dy); |
||||
mLastTouchX = x; |
||||
mLastTouchY = y; |
||||
|
||||
if (null != mVelocityTracker) { |
||||
mVelocityTracker.addMovement(ev); |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
|
||||
case MotionEvent.ACTION_CANCEL: { |
||||
// Recycle Velocity Tracker
|
||||
if (null != mVelocityTracker) { |
||||
mVelocityTracker.recycle(); |
||||
mVelocityTracker = null; |
||||
} |
||||
break; |
||||
} |
||||
|
||||
case MotionEvent.ACTION_UP: { |
||||
if (mIsDragging) { |
||||
if (null != mVelocityTracker) { |
||||
mLastTouchX = getActiveX(ev); |
||||
mLastTouchY = getActiveY(ev); |
||||
|
||||
// Compute velocity within the last 1000ms
|
||||
mVelocityTracker.addMovement(ev); |
||||
mVelocityTracker.computeCurrentVelocity(1000); |
||||
|
||||
final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker |
||||
.getYVelocity(); |
||||
|
||||
// If the velocity is greater than minVelocity, call
|
||||
// listener
|
||||
if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) { |
||||
mListener.onFling(mLastTouchX, mLastTouchY, -vX, |
||||
-vY); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Recycle Velocity Tracker
|
||||
if (null != mVelocityTracker) { |
||||
mVelocityTracker.recycle(); |
||||
mVelocityTracker = null; |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
} |
@ -1,85 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.gestures; |
||||
|
||||
import uk.co.senab.photoview.Compat; |
||||
import android.annotation.TargetApi; |
||||
import android.content.Context; |
||||
import android.view.MotionEvent; |
||||
|
||||
@TargetApi(5) |
||||
public class EclairGestureDetector extends CupcakeGestureDetector { |
||||
|
||||
private static final int INVALID_POINTER_ID = -1; |
||||
private int mActivePointerId = INVALID_POINTER_ID; |
||||
private int mActivePointerIndex = 0; |
||||
|
||||
public EclairGestureDetector(Context context) { |
||||
super(context); |
||||
} |
||||
|
||||
@Override |
||||
float getActiveX(MotionEvent ev) { |
||||
try { |
||||
return ev.getX(mActivePointerIndex); |
||||
} catch (Exception e) { |
||||
return ev.getX(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
float getActiveY(MotionEvent ev) { |
||||
try { |
||||
return ev.getY(mActivePointerIndex); |
||||
} catch (Exception e) { |
||||
return ev.getY(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public boolean onTouchEvent(MotionEvent ev) { |
||||
final int action = ev.getAction(); |
||||
switch (action & MotionEvent.ACTION_MASK) { |
||||
case MotionEvent.ACTION_DOWN: |
||||
mActivePointerId = ev.getPointerId(0); |
||||
break; |
||||
case MotionEvent.ACTION_CANCEL: |
||||
case MotionEvent.ACTION_UP: |
||||
mActivePointerId = INVALID_POINTER_ID; |
||||
break; |
||||
case MotionEvent.ACTION_POINTER_UP: |
||||
// Ignore deprecation, ACTION_POINTER_ID_MASK and
|
||||
// ACTION_POINTER_ID_SHIFT has same value and are deprecated
|
||||
// You can have either deprecation or lint target api warning
|
||||
final int pointerIndex = Compat.getPointerIndex(ev.getAction()); |
||||
final int pointerId = ev.getPointerId(pointerIndex); |
||||
if (pointerId == mActivePointerId) { |
||||
// This was our active pointer going up. Choose a new
|
||||
// active pointer and adjust accordingly.
|
||||
final int newPointerIndex = pointerIndex == 0 ? 1 : 0; |
||||
mActivePointerId = ev.getPointerId(newPointerIndex); |
||||
mLastTouchX = ev.getX(newPointerIndex); |
||||
mLastTouchY = ev.getY(newPointerIndex); |
||||
} |
||||
break; |
||||
} |
||||
|
||||
mActivePointerIndex = ev |
||||
.findPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId |
||||
: 0); |
||||
return super.onTouchEvent(ev); |
||||
} |
||||
} |
@ -1,63 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.gestures; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.content.Context; |
||||
import android.view.MotionEvent; |
||||
import android.view.ScaleGestureDetector; |
||||
|
||||
@TargetApi(8) |
||||
public class FroyoGestureDetector extends EclairGestureDetector { |
||||
|
||||
protected final ScaleGestureDetector mDetector; |
||||
|
||||
public FroyoGestureDetector(Context context) { |
||||
super(context); |
||||
ScaleGestureDetector.OnScaleGestureListener mScaleListener = new ScaleGestureDetector.OnScaleGestureListener() { |
||||
|
||||
@Override |
||||
public boolean onScale(ScaleGestureDetector detector) { |
||||
mListener.onScale(detector.getScaleFactor(), |
||||
detector.getFocusX(), detector.getFocusY()); |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public boolean onScaleBegin(ScaleGestureDetector detector) { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void onScaleEnd(ScaleGestureDetector detector) { |
||||
// NO-OP
|
||||
} |
||||
}; |
||||
mDetector = new ScaleGestureDetector(context, mScaleListener); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isScaling() { |
||||
return mDetector.isInProgress(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean onTouchEvent(MotionEvent ev) { |
||||
mDetector.onTouchEvent(ev); |
||||
return super.onTouchEvent(ev); |
||||
} |
||||
|
||||
} |
@ -1,28 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.gestures; |
||||
|
||||
import android.view.MotionEvent; |
||||
|
||||
public interface GestureDetector { |
||||
|
||||
public boolean onTouchEvent(MotionEvent ev); |
||||
|
||||
public boolean isScaling(); |
||||
|
||||
public void setOnGestureListener(OnGestureListener listener); |
||||
|
||||
} |
@ -1,27 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.gestures; |
||||
|
||||
public interface OnGestureListener { |
||||
|
||||
public void onDrag(float dx, float dy); |
||||
|
||||
public void onFling(float startX, float startY, float velocityX, |
||||
float velocityY); |
||||
|
||||
public void onScale(float scaleFactor, float focusX, float focusY); |
||||
|
||||
} |
@ -1,42 +0,0 @@ |
||||
package uk.co.senab.photoview.gestures; |
||||
|
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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. |
||||
*******************************************************************************/ |
||||
|
||||
import android.content.Context; |
||||
import android.os.Build; |
||||
|
||||
public final class VersionedGestureDetector { |
||||
|
||||
public static GestureDetector newInstance(Context context, |
||||
OnGestureListener listener) { |
||||
final int sdkVersion = Build.VERSION.SDK_INT; |
||||
GestureDetector detector; |
||||
|
||||
if (sdkVersion < Build.VERSION_CODES.ECLAIR) { |
||||
detector = new CupcakeGestureDetector(context); |
||||
} else if (sdkVersion < Build.VERSION_CODES.FROYO) { |
||||
detector = new EclairGestureDetector(context); |
||||
} else { |
||||
detector = new FroyoGestureDetector(context); |
||||
} |
||||
|
||||
detector.setOnGestureListener(listener); |
||||
|
||||
return detector; |
||||
} |
||||
|
||||
} |
@ -1,35 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.log; |
||||
|
||||
import android.util.Log; |
||||
|
||||
/** |
||||
* class that holds the {@link Logger} for this library, defaults to {@link LoggerDefault} to send logs to android {@link Log} |
||||
*/ |
||||
public final class LogManager { |
||||
|
||||
private static Logger logger = new LoggerDefault(); |
||||
|
||||
public static void setLogger(Logger newLogger) { |
||||
logger = newLogger; |
||||
} |
||||
|
||||
public static Logger getLogger() { |
||||
return logger; |
||||
} |
||||
|
||||
} |
@ -1,116 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.log; |
||||
|
||||
/** |
||||
* interface for a logger class to replace the static calls to {@link android.util.Log} |
||||
*/ |
||||
public interface Logger { |
||||
/** |
||||
* Send a {@link android.util.Log#VERBOSE} log message. |
||||
* |
||||
* @param tag Used to identify the source of a log message. It usually identifies |
||||
* the class or activity where the log call occurs. |
||||
* @param msg The message you would like logged. |
||||
*/ |
||||
int v(String tag, String msg); |
||||
|
||||
/** |
||||
* Send a {@link android.util.Log#VERBOSE} log message and log the exception. |
||||
* |
||||
* @param tag Used to identify the source of a log message. It usually identifies |
||||
* the class or activity where the log call occurs. |
||||
* @param msg The message you would like logged. |
||||
* @param tr An exception to log |
||||
*/ |
||||
int v(String tag, String msg, Throwable tr); |
||||
|
||||
/** |
||||
* Send a {@link android.util.Log#DEBUG} log message. |
||||
* |
||||
* @param tag Used to identify the source of a log message. It usually identifies |
||||
* the class or activity where the log call occurs. |
||||
* @param msg The message you would like logged. |
||||
*/ |
||||
int d(String tag, String msg); |
||||
|
||||
/** |
||||
* Send a {@link android.util.Log#DEBUG} log message and log the exception. |
||||
* |
||||
* @param tag Used to identify the source of a log message. It usually identifies |
||||
* the class or activity where the log call occurs. |
||||
* @param msg The message you would like logged. |
||||
* @param tr An exception to log |
||||
*/ |
||||
int d(String tag, String msg, Throwable tr); |
||||
|
||||
/** |
||||
* Send an {@link android.util.Log#INFO} log message. |
||||
* |
||||
* @param tag Used to identify the source of a log message. It usually identifies |
||||
* the class or activity where the log call occurs. |
||||
* @param msg The message you would like logged. |
||||
*/ |
||||
int i(String tag, String msg); |
||||
|
||||
/** |
||||
* Send a {@link android.util.Log#INFO} log message and log the exception. |
||||
* |
||||
* @param tag Used to identify the source of a log message. It usually identifies |
||||
* the class or activity where the log call occurs. |
||||
* @param msg The message you would like logged. |
||||
* @param tr An exception to log |
||||
*/ |
||||
int i(String tag, String msg, Throwable tr); |
||||
|
||||
/** |
||||
* Send a {@link android.util.Log#WARN} log message. |
||||
* |
||||
* @param tag Used to identify the source of a log message. It usually identifies |
||||
* the class or activity where the log call occurs. |
||||
* @param msg The message you would like logged. |
||||
*/ |
||||
int w(String tag, String msg); |
||||
|
||||
/** |
||||
* Send a {@link android.util.Log#WARN} log message and log the exception. |
||||
* |
||||
* @param tag Used to identify the source of a log message. It usually identifies |
||||
* the class or activity where the log call occurs. |
||||
* @param msg The message you would like logged. |
||||
* @param tr An exception to log |
||||
*/ |
||||
int w(String tag, String msg, Throwable tr); |
||||
|
||||
/** |
||||
* Send an {@link android.util.Log#ERROR} log message. |
||||
* |
||||
* @param tag Used to identify the source of a log message. It usually identifies |
||||
* the class or activity where the log call occurs. |
||||
* @param msg The message you would like logged. |
||||
*/ |
||||
int e(String tag, String msg); |
||||
|
||||
/** |
||||
* Send a {@link android.util.Log#ERROR} log message and log the exception. |
||||
* |
||||
* @param tag Used to identify the source of a log message. It usually identifies |
||||
* the class or activity where the log call occurs. |
||||
* @param msg The message you would like logged. |
||||
* @param tr An exception to log |
||||
*/ |
||||
int e(String tag, String msg, Throwable tr); |
||||
} |
@ -1,76 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.log; |
||||
|
||||
import android.util.Log; |
||||
|
||||
/** |
||||
* Helper class to redirect {@link LogManager#logger} to {@link Log} |
||||
*/ |
||||
public class LoggerDefault implements Logger { |
||||
|
||||
@Override |
||||
public int v(String tag, String msg) { |
||||
return Log.v(tag, msg); |
||||
} |
||||
|
||||
@Override |
||||
public int v(String tag, String msg, Throwable tr) { |
||||
return Log.v(tag, msg, tr); |
||||
} |
||||
|
||||
@Override |
||||
public int d(String tag, String msg) { |
||||
return Log.d(tag, msg); |
||||
} |
||||
|
||||
@Override |
||||
public int d(String tag, String msg, Throwable tr) { |
||||
return Log.d(tag, msg, tr); |
||||
} |
||||
|
||||
@Override |
||||
public int i(String tag, String msg) { |
||||
return Log.i(tag, msg); |
||||
} |
||||
|
||||
@Override |
||||
public int i(String tag, String msg, Throwable tr) { |
||||
return Log.i(tag, msg, tr); |
||||
} |
||||
|
||||
@Override |
||||
public int w(String tag, String msg) { |
||||
return Log.w(tag, msg); |
||||
} |
||||
|
||||
@Override |
||||
public int w(String tag, String msg, Throwable tr) { |
||||
return Log.w(tag, msg, tr); |
||||
} |
||||
|
||||
@Override |
||||
public int e(String tag, String msg) { |
||||
return Log.e(tag, msg); |
||||
} |
||||
|
||||
@Override |
||||
public int e(String tag, String msg, Throwable tr) { |
||||
return Log.e(tag, msg, tr); |
||||
} |
||||
|
||||
|
||||
} |
@ -1,68 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.scrollerproxy; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.content.Context; |
||||
import android.widget.OverScroller; |
||||
|
||||
@TargetApi(9) |
||||
public class GingerScroller extends ScrollerProxy { |
||||
|
||||
protected final OverScroller mScroller; |
||||
private boolean mFirstScroll = false; |
||||
|
||||
public GingerScroller(Context context) { |
||||
mScroller = new OverScroller(context); |
||||
} |
||||
|
||||
@Override |
||||
public boolean computeScrollOffset() { |
||||
// Workaround for first scroll returning 0 for the direction of the edge it hits.
|
||||
// Simply recompute values.
|
||||
if (mFirstScroll) { |
||||
mScroller.computeScrollOffset(); |
||||
mFirstScroll = false; |
||||
} |
||||
return mScroller.computeScrollOffset(); |
||||
} |
||||
|
||||
@Override |
||||
public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY, |
||||
int overX, int overY) { |
||||
mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY, overX, overY); |
||||
} |
||||
|
||||
@Override |
||||
public void forceFinished(boolean finished) { |
||||
mScroller.forceFinished(finished); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isFinished() { |
||||
return mScroller.isFinished(); |
||||
} |
||||
|
||||
@Override |
||||
public int getCurrX() { |
||||
return mScroller.getCurrX(); |
||||
} |
||||
|
||||
@Override |
||||
public int getCurrY() { |
||||
return mScroller.getCurrY(); |
||||
} |
||||
} |
@ -1,33 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.scrollerproxy; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.content.Context; |
||||
|
||||
@TargetApi(14) |
||||
public class IcsScroller extends GingerScroller { |
||||
|
||||
public IcsScroller(Context context) { |
||||
super(context); |
||||
} |
||||
|
||||
@Override |
||||
public boolean computeScrollOffset() { |
||||
return mScroller.computeScrollOffset(); |
||||
} |
||||
|
||||
} |
@ -1,58 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.scrollerproxy; |
||||
|
||||
import android.content.Context; |
||||
import android.widget.Scroller; |
||||
|
||||
public class PreGingerScroller extends ScrollerProxy { |
||||
|
||||
private final Scroller mScroller; |
||||
|
||||
public PreGingerScroller(Context context) { |
||||
mScroller = new Scroller(context); |
||||
} |
||||
|
||||
@Override |
||||
public boolean computeScrollOffset() { |
||||
return mScroller.computeScrollOffset(); |
||||
} |
||||
|
||||
@Override |
||||
public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY, |
||||
int overX, int overY) { |
||||
mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY); |
||||
} |
||||
|
||||
@Override |
||||
public void forceFinished(boolean finished) { |
||||
mScroller.forceFinished(finished); |
||||
} |
||||
|
||||
public boolean isFinished() { |
||||
return mScroller.isFinished(); |
||||
} |
||||
|
||||
@Override |
||||
public int getCurrX() { |
||||
return mScroller.getCurrX(); |
||||
} |
||||
|
||||
@Override |
||||
public int getCurrY() { |
||||
return mScroller.getCurrY(); |
||||
} |
||||
} |
@ -1,48 +0,0 @@ |
||||
/******************************************************************************* |
||||
* Copyright 2011, 2012 Chris Banes. |
||||
* |
||||
* 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 uk.co.senab.photoview.scrollerproxy; |
||||
|
||||
import android.content.Context; |
||||
import android.os.Build.VERSION; |
||||
import android.os.Build.VERSION_CODES; |
||||
|
||||
public abstract class ScrollerProxy { |
||||
|
||||
public static ScrollerProxy getScroller(Context context) { |
||||
if (VERSION.SDK_INT < VERSION_CODES.GINGERBREAD) { |
||||
return new PreGingerScroller(context); |
||||
} else if (VERSION.SDK_INT < VERSION_CODES.ICE_CREAM_SANDWICH) { |
||||
return new GingerScroller(context); |
||||
} else { |
||||
return new IcsScroller(context); |
||||
} |
||||
} |
||||
|
||||
public abstract boolean computeScrollOffset(); |
||||
|
||||
public abstract void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, |
||||
int maxY, int overX, int overY); |
||||
|
||||
public abstract void forceFinished(boolean finished); |
||||
|
||||
public abstract boolean isFinished(); |
||||
|
||||
public abstract int getCurrX(); |
||||
|
||||
public abstract int getCurrY(); |
||||
|
||||
|
||||
} |
After Width: | Height: | Size: 873 B |
After Width: | Height: | Size: 561 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1,24 @@ |
||||
<?xml version="1.0" encoding="utf-8"?><!-- |
||||
Clover - 4chan browser https://github.com/Floens/Clover/ |
||||
Copyright (C) 2014 Floens |
||||
|
||||
This program is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
--> |
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item android:id="@android:id/progress"> |
||||
<scale |
||||
android:drawable="@drawable/progress_primary_holo_light" |
||||
android:scaleWidth="100%" /> |
||||
</item> |
||||
</layer-list> |
Loading…
Reference in new issue