android兼容各版本共享view beta1

使用

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.image).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShareView.get()
                        .activity(MainActivity.this)
                        .shareView(findViewById(R.id.image))
                        .startActivity(new Intent(getApplicationContext(),SecondAct.class));
            }
        });

    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.wanjian.shareview.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="First Act"/>

    <LinearLayout
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:src="@drawable/img"/>

        <ImageView
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:layout_marginLeft="5dp"
            android:src="@drawable/img"/>
    </LinearLayout>
</RelativeLayout>

public class SecondAct extends AppCompatActivity {

    String TAG = "AnimView";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_sec);

        ShareView.get().activity(this).shareView(findViewById(R.id.image)).onCreate(new ShareView.AnimListener() {
            @Override
            public void onStart() {
                Log.d(TAG, "onStart: ");
            }

            @Override
            public void onUpdate(float degree) {
                //Log.d(TAG, "onUpdate: " + degree);
            }

            @Override
            public void onEnd() {
                Log.d(TAG, "onEnd: ");
            }
        });

        View v=findViewById(R.id.image);
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShareView.get().activity(SecondAct.this).shareView(v).startActivity(new Intent(getApplicationContext(),ThreedAct.class));
            }
        });


    }
}

activity_sec.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.wanjian.shareview.MainActivity">


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"

        android:background="#e1e1e1"
        android:orientation="vertical">


        <LinearLayout
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:orientation="horizontal">

            <ImageView
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:src="@drawable/img"/>

            <ImageView
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginLeft="5dp"
                android:src="@drawable/img"/>
        </LinearLayout>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="second"
            android:textColor="#000"
            android:textSize="20sp"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="90dp"
        android:orientation="vertical">

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="test"/>

        <Button
            android:layout_marginTop="5dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="test"/>

        <Button
            android:layout_marginTop="5dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="test"/>

        <Button
            android:layout_marginTop="5dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="test"/>

        <Button
            android:layout_marginTop="5dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="test"/>

        <Button
            android:layout_marginTop="5dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="test"/>
    </LinearLayout>
</RelativeLayout>


package com.wanjian.shareview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

/**
 * Created by wanjian on 2016/10/18.
 */

public class ThreedAct extends AppCompatActivity {

    String TAG = "AnimView";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_three);

        ShareView.get().activity(this).shareView(findViewById(R.id.image)).onCreate(new ShareView.AnimListener() {
            @Override
            public void onStart() {
                Log.d(TAG, "onStart: ");
            }

            @Override
            public void onUpdate(float degree) {
                //Log.d(TAG, "onUpdate: " + degree);
            }

            @Override
            public void onEnd() {
                Log.d(TAG, "onEnd: ");
            }
        });
    }
}


activity_three.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"

    android:orientation="vertical"
    tools:context="com.wanjian.shareview.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="test"/>

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:text="test"/>

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:text="test"/>


    </LinearLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#e1e1e1"
        android:orientation="vertical">


        <ImageView
            android:id="@+id/image"
            android:layout_width="250dp"
            android:layout_height="250dp"
            android:src="@drawable/img"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="three"
            android:textColor="#f00"
            android:textSize="30sp"/>
    </LinearLayout>


</LinearLayout>



ShareView源码

package com.wanjian.shareview;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

import java.lang.ref.WeakReference;

/**
 * Created by wanjian on 2016/10/18.
 * <p>
 * <p>
 * 基本思路:<p>
 * 获取当前activity中所需共享view的影像bitmap(view.draw(new Canvas(bitmap))),和在屏幕上位置,宽高。<p>
 * 启动新activity时设置没有动画过度act.overridePendingTransition(0, 0)。<p>
 * 获取新activty中共享view在屏幕上的位置,宽高。<p>
 * 为新activity添加蒙层(FrameLayout) act.getWindow().getDecorView().addView(animView)<p>
 * 开启动画(mScroller),绘制之前activty共享view的影像bitmap,通过Matrix对其移动和缩放<p>
 * <p>
 * 优点:<p>
 * 不受布局限制,可以是任何布局,两个activty中共享view可以没有任何联系,大小,位置,随意
 * (git上PreLollipopTransition是在父布局内进行属性动画变化,若父布局比较小,则动画过程显示不完整)。
 * <p>
 * <p>
 * 若没有动画,可能是由于bitmap被回收了,logcat会输出如下<p>
 * preLaunch: android.graphics.Bitmap@32d90820<p>
 * onCreate:... android.widget.LinearLayout{deb1680 V.E..... ......I. 0,0-0,0 #7f0b0029 app:id/image} null<p>
 *
 *  该demo在魅族mx5上只需多耗费2M内存
 */

public class ShareView {

    private String TAG = "AnimView";
    private static WeakReference<Activity> sActivityRef;
    private static WeakReference<View> sViewRef;
    private static WeakReference<Bitmap> sBitmapRef;

    private static int[] sViewLocation;
    private static int width;
    private static int height;
    private static ShareView sShareView;

    public static ShareView get() {
        return sShareView = new ShareView();
    }

    public ShareView activity(Activity activity) {
        sActivityRef = new WeakReference<>(activity);
        return this;
    }

    public ShareView shareView(View view) {
        sViewRef = new WeakReference<>(view);
        return this;
    }

    public void startActivity(Intent intent) {
        if (sActivityRef == null) {
            return;
        }
        Activity act = sActivityRef.get();
        if (act == null) {
            return;
        }
        preLaunch();
        act.startActivity(intent);
        act.overridePendingTransition(0, 0);
    }

//    public void startActivity(Intent intent, @Nullable Bundle options) {
//        if (sActivityRef == null) {
//            return;
//        }
//        Activity act = sActivityRef.get();
//        if (act == null) {
//            return;
//        }
//        preLaunch();
//        act.startActivity(intent, potions);
//        act.overridePendingTransition(0, 0);
//    }

    public void startActivityForResult(Intent intent, int requestCode) {
        if (sActivityRef == null) {
            return;
        }
        Activity act = sActivityRef.get();
        if (act == null) {
            return;
        }
        preLaunch();
        act.startActivityForResult(intent, requestCode);
        act.overridePendingTransition(0, 0);
    }

//    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
//        if (sActivityRef == null) {
//            return;
//        }
//        Activity act = sActivityRef.get();
//        if (act == null) {
//            return;
//        }
//        preLaunch();
//        act.startActivityForResult(intent, requestCode, options);
//        act.overridePendingTransition(0, 0);
//    }


    public void onCreate(final AnimListener animlistener) {
        Log.d(TAG, "onCreate: " + sActivityRef + " " + sViewRef + " " + sBitmapRef + " " + sViewLocation);
        if (sActivityRef == null || sViewRef == null || sBitmapRef == null || sViewLocation == null) {
            return;
        }
        final Activity act = sActivityRef.get();
        final View view = sViewRef.get();
        final Bitmap bmp = sBitmapRef.get();

        Log.d(TAG, "onCreate: " + act + " " + view + " " + bmp);
        if (act == null || view == null || bmp == null || bmp.isRecycled()) {
            return;
        }
        if (!(act.getWindow().getDecorView() instanceof FrameLayout)) {
            return;
        }
        final FrameLayout animContainer = (FrameLayout) act.getWindow().getDecorView();
        final int viewState = view.getVisibility();
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                Log.d(TAG, "onGlobalLayout: ");
                view.setVisibility(View.INVISIBLE);
                int curLocation[] = new int[2];
                view.getLocationOnScreen(curLocation);
                final AnimView animView = new AnimView(act);
                animContainer.addView(animView);
                animView.startAnim(bmp, sViewLocation[0], sViewLocation[1], width, height, curLocation[0], curLocation[1], view.getWidth(), view.getHeight(), new AnimListener() {
                    @Override
                    public void onStart() {
                        if (animlistener != null) {
                            animlistener.onStart();
                        }
                    }

                    @Override
                    public void onUpdate(float degree) {
                        if (animlistener != null) {
                            animlistener.onUpdate(degree);
                        }
                    }

                    @Override
                    public void onEnd() {
                        animContainer.removeView(animView);
                        Log.d(TAG, "onEnd: ---- ");
                        if (animlistener != null) {
                            view.setVisibility(viewState);
                            animlistener.onEnd();
                        }
                    }
                });
            }
        });
    }

    private void preLaunch() {
        if (sViewRef == null) {
            return;
        }
        View view = sViewRef.get();

        if (view != null && (width = view.getWidth()) > 0 && (height = view.getHeight()) > 0) {
            try {
                Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
                Canvas canvas = new Canvas(bitmap);
                canvas.drawColor(Color.WHITE);//设置背景白色
                view.draw(canvas);
                sBitmapRef = new WeakReference<>(bitmap);
                sViewLocation = new int[2];
                view.getLocationOnScreen(sViewLocation);
                Log.d(TAG, "preLaunch: " + bitmap);
            } catch (Exception e) {
                e.printStackTrace();
                return;
            }

        }
    }

    interface AnimListener {
        void onStart();

        void onUpdate(float degree);

        void onEnd();
    }
}


animView

package com.wanjian.shareview;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.Scroller;

/**
 * Created by wanjian on 2016/10/18.
 */

public class AnimView extends View {

    private static final String TAG = "AnimView";

    public AnimView(Context context) {
        super(context);
        init();
    }

    public AnimView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public AnimView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @SuppressLint("NewApi")
    public AnimView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }


    private final int DURATION = 1000;
    private Scroller mScroller;

    private Matrix mMatrix;

    private Bitmap bitmap;
    private int origL;
    private int origT;
    private int origW;
    private int origH;
    private int curL;
    private int curT;
    private int curW;
    private int curH;
    private ShareView.AnimListener listener;

    private Runnable mTask;

    private void init() {
        mMatrix = new Matrix();
        mTask = new Runnable() {
            @Override
            public void run() {
                if (listener != null) {
                    listener.onEnd();
                }
            }
        };
        mScroller = new Scroller(getContext(), new AccelerateDecelerateInterpolator());
    }

    public void startAnim(final Bitmap bitmap, int origL, int origT, int origW, int origH, int curL, int curT, int curW, int curH, final ShareView.AnimListener listener) {
        this.bitmap = bitmap;
        this.origL = origL;
        this.origT = origT;
        this.origW = origW;
        this.origH = origH;
        this.curL = curL;
        this.curT = curT;
        this.curW = curW;
        this.curH = curH;
        this.listener = listener;
        if (listener != null) {
            listener.onStart();
        }
        mScroller.startScroll(0, 0, 0, 0, DURATION);
        invalidate();
        postDelayed(mTask, DURATION);
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            if (listener != null) {
                listener.onUpdate(1.0f * mScroller.timePassed() / DURATION);
            }
            invalidate();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        if (!bitmap.isRecycled()) {
            bitmap.recycle();
        }
        getHandler().removeCallbacks(mTask);
        Log.d(TAG, "onDetachedFromWindow: " + bitmap.isRecycled());
        super.onDetachedFromWindow();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.d(TAG, "onDraw: ");
        if (bitmap.isRecycled()) {
            return;
        }
        float degree = 1.0f * mScroller.timePassed() / DURATION;

        float curX = origL + (curL - origL) * degree;
        float curY = origT + (curT - origT) * degree;

        mMatrix.setTranslate(curX, curY);
        float scaleX = 1.0f * ((curW - origW) * degree + origW) / origW;
        float scaleY = 1.0f * ((curH - origH) * degree + origH) / origH;
        mMatrix.preScale(scaleX, scaleY);
        canvas.drawBitmap(bitmap, mMatrix, null);
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值