add autozoomimageview
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.mogo.tanlu.fragment;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
@@ -25,6 +26,7 @@ import com.mogo.map.search.poisearch.IMogoPoiSearchListener;
|
||||
import com.mogo.map.search.poisearch.MogoPoiResult;
|
||||
import com.mogo.map.uicontroller.EnumMapUI;
|
||||
import com.mogo.service.MogoServicePaths;
|
||||
import com.mogo.service.imageloader.IMogoImageLoaderListener;
|
||||
import com.mogo.service.imageloader.IMogoImageloader;
|
||||
import com.mogo.service.module.IMogoModuleLifecycle;
|
||||
import com.mogo.tanlu.R;
|
||||
@@ -144,10 +146,46 @@ public class TanluCardViewFragment extends MvpFragment<IView, Presenter<IView>>
|
||||
//图片显示
|
||||
autoZoomInImageView.setVisibility(View.VISIBLE);
|
||||
simpleCoverVideoPlayer.setVisibility(View.GONE);
|
||||
mogoImageloader.displayImage(imageUrl, autoZoomInImageView);
|
||||
// mogoImageloader.displayImage(imageUrl, autoZoomInImageView);
|
||||
mogoImageloader.downloadImage(getActivity(), imageUrl, new IMogoImageLoaderListener() {
|
||||
@Override
|
||||
public void onStart() {
|
||||
Logger.d(TAG, "onStart ------>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompleted(Bitmap bitmap) {
|
||||
Logger.d(TAG, "onCompleted ------>");
|
||||
autoZoomInImageView.setImageBitmap(bitmap);
|
||||
//动画
|
||||
handleImageAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
Logger.e(TAG, "onFailure -----E->" + e);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行图片动画
|
||||
*/
|
||||
private void handleImageAnimation() {
|
||||
autoZoomInImageView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//放大增量是0.3,放大时间是1000毫秒,放大开始时间是1000毫秒以后
|
||||
autoZoomInImageView.init()
|
||||
.startZoomInByScaleDeltaAndDuration(0.3f, 1000, 1500);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* marker点击事件 TODO
|
||||
*
|
||||
@@ -171,14 +209,14 @@ public class TanluCardViewFragment extends MvpFragment<IView, Presenter<IView>>
|
||||
//TODO C位事件,如何获取数据,需要有默认数据
|
||||
@Override
|
||||
public void onPerform() {
|
||||
Logger.d(TAG, "卡片2有效");
|
||||
Logger.d(TAG, "tanlu卡片 有效");
|
||||
|
||||
}
|
||||
|
||||
//TODO 离开C位事件
|
||||
@Override
|
||||
public void onDisable() {
|
||||
Logger.d(TAG, "卡片2无效");
|
||||
Logger.e(TAG, "tanlu卡片 无效");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,7 +264,7 @@ public class TanluCardViewFragment extends MvpFragment<IView, Presenter<IView>>
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onMapClick(MogoLatLng latLng) {
|
||||
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
package com.mogo.tanlu.view;
|
||||
|
||||
import com.mogo.service.imageloader.MogoImageView;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
|
||||
/**
|
||||
* @author lixiaopeng
|
||||
* @description
|
||||
* @since 2020-01-06
|
||||
*/
|
||||
public class AutoZoomInImageView extends MogoImageView {
|
||||
private int mDrawableW;
|
||||
private int mDrawableH;
|
||||
private int mImageViewW;
|
||||
private int mImageViewH;
|
||||
private long mDurationMillis = 700;
|
||||
|
||||
private float[] mValues = new float[9];
|
||||
private float mScaleDelta = 0.2f;
|
||||
|
||||
private Drawable mDrawable;
|
||||
private Matrix mMatrix;
|
||||
|
||||
public AutoZoomInImageView(Context context) {
|
||||
super(context);
|
||||
this.setScaleType(ScaleType.MATRIX);
|
||||
}
|
||||
|
||||
public AutoZoomInImageView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
this.setScaleType(ScaleType.MATRIX);
|
||||
}
|
||||
|
||||
public AutoZoomInImageView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
this.setScaleType(ScaleType.MATRIX);
|
||||
}
|
||||
|
||||
public AutoZoomInImageView init() {
|
||||
initInternalValues();
|
||||
initPicturePosition();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void init(Drawable drawable) {
|
||||
initInternalValues(drawable);
|
||||
initPicturePosition();
|
||||
}
|
||||
|
||||
private void initInternalValues() {
|
||||
mDrawable = getDrawable();
|
||||
|
||||
if (mDrawable == null) {
|
||||
throw new IllegalArgumentException("please set the source of AutoZoomInImageView");
|
||||
}
|
||||
|
||||
mDrawableW = mDrawable.getIntrinsicWidth();
|
||||
mDrawableH = mDrawable.getIntrinsicHeight();
|
||||
|
||||
mImageViewW = getMeasuredWidth();
|
||||
mImageViewH = getMeasuredHeight();
|
||||
|
||||
mMatrix = getImageMatrix();
|
||||
mMatrix.getValues(mValues);
|
||||
}
|
||||
|
||||
private void initInternalValues(Drawable drawable) {
|
||||
mDrawable = drawable;
|
||||
|
||||
if (mDrawable == null) {
|
||||
throw new IllegalArgumentException("please set the source of AutoZoomInImageView");
|
||||
}
|
||||
|
||||
mDrawableW = mDrawable.getIntrinsicWidth();
|
||||
mDrawableH = mDrawable.getIntrinsicHeight();
|
||||
|
||||
mImageViewW = getMeasuredWidth();
|
||||
mImageViewH = getMeasuredHeight();
|
||||
|
||||
mMatrix = getImageMatrix();
|
||||
mMatrix.getValues(mValues);
|
||||
}
|
||||
|
||||
private void initPicturePosition() {
|
||||
updateMatrixValuesOrigin(mMatrix, mValues, mDrawableW, mDrawableH, mImageViewW, mImageViewH);
|
||||
setImageMatrix(mMatrix);
|
||||
}
|
||||
|
||||
private void startZoomInByScaleDelta(final float scaleDelta, long duration) {
|
||||
|
||||
final float oriScaleX = mValues[0];
|
||||
final float oriScaleY = mValues[4];
|
||||
|
||||
ValueAnimator va = ValueAnimator.ofFloat(0, scaleDelta);
|
||||
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
float value = (Float) animation.getAnimatedValue();
|
||||
if (mOnZoomListener != null)
|
||||
mOnZoomListener.onUpdate(AutoZoomInImageView.this, value / scaleDelta);
|
||||
updateMatrixValuesSpan(mValues, mDrawableW, mDrawableH, mImageViewW, mImageViewH,
|
||||
oriScaleX, oriScaleY, value);
|
||||
mMatrix.setValues(mValues);
|
||||
setImageMatrix(mMatrix);
|
||||
}
|
||||
});
|
||||
va.addListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
if (mOnZoomListener != null) mOnZoomListener.onStart(AutoZoomInImageView.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mOnZoomListener != null) mOnZoomListener.onEnd(AutoZoomInImageView.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
}
|
||||
});
|
||||
va.setDuration(duration);
|
||||
va.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* start zooming in
|
||||
*
|
||||
* @param scaleDelta the scale that the image will add to original scale
|
||||
* @param durationMillis the duration of zoomin animation, in millisecond.
|
||||
* @param delayMillis the delayed time of starting zoomin animation, in millisecond.
|
||||
*/
|
||||
public void startZoomInByScaleDeltaAndDuration(final float scaleDelta, final long durationMillis, long delayMillis) {
|
||||
if (scaleDelta < 0) {
|
||||
throw new IllegalArgumentException("scaleDelta should be larger than 0, now scaleDelta is " + scaleDelta);
|
||||
}
|
||||
if (durationMillis < 0) {
|
||||
throw new IllegalArgumentException("durationMillis should not be less than 0, now durationMillis is " + durationMillis);
|
||||
}
|
||||
if (delayMillis < 0) {
|
||||
throw new IllegalArgumentException("delayMillis should not be less than 0, now delayMillis is " + delayMillis);
|
||||
}
|
||||
postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startZoomInByScaleDelta(scaleDelta, durationMillis);
|
||||
}
|
||||
}, delayMillis);
|
||||
}
|
||||
|
||||
/**
|
||||
* the scale that the image will add to original scale
|
||||
*
|
||||
* @param scaleDelta
|
||||
* @return
|
||||
*/
|
||||
public AutoZoomInImageView setScaleDelta(float scaleDelta) {
|
||||
mScaleDelta = scaleDelta;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* the duration of zoomin animation, in millisecond.
|
||||
*
|
||||
* @param durationMillis
|
||||
* @return
|
||||
*/
|
||||
public AutoZoomInImageView setDurationMillis(long durationMillis) {
|
||||
mDurationMillis = durationMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* callback when zoomin animation finished
|
||||
*
|
||||
* @param onZoomListener
|
||||
* @return
|
||||
*/
|
||||
public AutoZoomInImageView setOnZoomListener(OnZoomListener onZoomListener) {
|
||||
mOnZoomListener = onZoomListener;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* start animation of zoomin
|
||||
*
|
||||
* @param delayMillis the delayed time of starting zoomin animation, in millisecond.
|
||||
*/
|
||||
public void start(long delayMillis) {
|
||||
postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startZoomInByScaleDelta(mScaleDelta, mDurationMillis);
|
||||
}
|
||||
}, delayMillis);
|
||||
}
|
||||
|
||||
private void updateMatrixValuesOrigin(Matrix outMatrix, float[] outValues, float drawW, float drawH, float imageW, float imageH) {
|
||||
if (outMatrix == null || outValues == null) {
|
||||
throw new IllegalArgumentException("please set the source of AutoZoomInImageView's matrix and values");
|
||||
}
|
||||
outMatrix.reset();
|
||||
if ((imageH * drawW > drawH * imageW)) {
|
||||
float scale1 = (imageH) / (drawH);
|
||||
float offset1 = (drawW * scale1 - imageW) / 2;
|
||||
outMatrix.postScale(scale1, scale1);
|
||||
outMatrix.postTranslate(-offset1, 0);
|
||||
} else {
|
||||
float scale2 = (imageW) / (drawW);
|
||||
float offset2 = (drawH * scale2 - imageH) / 2;
|
||||
outMatrix.postScale(scale2, scale2);
|
||||
outMatrix.postTranslate(0, -offset2);
|
||||
}
|
||||
outMatrix.getValues(outValues);
|
||||
}
|
||||
|
||||
private void updateMatrixValuesSpan(float[] outValues,
|
||||
float drawW, float drawH,
|
||||
float imageW, float imageH,
|
||||
float oriScaleX, float oriScaleY,
|
||||
float scaleDelta) {
|
||||
outValues[0] = oriScaleX * (1 + scaleDelta);
|
||||
outValues[4] = oriScaleY * (1 + scaleDelta);
|
||||
float offsetwidth = (drawW * outValues[0] - imageW) / 2;
|
||||
outValues[2] = -offsetwidth;
|
||||
float offsetHeight = (drawH * outValues[4] - imageH) / 2;
|
||||
outValues[5] = -offsetHeight;
|
||||
}
|
||||
|
||||
private OnZoomListener mOnZoomListener;
|
||||
|
||||
public interface OnZoomListener {
|
||||
/**
|
||||
* callback when zoom in animation is updating
|
||||
*
|
||||
* @param view AutoZoomInImageView
|
||||
* @param progress return the progress of animation, scope is [0,1]
|
||||
*/
|
||||
void onUpdate(View view, float progress);
|
||||
|
||||
void onEnd(View view);
|
||||
|
||||
void onStart(View view);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
package com.mogo.tanlu.view
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import com.mogo.service.imageloader.MogoImageView
|
||||
|
||||
class AutoZoomInImageView : MogoImageView {
|
||||
|
||||
companion object {
|
||||
const val TAG = "AutoZoomInImageView"
|
||||
}
|
||||
|
||||
private var mDrawableW: Int = 0
|
||||
private var mDrawableH: Int = 0
|
||||
private var mImageViewW: Int = 0
|
||||
private var mImageViewH: Int = 0
|
||||
private var mDurationMillis = 3000L
|
||||
|
||||
private var mValues = FloatArray(9)
|
||||
var isInit: Boolean = false
|
||||
private var mScaleDelta = 0.2f
|
||||
private var va: ValueAnimator = ValueAnimator.ofFloat(0f, mScaleDelta)
|
||||
|
||||
private lateinit var mDrawable: Drawable
|
||||
private lateinit var mMatrix: Matrix
|
||||
|
||||
private var onStart: (View.() -> Unit)? = null
|
||||
|
||||
private var onUpdate: ((view: View, progress: Float) -> Unit)? = null
|
||||
|
||||
private var onEnd: (View.() -> Unit)? = null
|
||||
|
||||
infix fun onStart(onStart: View.() -> Unit) :AutoZoomInImageView{
|
||||
this.onStart = onStart
|
||||
return this
|
||||
}
|
||||
|
||||
infix fun onUpdate(onUpdate: (view: View, progress: Float) -> Unit) :AutoZoomInImageView{
|
||||
this.onUpdate = onUpdate
|
||||
return this
|
||||
}
|
||||
|
||||
infix fun onEnd(onEnd: View.() -> Unit):AutoZoomInImageView {
|
||||
this.onEnd = onEnd
|
||||
return this
|
||||
}
|
||||
|
||||
constructor(context: Context?) : super(context) {
|
||||
this.scaleType = ScaleType.MATRIX
|
||||
}
|
||||
|
||||
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||
this.scaleType = ScaleType.MATRIX
|
||||
}
|
||||
|
||||
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyleAttr
|
||||
) {
|
||||
this.scaleType = ScaleType.MATRIX
|
||||
}
|
||||
|
||||
|
||||
fun init(): AutoZoomInImageView {
|
||||
initInternalValues()
|
||||
initPicturePosition()
|
||||
isInit = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun init(drawable: Drawable) {
|
||||
initInternalValues(drawable)
|
||||
initPicturePosition()
|
||||
}
|
||||
|
||||
private fun initInternalValues() {
|
||||
mDrawable = drawable
|
||||
|
||||
mDrawableW = mDrawable.intrinsicWidth
|
||||
mDrawableH = mDrawable.intrinsicHeight
|
||||
|
||||
mImageViewW = measuredWidth
|
||||
mImageViewH = measuredHeight
|
||||
|
||||
mMatrix = imageMatrix
|
||||
mMatrix.getValues(mValues)
|
||||
}
|
||||
|
||||
private fun initInternalValues(drawable: Drawable) {
|
||||
mDrawable = drawable
|
||||
|
||||
mDrawableW = mDrawable.intrinsicWidth
|
||||
mDrawableH = mDrawable.intrinsicHeight
|
||||
|
||||
mImageViewW = measuredWidth
|
||||
mImageViewH = measuredHeight
|
||||
|
||||
mMatrix = imageMatrix
|
||||
mMatrix.getValues(mValues)
|
||||
}
|
||||
|
||||
private fun initPicturePosition() {
|
||||
updateMatrixValuesOrigin(
|
||||
mMatrix,
|
||||
mValues,
|
||||
mDrawableW.toFloat(),
|
||||
mDrawableH.toFloat(),
|
||||
mImageViewW.toFloat(),
|
||||
mImageViewH.toFloat()
|
||||
)
|
||||
imageMatrix = mMatrix
|
||||
}
|
||||
|
||||
fun setDurationMillis(durationMillis: Long): AutoZoomInImageView {
|
||||
mDurationMillis = durationMillis
|
||||
return this
|
||||
}
|
||||
|
||||
fun startZoomInByScaleDelta(scaleDelta: Float = 0.2f, duration: Long = 3000) {
|
||||
val oriScaleX = mValues[0]
|
||||
val oriScaleY = mValues[4]
|
||||
|
||||
va.addUpdateListener { animation ->
|
||||
val value = animation.animatedValue as Float
|
||||
onUpdate?.invoke(this@AutoZoomInImageView, value / scaleDelta)
|
||||
updateMatrixValuesSpan(
|
||||
mValues,
|
||||
mDrawableW.toFloat(),
|
||||
mDrawableH.toFloat(),
|
||||
mImageViewW.toFloat(),
|
||||
mImageViewH.toFloat(),
|
||||
oriScaleX,
|
||||
oriScaleY,
|
||||
value
|
||||
)
|
||||
mMatrix.setValues(mValues)
|
||||
imageMatrix = mMatrix
|
||||
}
|
||||
va.addListener(object : Animator.AnimatorListener {
|
||||
override fun onAnimationStart(animation: Animator) {
|
||||
onStart?.invoke(this@AutoZoomInImageView)
|
||||
}
|
||||
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
onEnd?.invoke(this@AutoZoomInImageView)
|
||||
}
|
||||
|
||||
override fun onAnimationCancel(animation: Animator) {}
|
||||
override fun onAnimationRepeat(animation: Animator) {}
|
||||
})
|
||||
va.duration = duration
|
||||
va.start()
|
||||
}
|
||||
|
||||
fun zoomPause() {
|
||||
if (va.isRunning) {
|
||||
Log.d(TAG, "pause")
|
||||
va.pause()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun zoomResume() {
|
||||
if (va.isStarted && va.isPaused) {
|
||||
Log.d(TAG, "resume")
|
||||
va.resume()
|
||||
} else {
|
||||
Log.d(TAG, "restart")
|
||||
va.start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateMatrixValuesOrigin(
|
||||
outMatrix: Matrix?,
|
||||
outValues: FloatArray?,
|
||||
drawW: Float,
|
||||
drawH: Float,
|
||||
imageW: Float,
|
||||
imageH: Float
|
||||
) {
|
||||
if (outMatrix == null || outValues == null) {
|
||||
throw IllegalArgumentException("please set the source of AutoZoomInImageView's matrix and values")
|
||||
}
|
||||
outMatrix.reset()
|
||||
|
||||
if (imageH * drawW > drawH * imageW) {
|
||||
val scale1 = imageH / drawH
|
||||
val offset1 = (drawW * scale1 - imageW) / 2
|
||||
outMatrix.postScale(scale1, scale1)
|
||||
outMatrix.postTranslate(-offset1, 0f)
|
||||
} else {
|
||||
val scale2 = imageW / drawW
|
||||
val offset2 = (drawH * scale2 - imageH) / 2
|
||||
outMatrix.postScale(scale2, scale2)
|
||||
outMatrix.postTranslate(0f, -offset2)
|
||||
}
|
||||
outMatrix.getValues(outValues)
|
||||
}
|
||||
|
||||
private fun updateMatrixValuesSpan(
|
||||
outValues: FloatArray,
|
||||
drawW: Float, drawH: Float,
|
||||
imageW: Float, imageH: Float,
|
||||
oriScaleX: Float, oriScaleY: Float,
|
||||
scaleDelta: Float
|
||||
) {
|
||||
outValues[0] = oriScaleX * (1 + scaleDelta)
|
||||
outValues[4] = oriScaleY * (1 + scaleDelta)
|
||||
val offsetwidth = (drawW * outValues[0] - imageW) / 2
|
||||
outValues[2] = -offsetwidth
|
||||
val offsetHeight = (drawH * outValues[4] - imageH) / 2
|
||||
outValues[5] = -offsetHeight
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@
|
||||
|
||||
<com.mogo.tanlu.view.AutoZoomInImageView
|
||||
android:id="@+id/tanlu_photo_imageView"
|
||||
android:src="@drawable/default_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user