Android dynamic efficiency achieved - up pop sliding bottom barrage

 Recently there is a new requirement Lively list needs to be made in turn from the bottom of the screen pop-up animation, rendering saw the first time thought of the barrage to achieve, but think about it later rejected the idea, first of all this Lively unlike the list barrage need real-time access to play, a limited number of comments on the second screen shows bar, fixed to a maximum of a few, and then there are the new pop-up put a top disappear, I do not want to barrage are like full screen, the third is what I saw barrage B stations open source library does not support the barrage vertical play, if you want to achieve this demand through barrage way, it also needs its own to expand the library, a little detour mean.

After thinking it over, I think ViewGroup can animate when adding and removing internal View, then it is not I meet all the features you need it? So online Baidu a moment, it was a useful way to do this is similar to the effect of, for example, this Android UI: scroll up and down the barrage of comments

Others achieve results

By the time the animation ViewGroup set LayoutTransition to achieve control View to add and delete, display interface fixed four reviews, the entire carousel comments are multiplexed four TextView, delete comment when shown the first time more than four comments to display. But I found that it is only performed Demo animation set in advance when added View, delete the time and did not execute. First Copy down the short run it and see it (the ability to copy and paste Levi full level), do not run do not know, a run surprised even add animation when the View can not perform normal, when you add a fifth View (that is, Article comments, multiplexing first reviews the content), the new VIew is displayed directly, and did not perform animations, and before the four can all be performed normally.

I began to suspect that is not because the implementation of the delete operation before the new so out of the question, I'll delete the code and then ran off the note again, really no problem, so I would venture to guess that ViewGroup can not be executed at the same time adding and removing animation, in order to verify my guess, I went to the Baidu (Baidu capacity out), looked around found a blog is the problem, and I figured out, and the same conclusion, because there was no collection of bookmarks, too lazy to find, and hold on links.

In addition to my problems found in the process of Baidu's LayoutTransition a lot of pits, concrete can take a look at this blog Kai ship the god of custom animation trilogy of articles (XII) - animateLayoutChanges and LayoutTransition

Solution

Since I can not perform add and delete animations while, then I can listen to add animation, etc. after it completed the implementation of a delete operation, but this way, add and delete animations can not be executed synchronously, so the effect will be greatly reduced , how to do it, Quxianjiuguo, then add animation to start when you want to remove pairs VIew execution of a change in the transparency of animation, such as after the end of adding animation to delete VIew will become transparent, and the next time you perform a delete operation , you can mysteriously achieve the results we want. Note that there will be deleted when you delete an animation execution here, so we need to carry out a process to remove the animation, the effect to prevent errors occur.

The Code

<RelativeLayout 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"
    android:background="@android:color/white"
    android:orientation="vertical">


    <LinearLayout
        android:id="@+id/ll_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="bottom"
        android:divider="@drawable/divider"
        android:orientation="vertical"
        android:padding="15dp"
        android:showDividers="middle">

    </LinearLayout>

</RelativeLayout>
public class Main2Activity extends AppCompatActivity {

    private LinearLayout llContainer;
    LayoutTransition transition;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        llContainer = (LinearLayout) findViewById(R.id.ll_container);
        transition = new LayoutTransition();
        //添加动画
        ObjectAnimator valueAnimator = ObjectAnimator.ofFloat(null, "alpha", 0, 1);
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                //当前展示超过四条,执行删除动画
                if (llContainer.getChildCount() == 4) {
                    handler.sendEmptyMessage(1);
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (llContainer.getChildCount() == 5)
                    //动画执行完毕,删除view
                    handler.sendEmptyMessage(2);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        transition.setAnimator(LayoutTransition.APPEARING, valueAnimator);
        //删除动画
        PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0, 0);
        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(null, new PropertyValuesHolder[]{alpha}).setDuration(transition.getDuration(LayoutTransition.DISAPPEARING));

        transition.setAnimator(LayoutTransition.DISAPPEARING, objectAnimator);
        llContainer.setLayoutTransition(transition);
    }

    private String[] texts = new String[]{
            "火来我在灰烬中等你",
            "我对这个世界没什么可说的。我对这个世界没什么可说的。我对这个世界没什么可说的。",
            "侠之大者,为国为民。",
            "为往圣而继绝学"};
   

    Pools.SimplePool<TextView> textViewPool = new Pools.SimplePool<>(texts.length);

    private TextView obtainTextView() {
        TextView textView = textViewPool.acquire();
        if (textView == null) {
            textView = new TextView(Main2Activity.this);
            textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            textView.setPadding(dp2px(10), dp2px(5), dp2px(10), dp2px(5));
            textView.setTextColor(0xffffffff);
            textView.setMaxLines(1);
            textView.setEllipsize(TextUtils.TruncateAt.END);
            textView.setGravity(Gravity.CENTER);
            textView.setTextSize(15);
            textView.setTextColor(0xffffffff);
            Drawable drawable = getResources().getDrawable(R.mipmap.circle_head);
            drawable.setBounds(0, 0, 80, 80);
            textView.setCompoundDrawablesRelative(drawable, null, null, null);
            textView.setCompoundDrawablePadding(10);
            switch (index) {
                case 0:
                    textView.setBackgroundDrawable(ContextCompat.getDrawable(Main2Activity.this, R.drawable.rect_black));
                    break;
                case 1:
                    textView.setBackgroundDrawable(ContextCompat.getDrawable(Main2Activity.this, R.drawable.rect_blue));

                    break;
                case 2:
                    textView.setBackgroundDrawable(ContextCompat.getDrawable(Main2Activity.this, R.drawable.rect_green));

                    break;
                case 3:
                    textView.setBackgroundDrawable(ContextCompat.getDrawable(Main2Activity.this, R.drawable.rect_red));

                    break;
            }
        }
        textView.setText(texts[index]);
        return textView;
    }

    private int dp2px(float dp) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        this.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics);
    }


    int index = 0;
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @SuppressLint("ResourceAsColor")
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    TextView textView = obtainTextView();
                    llContainer.addView(textView);
                    sendEmptyMessageDelayed(0, 2000);
                    index++;
                    if (index == 4) {
                        index = 0;
                    }
                    break;
                case 1:
                    //给展示的第一个view增加渐变透明动画
                    llContainer.getChildAt(0).animate().alpha(0).setDuration(transition.getDuration(LayoutTransition.APPEARING)).start();
                    break;
                case 2:
                    //删除顶部view
                    llContainer.removeViewAt(0);
                    break;
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        handler.sendEmptyMessage(0);
    }

    @Override
    protected void onPause() {
        super.onPause();
        handler.removeMessages(0);
    }
}

The renderings

 

Published 57 original articles · won praise 26 · views 40000 +

Guess you like

Origin blog.csdn.net/Ever69/article/details/105105243