scenario

Because the company’s project is going to make a pop-up animation effect similar to microblog release, and I also think this effect is cool, so I would like to share my results here (O(∩_∩) haha ~

Without further ado, let’s take a look at the renderings





image

The implementation process

Experiment this effect only has one page, the specific layout file is as follows:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/contentView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
    android:alpha="0.9"
    android:background="@mipmap/bg_dialog_publish"
    android:gravity="bottom|center_horizontal">

    <LinearLayout
        android:id="@+id/ll_close"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:layout_alignParentBottom="true"
        android:background="@android:color/white"
        android:gravity="center">

        <ImageView
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_gravity="center"
            android:padding="8dp"
            android:src="@mipmap/ic_publish_delete" />
    </LinearLayout>


    <LinearLayout
        android:id="@+id/ll_link_des"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/ll_close"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="20dp"
        android:gravity="center">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Publish links to support the analysis of wechat articles, B sites, Miaopai and other links"
            android:textColor="#7f7f7f"
            android:textSize="12sp" />
        <ImageView
            android:layout_width="12dp"
            android:layout_height="12dp"
            android:layout_gravity="center"
            android:layout_marginLeft="3dp"
            android:src="@mipmap/ic_why_tag_blue" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/weblink_window"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/ll_close"
        android:layout_alignLeft="@+id/video_window"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="80dp"
        android:layout_marginTop="40dp"
        android:gravity="center"
        android:orientation="vertical">

        <ImageView
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@mipmap/ic_publish_weblink" />

        <TextView
            android:textSize="15sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Link"
            android:textColor="# 606060" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/text_window"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/ll_close"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="80dp"
        android:layout_marginTop="40dp"
        android:gravity="center"
        android:orientation="vertical">

        <ImageView
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@mipmap/ic_publish_text" />

        <TextView
            android:textSize="15sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Text"
            android:textColor="# 606060" />
    </LinearLayout>


    <LinearLayout
        android:id="@+id/photo_window"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/weblink_window"
        android:layout_centerHorizontal="true"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:gravity="center"
        android:orientation="vertical">

        <ImageView
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@mipmap/ic_publish_photo" />

        <TextView
            android:textSize="15sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Image"
            android:textColor="# 606060" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/video_window"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/weblink_window"
        android:layout_centerHorizontal="true"
        android:layout_toLeftOf="@+id/photo_window"
        android:gravity="center"
        android:orientation="vertical">

        <ImageView
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@mipmap/ic_publish_video" />

        <TextView
            android:textSize="15sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Video"
            android:textColor="# 606060" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/voice_window"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/weblink_window"
        android:layout_centerHorizontal="true"
        android:layout_toRightOf="@+id/photo_window"
        android:gravity="center"
        android:orientation="vertical">

        <ImageView
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@mipmap/ic_publish_voice" />

        <TextView
            android:textSize="15sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Voice"
            android:textColor="# 606060" />
    </LinearLayout>

</RelativeLayout>Copy the code

There is nothing to explain about the layout code, so let’s look at the effects of the animation:

public class PublishPopWindow extends PopupWindow implements View.OnClickListener {

    private View rootView;
    private RelativeLayout contentView;
    private Activity mContext;

    public PublishPopWindow(Activity context) {
        this.mContext = context;
    }

    public void showMoreWindow(View anchor) {
        LayoutInflater inflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        rootView = inflater.inflate(R.layout.dialog_publish, null);
        int h = mContext.getWindowManager().getDefaultDisplay().getHeight();
        int w = mContext.getWindowManager().getDefaultDisplay().getWidth();
        setContentView(rootView);
        this.setWidth(w);
        this.setHeight(h - ScreenUtils.getStatusHeight(mContext));

        contentView = (RelativeLayout) rootView.findViewById(R.id.contentView);
        LinearLayout close = (LinearLayout) rootView.findViewById(R.id.ll_close);
        close.setBackgroundColor(0xFFFFFFFF);
        close.setOnClickListener(this);
        showAnimation(contentView);
        setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.translucence_with_white));
        setOutsideTouchable(true);
        setFocusable(true);
        showAtLocation(anchor, Gravity.BOTTOM, 0.0);
    }

    /** * displays the animation effect *@param layout
     */
    private void showAnimation(ViewGroup layout) {
        // Traverses the subattempt of the root attempt
        for (int i = 0; i < layout.getChildCount(); i++) {
            final View child = layout.getChildAt(i);
            // Ignore closing the component
            if (child.getId() == R.id.ll_close) {
                continue;
            }
            // Sets click events for all level 1 child attempts
            child.setOnClickListener(this);
            child.setVisibility(View.INVISIBLE);
            // Delay the display of each sub-attempt (main animation is shown here)
            Observable.timer(i * 50, TimeUnit.MILLISECONDS)
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Action1<Long>() {
                        @Override
                        public void call(Long aLong) {
                            child.setVisibility(View.VISIBLE);
                            ValueAnimator fadeAnim = ObjectAnimator.ofFloat(child, "translationY".600.0);
                            fadeAnim.setDuration(300);
                            KickBackAnimator kickAnimator = new KickBackAnimator();
                            kickAnimator.setDuration(150); fadeAnim.setEvaluator(kickAnimator); fadeAnim.start(); }}); }}/** * Close animation *@param layout
     */
    private void closeAnimation(ViewGroup layout) {
        for (int i = 0; i < layout.getChildCount(); i++) {
            final View child = layout.getChildAt(i);
            if (child.getId() == R.id.ll_close) {
                continue;
            }
            Observable.timer((layout.getChildCount() - i - 1) * 30, TimeUnit.MILLISECONDS)
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Action1<Long>() {
                        @Override
                        public void call(Long aLong) {
                            child.setVisibility(View.VISIBLE);
                            ValueAnimator fadeAnim = ObjectAnimator.ofFloat(child, "translationY".0.600);
                            fadeAnim.setDuration(200);
                            KickBackAnimator kickAnimator = new KickBackAnimator();
                            kickAnimator.setDuration(100);
                            fadeAnim.setEvaluator(kickAnimator);
                            fadeAnim.start();
                            fadeAnim.addListener(new Animator.AnimatorListener() {

                                @Override
                                public void onAnimationStart(Animator animation) {}@Override
                                public void onAnimationRepeat(Animator animation) {}@Override
                                public void onAnimationEnd(Animator animation) {
                                    child.setVisibility(View.INVISIBLE);
                                }

                                @Override
                                public void onAnimationCancel(Animator animation) {}}); }});if (child.getId() == R.id.video_window) {
                Observable.timer((layout.getChildCount() - i) * 30 + 80, TimeUnit.MILLISECONDS)
                        .subscribeOn(Schedulers.newThread())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<Long>() {
                            @Override
                            public void call(Long aLong) { dismiss(); }}); }}}@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.video_window:
            case R.id.photo_window:
            case R.id.voice_window:
            case R.id.weblink_window:
            case R.id.text_window:
            case R.id.ll_link_des:
                goCreate();
                break;
            case R.id.ll_close:
                if (isShowing()) {
                    closeAnimation(contentView);
                }
                break;
            default:
                break; }}private void goCreate(a) {
        Observable.timer(500, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) { closeAnimation(contentView); }}); }}Copy the code

Basically a popWindow popup attempt. Explain exactly how it works

  • The showMoreWindow() method is mainly used to initialize popWindow.
  • The showAnimation() method mainly implements the incoming animation. The process is to iterate through the root attempt and assign an animation effect to each child attempt based on the specific effect. In this case, the processing is delay, each child attempt to display a time difference, and finally we have the desired animation effect. Here I delay processing is implemented through the TIMER operator of Rxjava, and more Rxjava scenario operations are passed to the Rxjava usage scenario
  • The closeAnimation() method is similar to the showAnimation method, except that it is the animation that leaves. The extra part is the animation listener, which hides the child attempt after the animation, and the other part is this code

if (child.getId() == R.id.video_window) { Observable.timer((layout.getChildCount() – i) * 30 + 80, TimeUnit.MILLISECONDS) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1

() { @Override public void call(Long aLong) { dismiss(); }}); } this code is mainly used to close the popWindow window, where r.id.video_window is not necessarily the last traversal to the child, it is not very important, mainly depends on the effect.

  • OnClick () is the click listener.

The appendix

I hope you have any suggestions and opinions can be put forward. Hope more.

We look forward to your attention and exchange Android together

GITHUB source code download