|
|
@ -6,16 +6,23 @@ import android.graphics.BitmapShader; |
|
|
|
import android.graphics.Canvas; |
|
|
|
import android.graphics.Canvas; |
|
|
|
import android.graphics.Matrix; |
|
|
|
import android.graphics.Matrix; |
|
|
|
import android.graphics.Paint; |
|
|
|
import android.graphics.Paint; |
|
|
|
|
|
|
|
import android.graphics.Rect; |
|
|
|
import android.graphics.RectF; |
|
|
|
import android.graphics.RectF; |
|
|
|
import android.graphics.Shader; |
|
|
|
import android.graphics.Shader; |
|
|
|
import android.text.TextUtils; |
|
|
|
import android.text.TextUtils; |
|
|
|
import android.util.AttributeSet; |
|
|
|
import android.util.AttributeSet; |
|
|
|
import android.view.View; |
|
|
|
import android.view.View; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.android.volley.NetworkError; |
|
|
|
|
|
|
|
import com.android.volley.NoConnectionError; |
|
|
|
import com.android.volley.VolleyError; |
|
|
|
import com.android.volley.VolleyError; |
|
|
|
import com.android.volley.toolbox.ImageLoader; |
|
|
|
import com.android.volley.toolbox.ImageLoader; |
|
|
|
|
|
|
|
|
|
|
|
import org.floens.chan.ChanApplication; |
|
|
|
import org.floens.chan.ChanApplication; |
|
|
|
|
|
|
|
import org.floens.chan.R; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import static org.floens.chan.utils.AndroidUtils.getString; |
|
|
|
|
|
|
|
import static org.floens.chan.utils.AndroidUtils.sp; |
|
|
|
|
|
|
|
|
|
|
|
public class ThumbnailView extends View implements ImageLoader.ImageListener { |
|
|
|
public class ThumbnailView extends View implements ImageLoader.ImageListener { |
|
|
|
private ImageLoader.ImageContainer container; |
|
|
|
private ImageLoader.ImageContainer container; |
|
|
@ -34,6 +41,10 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { |
|
|
|
BitmapShader bitmapShader; |
|
|
|
BitmapShader bitmapShader; |
|
|
|
private Paint roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); |
|
|
|
private Paint roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean error = false; |
|
|
|
|
|
|
|
private String errorText; |
|
|
|
|
|
|
|
private Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); |
|
|
|
|
|
|
|
|
|
|
|
public ThumbnailView(Context context) { |
|
|
|
public ThumbnailView(Context context) { |
|
|
|
super(context); |
|
|
|
super(context); |
|
|
|
init(); |
|
|
|
init(); |
|
|
@ -50,6 +61,8 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void init() { |
|
|
|
private void init() { |
|
|
|
|
|
|
|
textPaint.setColor(0xff000000); |
|
|
|
|
|
|
|
textPaint.setTextSize(sp(14)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void setUrl(String url, int width, int height) { |
|
|
|
public void setUrl(String url, int width, int height) { |
|
|
@ -60,6 +73,7 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { |
|
|
|
if (container != null) { |
|
|
|
if (container != null) { |
|
|
|
container.cancelRequest(); |
|
|
|
container.cancelRequest(); |
|
|
|
container = null; |
|
|
|
container = null; |
|
|
|
|
|
|
|
error = false; |
|
|
|
setImageBitmap(null); |
|
|
|
setImageBitmap(null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -84,25 +98,28 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { |
|
|
|
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) { |
|
|
|
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) { |
|
|
|
if (response.getBitmap() != null) { |
|
|
|
if (response.getBitmap() != null) { |
|
|
|
setImageBitmap(response.getBitmap()); |
|
|
|
setImageBitmap(response.getBitmap()); |
|
|
|
|
|
|
|
onImageSet(isImmediate); |
|
|
|
clearAnimation(); |
|
|
|
|
|
|
|
if (fadeTime > 0 && !isImmediate) { |
|
|
|
|
|
|
|
setAlpha(0f); |
|
|
|
|
|
|
|
animate().alpha(1f).setDuration(fadeTime); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
setAlpha(1f); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void onErrorResponse(VolleyError error) { |
|
|
|
public void onErrorResponse(VolleyError e) { |
|
|
|
error.printStackTrace(); |
|
|
|
error = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((e instanceof NoConnectionError) || (e instanceof NetworkError)) { |
|
|
|
|
|
|
|
errorText = getString(R.string.thumbnail_load_failed_network); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
errorText = getString(R.string.thumbnail_load_failed_server); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onImageSet(false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected boolean onSetAlpha(int alpha) { |
|
|
|
protected boolean onSetAlpha(int alpha) { |
|
|
|
if (circular) { |
|
|
|
if (error) { |
|
|
|
|
|
|
|
textPaint.setAlpha(alpha); |
|
|
|
|
|
|
|
} else if (circular) { |
|
|
|
roundPaint.setAlpha(alpha); |
|
|
|
roundPaint.setAlpha(alpha); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
paint.setAlpha(alpha); |
|
|
|
paint.setAlpha(alpha); |
|
|
@ -114,45 +131,71 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected void onDraw(Canvas canvas) { |
|
|
|
protected void onDraw(Canvas canvas) { |
|
|
|
if (bitmap == null || getAlpha() == 0f) { |
|
|
|
if (getAlpha() == 0f) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int width = getWidth() - getPaddingLeft() - getPaddingRight(); |
|
|
|
if (error) { |
|
|
|
int height = getHeight() - getPaddingTop() - getPaddingBottom(); |
|
|
|
canvas.save(); |
|
|
|
|
|
|
|
|
|
|
|
if (calculate) { |
|
|
|
Rect bounds = new Rect(); |
|
|
|
calculate = false; |
|
|
|
textPaint.getTextBounds(errorText, 0, errorText.length(), bounds); |
|
|
|
bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight()); |
|
|
|
float x = (getWidth() - bounds.width()) / 2; |
|
|
|
float scale = Math.max( |
|
|
|
float y = getHeight() - (getHeight() - bounds.height()) / 2; |
|
|
|
(float) width / (float) bitmap.getWidth(), |
|
|
|
canvas.drawText(errorText, x, y, textPaint); |
|
|
|
(float) height / (float) bitmap.getHeight()); |
|
|
|
|
|
|
|
float scaledX = bitmap.getWidth() * scale; |
|
|
|
|
|
|
|
float scaledY = bitmap.getHeight() * scale; |
|
|
|
|
|
|
|
float offsetX = (scaledX - width) * 0.5f; |
|
|
|
|
|
|
|
float offsetY = (scaledY - height) * 0.5f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
drawRect.set(-offsetX, -offsetY, scaledX - offsetX, scaledY - offsetY); |
|
|
|
canvas.restore(); |
|
|
|
drawRect.offset(getPaddingLeft(), getPaddingTop()); |
|
|
|
} else { |
|
|
|
|
|
|
|
if (bitmap == null) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int width = getWidth() - getPaddingLeft() - getPaddingRight(); |
|
|
|
|
|
|
|
int height = getHeight() - getPaddingTop() - getPaddingBottom(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (calculate) { |
|
|
|
|
|
|
|
calculate = false; |
|
|
|
|
|
|
|
bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight()); |
|
|
|
|
|
|
|
float scale = Math.max( |
|
|
|
|
|
|
|
(float) width / (float) bitmap.getWidth(), |
|
|
|
|
|
|
|
(float) height / (float) bitmap.getHeight()); |
|
|
|
|
|
|
|
float scaledX = bitmap.getWidth() * scale; |
|
|
|
|
|
|
|
float scaledY = bitmap.getHeight() * scale; |
|
|
|
|
|
|
|
float offsetX = (scaledX - width) * 0.5f; |
|
|
|
|
|
|
|
float offsetY = (scaledY - height) * 0.5f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
drawRect.set(-offsetX, -offsetY, scaledX - offsetX, scaledY - offsetY); |
|
|
|
|
|
|
|
drawRect.offset(getPaddingLeft(), getPaddingTop()); |
|
|
|
|
|
|
|
|
|
|
|
outputRect.set(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), getHeight() - getPaddingBottom()); |
|
|
|
outputRect.set(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), getHeight() - getPaddingBottom()); |
|
|
|
|
|
|
|
|
|
|
|
matrix.setRectToRect(bitmapRect, drawRect, Matrix.ScaleToFit.FILL); |
|
|
|
matrix.setRectToRect(bitmapRect, drawRect, Matrix.ScaleToFit.FILL); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (circular) { |
|
|
|
|
|
|
|
bitmapShader.setLocalMatrix(matrix); |
|
|
|
|
|
|
|
roundPaint.setShader(bitmapShader); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
canvas.save(); |
|
|
|
|
|
|
|
canvas.clipRect(outputRect); |
|
|
|
if (circular) { |
|
|
|
if (circular) { |
|
|
|
bitmapShader.setLocalMatrix(matrix); |
|
|
|
canvas.drawRoundRect(outputRect, width / 2, height / 2, roundPaint); |
|
|
|
roundPaint.setShader(bitmapShader); |
|
|
|
} else { |
|
|
|
|
|
|
|
canvas.drawBitmap(bitmap, matrix, paint); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
canvas.restore(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
canvas.save(); |
|
|
|
private void onImageSet(boolean isImmediate) { |
|
|
|
canvas.clipRect(outputRect); |
|
|
|
clearAnimation(); |
|
|
|
if (circular) { |
|
|
|
if (fadeTime > 0 && !isImmediate) { |
|
|
|
canvas.drawRoundRect(outputRect, width / 2, height / 2, roundPaint); |
|
|
|
setAlpha(0f); |
|
|
|
|
|
|
|
animate().alpha(1f).setDuration(fadeTime); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
canvas.drawBitmap(bitmap, matrix, paint); |
|
|
|
setAlpha(1f); |
|
|
|
} |
|
|
|
} |
|
|
|
canvas.restore(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void setImageBitmap(Bitmap bitmap) { |
|
|
|
private void setImageBitmap(Bitmap bitmap) { |
|
|
|