初級(jí)文章淀散,大神請(qǐng)輕噴
先上效果圖:
知識(shí)要點(diǎn):
屬性動(dòng)畫(huà)的使用
Android頂部狀態(tài)欄的隱藏(Theme)
一、屬性動(dòng)畫(huà)
本文主要用了縮放動(dòng)畫(huà),重點(diǎn)在于縮放動(dòng)畫(huà)的起始位置的計(jì)算。
1木人、先計(jì)算原小圖與全屏大圖的縮放比例mScale
public static float getCurrentPicOriginalScale(Context context, JPhotosInfos infos){
float mScale;
int width = infos.getWidth();
int height = infos.getHeight();
float imgScale = JBitmapUtils.getImgScale(width, height);
float mWindowScale = JWindowUtil.getWindowScale(context);
if(imgScale >= mWindowScale){
mScale = width * 1.0f / JWindowUtil.getWindowWidth(context);
}else{
mScale = height * 1.0f / JWindowUtil.getWindowHeight(context);
}
return mScale;
}
2中贝、計(jì)算縮放動(dòng)畫(huà)的起始點(diǎn)
首先獲取到小圖在整個(gè)屏幕中的位置及大小
public static Rect getDrawableBoundsInView(ImageView iv) {
if (iv == null || iv.getDrawable() == null) {
return null;
}
Drawable d = iv.getDrawable();
Rect result = new Rect();
iv.getGlobalVisibleRect(result);
Rect tDrawableRect = d.getBounds();
android.graphics.Matrix drawableMatrix = iv.getImageMatrix();
float[] values = new float[9];
if (drawableMatrix != null) {
drawableMatrix.getValues(values);
}
result.left = result.left + (int) values[android.graphics.Matrix.MTRANS_X];
result.top = result.top + (int) values[android.graphics.Matrix.MTRANS_Y];
result.right = (int) (result.left + tDrawableRect.width() * (values[android.graphics.Matrix.MSCALE_X] == 0 ? 1.0f : values[android.graphics.Matrix.MSCALE_X]));
result.bottom = (int) (result.top + tDrawableRect.height() * (values[android.graphics.Matrix.MSCALE_Y] == 0 ? 1.0f : values[android.graphics.Matrix.MSCALE_Y]));
return result;
}
圖片寬高及大小用于計(jì)算縮放動(dòng)畫(huà)的起始位置pivotX舔痕,pivotY
先取X軸為例湃交,如上圖:
紅點(diǎn)為起始縮放點(diǎn),黑線為最終長(zhǎng)度谦秧,那么只要計(jì)算紅點(diǎn)距離起始點(diǎn)的長(zhǎng)度就可以了竟纳,可得公式:
localX = pivot / (1-mScale)
Y軸同上邏輯,以代碼形式:
int width = infos.getWidth();
int height = infos.getHeight();
int localX = infos.getLeft();
int localY = infos.getTop();
float windowScale = JWindowUtil.getWindowScale(JApp.getIns());
float imgScale = JBitmapUtils.getImgScale(width, height);
if(imgScale >= windowScale){
animImgStartHeight = JWindowUtil.getWindowHeight(JApp.getIns()) * originalScale;
pivotX = localX / (1 - originalScale);
pivotY = (localY - (animImgStartHeight - height) / 2) / (1 - originalScale);
}else{
animImgStartWidth = JWindowUtil.getWindowWidth(JApp.getIns()) * originalScale;
pivotX = (localX - (animImgStartWidth - width) / 2) / (1 - originalScale);
pivotY = localY / (1 - originalScale);
}
PS:關(guān)于起始位置的計(jì)算疚鲤,我腦子短路了好久锥累,其實(shí)就是縮放度為0的那個(gè)點(diǎn)的坐標(biāo),那既然知道小圖片的位置集歇,寬高桶略,以及縮放度,那就簡(jiǎn)單了诲宇。
最后別忘了setPivotX和setPivotY际歼,至此打開(kāi)動(dòng)畫(huà)的設(shè)置完成。
3姑蓝、手勢(shì)滑動(dòng)
這里借用了GalleryFinal的PhotoView鹅心,在其基礎(chǔ)上添加了自定義的OnViewDragListener
public static interface OnViewDragListener {
/**
* A callback to receive where the user taps on a ImageView. You will receive a callback if
* the user taps anywhere on the view, dragging on 'whitespace' will not be ignored.
*
* @param x - where the user dragged from the left of the View.
* @param y - where the user dragged from the top of the View.
*/
void onViewDrag(float x, float y);
void onDragFinish();
}
x和y分別是在其坐標(biāo)軸上的偏移量。
手勢(shì)移動(dòng)監(jiān)聽(tīng)回調(diào):
private void startDrag(float x, float y){
mViewPager.setTranslationX(x);
mViewPager.setTranslationY(y);
if(y > 0){
mViewPager.setPivotX(JWindowUtil.getWindowWidth(this) / 2);
mViewPager.setPivotY(JWindowUtil.getWindowHeight(this) / 2);
float scale = Math.abs(y) / JWindowUtil.getWindowHeight(this);
if(scale < 1 && scale > 0) {
mViewPager.setScaleX(1-scale);
mViewPager.setScaleY(1-scale);
mRlRoot.setBackgroundColor(Color.parseColor(JStringUtils.getBlackAlphaBg(1-scale)));
}
}
}
這里重新設(shè)置了PivotX和PivotY它掂,設(shè)置為大圖中心巴帮,不然滑動(dòng)的縮放會(huì)跑偏溯泣。
4虐秋、退出動(dòng)畫(huà)
這個(gè)和開(kāi)始動(dòng)畫(huà)差不多,唯一要注意的是垃沦,當(dāng)用手勢(shì)滑動(dòng)過(guò)以后客给,由于重新設(shè)置過(guò)PivotX和PivotY,所以移動(dòng)動(dòng)畫(huà)需要加上偏移量肢簿。
由上圖可知靶剑,改變了pivot之后蜻拨,Translation動(dòng)畫(huà)需要加上相應(yīng)地偏移量才能保證初始位置沒(méi)有變化。
ObjectAnimator animatorTransX = ObjectAnimator.ofFloat(target, View.TRANSLATION_X,
target.getTranslationX() +
(JWindowUtil.getWindowWidth(JApp.getIns()) / 2 * (1 - target.getScaleX()) -
target.getPivotX() * (1 - target.getScaleX())),
0);
ObjectAnimator animatorTransY = ObjectAnimator.ofFloat(target, View.TRANSLATION_Y,
target.getTranslationY() +
(JWindowUtil.getWindowHeight(JApp.getIns()) / 2 * (1 - target.getScaleY()) -
target.getPivotY() * (1 - target.getScaleY())),
0);
好了桩引,一整套流程總算是走完了缎讼。
二、主題設(shè)置
這個(gè)比較簡(jiǎn)單了
在入口的activity的主題
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
布局文件上記得
android:fitsSystemWindows="true"
查看大圖的activity主題
<style name="FullscreenTransTheme" parent="AppTheme">
<item name="android:actionBarStyle">@style/FullscreenActionBarStyle</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">@color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowFullscreen">true</item>
</style>
<style name="FullscreenActionBarStyle" parent="Widget.AppCompat.ActionBar">
<item name="android:background">@color/transparent</item>
</style>
主要是為了防止返回的時(shí)候入口activity跳動(dòng)坑匠。
最后是傳送門(mén)血崭。
轉(zhuǎn)載請(qǐng)注明出處:http://www.reibang.com/p/dffca954fb52