Merge remote-tracking branch 'origin/feature/v1.0.0' into feature/v1.0.0

This commit is contained in:
zhangyuanzhen
2020-01-06 15:04:14 +08:00
24 changed files with 552 additions and 277 deletions

2
.idea/misc.xml generated
View File

@@ -5,7 +5,7 @@
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@@ -104,6 +104,6 @@ ext {
jetbrainsannotationsjava5: "org.jetbrains:annotations-java5:15.0",
// 统一登录
accountsdk : "com.zhidao.accoutservice:account-sdk:1.0.0.1@aar",
accountsdk : "com.zhidao.accountservice:account-sdk:1.0.2",
]
}

View File

@@ -72,7 +72,7 @@ public class AbsMogoApplication extends Application {
TipToast.init( sApp, null );
initNetConfig();
// initAccountSdk();
initAccountSdk();
}
private static void initNetConfig() {

View File

@@ -15,7 +15,7 @@ import java.lang.reflect.Method;
* Created by congtaowang on 2018/3/29.
*/
class Utils {
public class Utils {
public static String getCellId( Context context ) {
TelephonyManager tm = ( TelephonyManager ) context.getSystemService( Context.TELEPHONY_SERVICE );

View File

@@ -24,7 +24,7 @@ SNAPSHOT_REPOSITORY_URL=http://nexus.zhidaoauto.com/repository/maven-snapshots/
USERNAME=xintai
PASSWORD=xintai2018
# 编译模式: false - 依赖本地版本, true - 依赖 maven 版本
RELEASE=true
RELEASE=false
# 模块版本
DEMO_MODULE_MAP_VERSION=1.0.0-SNAPSHOT
DEMO_MODULE_MAP2_VERSION=1.0.0-SNAPSHOT

View File

@@ -3,10 +3,10 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_height="@dimen/dp_120"
android:orientation="vertical"
android:paddingLeft="35dp"
android:paddingRight="35dp">
android:paddingLeft="@dimen/dp_70"
android:paddingRight="@dimen/dp_70">
<ImageView
android:id="@+id/module_ext_id_voice"
@@ -23,7 +23,7 @@
android:gravity="center_vertical"
android:text="@string/module_ext_str_voice_msg"
android:textColor="@color/module_ext_color_voice_text"
android:textSize="16dp"
android:textSize="@dimen/dp_32"
app:layout_constraintBottom_toBottomOf="@+id/module_ext_id_voice"
app:layout_constraintLeft_toRightOf="@+id/module_ext_id_voice"
app:layout_constraintTop_toTopOf="@+id/module_ext_id_voice" />
@@ -34,7 +34,7 @@
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="#FFFFFF"
android:textSize="24dp"
android:textSize="@dimen/dp_48"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
@@ -44,10 +44,10 @@
android:id="@+id/module_ext_id_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="40dp"
android:layout_marginRight="@dimen/dp_80"
android:gravity="center_vertical"
android:textColor="#FFFFFF"
android:textSize="14dp"
android:textSize="@dimen/dp_28"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/module_ext_id_time"
app:layout_constraintTop_toTopOf="parent"
@@ -57,7 +57,7 @@
android:id="@+id/module_ext_id_weather_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="13dp"
android:layout_marginRight="@dimen/dp_26"
android:gravity="center"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
@@ -66,26 +66,26 @@
<ImageView
android:id="@+id/module_ext_id_weather_icon"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_width="@dimen/dp_44"
android:layout_height="@dimen/dp_44"
tools:src="@drawable/module_ext_ic_voice" />
<TextView
android:id="@+id/module_ext_id_weather_temp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="9dp"
android:layout_marginRight="@dimen/dp_18"
android:textColor="#FFFFFF"
android:textSize="17dp"
android:textSize="@dimen/dp_34"
tools:text="28°" />
<TextView
android:id="@+id/module_ext_id_weather_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="13dp"
android:layout_marginRight="@dimen/dp_26"
android:textColor="#FFFFFF"
android:textSize="14dp"
android:textSize="@dimen/dp_28"
tools:text="晴转多云" />
@@ -100,7 +100,7 @@
android:id="@+id/module_ext_id_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="14dp"
android:layout_marginRight="@dimen/dp_28"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/module_ext_id_weather_container"
app:layout_constraintTop_toTopOf="parent">
@@ -112,14 +112,14 @@
<TextView
android:id="@+id/module_ext_id_msg_counter"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_width="@dimen/dp_30"
android:layout_height="@dimen/dp_30"
android:layout_gravity="right"
android:background="@drawable/module_ext_drawable_msg_bkg"
android:gravity="center"
android:textColor="#FFFFFF"
android:textSize="@dimen/dp_20"
android:visibility="invisible"
android:textSize="10dp"
tools:text="···" />
</FrameLayout>

View File

@@ -17,8 +17,8 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="35dp"
android:layout_marginTop="5dp">
android:layout_marginLeft="@dimen/dp_70"
android:layout_marginTop="@dimen/dp_10">
<!-- 卡片-->
<FrameLayout
@@ -32,9 +32,9 @@
android:id="@+id/module_main_id_cards_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="90dp"
android:layout_marginBottom="@dimen/dp_211"
android:clipToPadding="false"
android:paddingBottom="10dp" />
android:paddingBottom="@dimen/dp_20" />
</FrameLayout>
<!-- 地图-->

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<corners android:radius="@dimen/dp_16" />
<solid android:color="#3F4057" />
</shape>
</item>
</selector>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient android:angle="90" android:endColor="#5CC1FF" android:startColor="#256BFF" />
<corners android:radius="@dimen/dp_16" />
</shape>
</item>
</selector>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -7,4 +8,121 @@
android:id="@+id/module_map_id_map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/module_map_id_search"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_90"
android:layout_marginLeft="@dimen/dp_32"
android:layout_marginTop="@dimen/dp_2"
android:background="@drawable/module_map_dw_common_corner_bkg"
android:drawableLeft="@drawable/module_map_ic_search"
android:drawablePadding="@dimen/dp_16"
android:gravity="center_vertical"
android:paddingLeft="@dimen/dp_26"
android:paddingRight="@dimen/dp_26"
android:text="@string/module_map_str_search_hint"
android:textColor="#99FFFFFF"
android:textSize="@dimen/dp_32"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_32"
android:layout_marginTop="@dimen/dp_2"
android:background="@drawable/module_map_dw_common_corner_bkg"
android:gravity="center_vertical"
android:paddingLeft="@dimen/dp_22"
android:paddingTop="@dimen/dp_17"
android:paddingRight="@dimen/dp_22"
android:paddingBottom="@dimen/dp_17"
app:layout_constraintLeft_toRightOf="@+id/module_map_id_search"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/module_map_id_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/module_map_ic_home" />
<View
android:layout_width="@dimen/dp_2"
android:layout_height="@dimen/dp_54"
android:layout_marginLeft="@dimen/dp_21"
android:layout_marginRight="@dimen/dp_21"
android:background="#1ED8D8D8" />
<ImageView
android:id="@+id/module_map_id_company"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/module_map_ic_company" />
</LinearLayout>
<LinearLayout
android:id="@+id/module_map_id_operation_panel"
android:layout_width="@dimen/dp_90"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/dp_32"
android:layout_marginBottom="@dimen/dp_33"
android:background="@drawable/module_map_dw_common_corner_bkg"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent">
<RelativeLayout
android:id="@+id/module_map_id_vr_mode"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_92"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/module_map_ic_move2_current_location"
android:text="实景"
android:textColor="#CCFFFFFF"
android:textSize="@dimen/dp_24" />
<View
android:layout_width="@dimen/dp_48"
android:layout_height="@dimen/dp_2"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="#1ED8D8D8" />
</RelativeLayout>
<LinearLayout
android:id="@+id/module_map_id_move2_current_location"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_90"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/module_map_ic_move2_current_location" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/module_map_id_upload_road_condition"
android:layout_width="@dimen/dp_90"
android:layout_height="@dimen/dp_90"
android:layout_marginBottom="@dimen/dp_40"
android:background="@drawable/module_map_dw_upload_road_condition_bkg"
android:gravity="center"
android:text="@string/module_map_str_upload_road_condition"
android:textColor="#FFFFFF"
android:textSize="@dimen/dp_24"
app:layout_constraintBottom_toTopOf="@+id/module_map_id_operation_panel"
app:layout_constraintRight_toRightOf="@+id/module_map_id_operation_panel"
app:layout_goneMarginBottom="@dimen/dp_32"
app:layout_goneMarginRight="@dimen/dp_32" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,3 +1,5 @@
<resources>
<string name="app_name">mogo-module-map</string>
<string name="module_map_str_search_hint">搜索目的地</string>
<string name="module_map_str_upload_road_condition">上报\n路况</string>
</resources>

View File

@@ -101,7 +101,7 @@ public class MogoServiceProvider implements IMogoModuleProvider,
case ServiceConst.MSG_TYPE_REFRESH_DECREASE:
mRefreshRemainingTime -= ServiceConst.DECREASE_INTERVAL;
if ( mRefreshRemainingTime == 0 ) {
notifyRefreshData( mAutoRefreshCallback );
notifyRefreshData( mLastAutoRefreshLocation, 2_000, mAutoRefreshCallback );
} else {
mHandler.sendEmptyMessageDelayed( msg.what, ServiceConst.DECREASE_INTERVAL );
}
@@ -334,19 +334,26 @@ public class MogoServiceProvider implements IMogoModuleProvider,
// 手动刷新触发
if ( mLastZoomLevel - zoom > mCustomRefreshStrategy.getZoomOutLevel() ) {
// 缩放级别缩小
notifyRefreshData( mCustomRefreshCallback );
notifyRefreshData( latLng, getQueryRadius(), mCustomRefreshCallback );
mLastCustomRefreshCenterLocation = latLng;
mLastZoomLevel = zoom;
} else if ( mLastZoomLevel == zoom ) {
// 手动平移
if ( invokeRefreshWhenTranslationByUser( latLng ) ) {
notifyRefreshData( mCustomRefreshCallback );
notifyRefreshData( latLng, getQueryRadius(), mCustomRefreshCallback );
mLastCustomRefreshCenterLocation = latLng;
}
}
Logger.d( TAG, "current map status: %s, zoom = %f, tilt = %f, bearing = %f", latLng, zoom, tilt, bearing );
}
private int getQueryRadius() {
if ( mIsVertical ) {
return ( ( int ) ( getMapCameraFactWidth() / 2 ) );
}
return ( ( int ) ( getMapCameraFactHeight() / 2 ) );
}
/**
* 平移地图刷新策略
*
@@ -379,11 +386,11 @@ public class MogoServiceProvider implements IMogoModuleProvider,
// 自动刷新触发
if ( mLastAutoRefreshLocation == null ) {
mLastAutoRefreshLocation = new MogoLatLng( location.getLatitude(), location.getLongitude() );
notifyRefreshData( mAutoRefreshCallback );
notifyRefreshData( mLastAutoRefreshLocation, 2_000, mAutoRefreshCallback );
} else {
float distance = Utils.calculateLineDistance( mLastAutoRefreshLocation, new MogoLatLng( location.getLatitude(), location.getLongitude() ) );
if ( distance > mAutoRefreshStrategy.getDistance() ) {
notifyRefreshData( mAutoRefreshCallback );
notifyRefreshData( mLastAutoRefreshLocation, 2_000, mAutoRefreshCallback );
}
}
}
@@ -391,9 +398,9 @@ public class MogoServiceProvider implements IMogoModuleProvider,
/**
* 刷新数据
*/
private void notifyRefreshData( RefreshCallback callback ) {
private void notifyRefreshData( MogoLatLng latLng, int radius, RefreshCallback callback ) {
Logger.d( TAG, mAutoRefreshCallback == callback ? "触发自动刷新" : "触发手动刷新" );
mRefreshModel.refreshData( callback );
mRefreshModel.refreshData( latLng, radius, callback );
}
@Override

View File

@@ -6,7 +6,10 @@ import java.util.Map;
import io.reactivex.Observable;
import io.reactivex.Single;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.QueryMap;
/**
@@ -17,6 +20,8 @@ import retrofit2.http.QueryMap;
*/
public interface RefreshApiService {
@GET( "" )
Observable< BaseData > refreshData( @QueryMap Map< String, Object > params );
@FormUrlEncoded
@POST( "" )
Observable< BaseData > refreshData( @QueryMap Map< String, Object > params,
@FieldMap Map< String, Object > parameters );
}

View File

@@ -0,0 +1,29 @@
package com.mogo.module.service.network;
import java.util.ArrayList;
import java.util.List;
/**
* @author congtaowang
* @since 2020-01-06
* <p>
* 刷新地图信息接口
*/
public class RefreshBody {
public List< String > dataType = new ArrayList<>();
public int limit = 50;// 请求数量
public int radius = 2_000; // 地理围栏半径(米)
public LatLon location;
public static class LatLon {
private double lat;
private double lon;
public LatLon( double lat, double lon ) {
this.lat = lat;
this.lon = lon;
}
}
}

View File

@@ -6,10 +6,14 @@ import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.commons.data.BaseData;
import com.mogo.commons.network.ParamsProvider;
import com.mogo.commons.network.SubscribeImpl;
import com.mogo.commons.network.Utils;
import com.mogo.map.MogoLatLng;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.network.IMogoNetwork;
import com.mogo.utils.network.RequestOptions;
import com.mogo.utils.network.utils.GsonUtil;
import java.util.HashMap;
import java.util.Map;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -33,14 +37,21 @@ public class RefreshModel {
this.mRefreshApiService = network.create( RefreshApiService.class, "http://www.baidu.com/" );
}
public void refreshData( final RefreshCallback callback ) {
public void refreshData( MogoLatLng latLng, int radius, final RefreshCallback callback ) {
if ( callback != null ) {
callback.onSuccess();
return;
}
if ( mRefreshApiService != null ) {
final Map< String, Object > params = new ParamsProvider.Builder( mContext ).build();
mRefreshApiService.refreshData( params )
final Map< String, Object > query = new ParamsProvider.Builder( mContext ).build();
final Map< String, Object > field = new HashMap<>();
field.put( "sn", query.get( "sn" ) );
final RefreshBody refreshBody = new RefreshBody();
refreshBody.limit = 50;
refreshBody.location = new RefreshBody.LatLon( latLng.lat, latLng.lng );
refreshBody.radius = radius;
field.put( "data", GsonUtil.jsonFromObject( refreshBody ) );
mRefreshApiService.refreshData( query, field )
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() )
.subscribe( new SubscribeImpl< BaseData >( RequestOptions.create( mContext ) ) {

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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
}
}

View File

@@ -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" />

View File

@@ -2,7 +2,9 @@ package com.mogo.service.impl.imageloader.glide;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.alibaba.android.arouter.facade.annotation.Route;
@@ -10,7 +12,10 @@ import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.ImageViewTarget;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.imageloader.IMogoImageLoaderListener;
import com.mogo.service.imageloader.IMogoImageloader;
@@ -21,6 +26,8 @@ import com.mogo.service.impl.imageloader.glide.transform.GlideRoundBitmapTransfo
import com.mogo.service.impl.imageloader.glide.utils.DiskLruCacheManager;
import com.mogo.utils.glide.GlideApp;
import java.io.File;
/**
* @author congtaowang
* @since 2019-12-23
@@ -142,22 +149,24 @@ public class GlideImageLoader implements IMogoImageloader {
GlideApp.with( context.getApplicationContext() )
.asBitmap()
.load( url )
.listener( new RequestListener< Bitmap >() {
.into( new SimpleTarget< Bitmap >() {
@Override
public boolean onLoadFailed( @Nullable GlideException e, Object model, Target< Bitmap > target, boolean isFirstResource ) {
if ( listener != null ) {
listener.onFailure( e );
}
return false;
}
@Override
public boolean onResourceReady( Bitmap resource, Object model, Target< Bitmap > target, DataSource dataSource, boolean isFirstResource ) {
public void onResourceReady( @NonNull Bitmap resource, @Nullable Transition< ? super Bitmap > transition ) {
if ( listener != null ) {
listener.onCompleted( resource );
}
return false;
}
@Override
public void onLoadStarted( @Nullable Drawable placeholder ) {
super.onLoadStarted( placeholder );
}
@Override
public void onLoadFailed( @Nullable Drawable errorDrawable ) {
if ( listener != null ) {
listener.onFailure( new Exception( "download failed." ) );
}
}
} );
}