当前位置:网站首页>Customize VIEW to realize in-app message reminder to rotate up and down

Customize VIEW to realize in-app message reminder to rotate up and down

2022-08-09 13:15:00 Xie Dong _

Post this picture to the title,Trust me not to explain what was shared today,Everyone already knows that,Next, I will explain it to you with the code,This message rotates automaticallyVIEW的具体实现方式.

需求分析:

1.在ITEMAfter sliding out with a message,The next message slides in automatically.

2.The message carousel can be looped

3.ITEM上绑定点击事件,点击对应的ITEM,TOASTcorresponding message content.

实现分析:

自定义VIEW继承自FrameLayout,利用AnimationThe animation gives two messages that are rotated before and afterITEMOne performs slide-in、The other executes the slide out,然后,利用FrameLayout的bringChildToFront(待播放的VIEW),Loop lets be rotatedITEMlocated in all subVIEW之前.

1.准备消息ITEM

   Item分析:Left is specificIMG标签,In the middle is the specific content of the message prompt,More arrows are indicated on the right. 根据分析,Item上,左边Img标签,中间      Text content is variable,The right arrow remains unchanged,抽取Item实体类如下:

  MessageEntity:


/**
 * desc :消息实体
 * author:xiedong
 * data:2018/7/20
 */
public class MessageEntity {
    private String message;
    private int imgRes;


    public MessageEntity(int imgRes, String message) {
        this.message = message;
        this.imgRes = imgRes;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getImgRes() {
        return imgRes;
    }

    public void setImgRes(int imgRes) {
        this.imgRes = imgRes;
    }
}

2.Item实现:

由于整个Item内容比较单一,我采用TextView实现,Left and right icons are usedsetCompoundDrawables()实现

 tipView.setCompoundDrawables(loadDrawable(tip.getImgRes()), null, loadDrawable(R.drawable.ic_more), null);

3.准备Item

Itemslide in、滑出动画,The message currently visible to the user performs a bottom-up slide animation,The message to be slid in performs the animation of sliding in from bottom to top,After being swiped in and visible to the user,Perform a slide out animation,The next one continues the slide-in animation,Become visible message and continue to slide out,Wait for the next one to slide in........

3.1Update the current message and perform the animation

    private void updateTipAndPlayAnimation() {
        if (curTipIndex % 2 == 0) {
            updateTip(tv_tip_out);
            tv_tip_in.startAnimation(anim_out);
            tv_tip_out.startAnimation(anim_in);
            this.bringChildToFront(tv_tip_in);
        } else {
            updateTip(tv_tip_in);
            tv_tip_out.startAnimation(anim_out);
            tv_tip_in.startAnimation(anim_in);
            this.bringChildToFront(tv_tip_out);
        }
    }

    private void updateTip(TextView tipView) {
        final MessageEntity tip = getNextTip();
        tipView.setCompoundDrawables(loadDrawable(tip.getImgRes()), null, loadDrawable(R.drawable.ic_more), null);
        if (!TextUtils.isEmpty(tip.getMessage())) {
            tipView.setText(tip.getMessage());
            tipView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    onItemClickListener.onClick(tip.getMessage());
                }
            });
        }
    }

3.2Get the next message to be rotated from the collection

    private MessageEntity getNextTip() {
        if (isListEmpty(tipList)) return null;
        return tipList.get(curTipIndex++ % tipList.size());
    }

3.3The specific creation process of animation

    private Animation newAnimation(float fromYValue, float toYValue) {
        Animation anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
                Animation.RELATIVE_TO_SELF, fromYValue, Animation.RELATIVE_TO_SELF, toYValue);
        anim.setDuration(ANIM_DURATION);
        anim.setStartOffset(ANIM_DELAYED_MILLIONS);
        anim.setInterpolator(new DecelerateInterpolator());
        return anim;
    }

消息轮播VIEWThe core realization idea is as above,主要是结合Animation动画配合FrameLayout的特性实现ViewThe slide in slide out effect,The above analysis I posted is part of the core implementation code,I paste the complete code below,You can expand by yourself according to specific business scenarios.

轮播View代码:


/**
 * desc :自定义viewRealize up and down rotationview(Client message carousel effect)
 * author:xiedong
 * data:2018/7/20
 */
public class LooperMessageView extends FrameLayout {
    private List<MessageEntity> tipList;
    private int curTipIndex = 0;
    private long lastTimeMillis;
    private static final int ANIM_DELAYED_MILLIONS = 3 * 1000;
    /**
     * 动画持续时长
     */
    private static final int ANIM_DURATION = 1 * 1000;
    private static final String DEFAULT_TEXT_COLOR = "#2F4F4F";
    private static final int DEFAULT_TEXT_SIZE = 16;
    private TextView tv_tip_out, tv_tip_in;
    private Animation anim_out, anim_in;
    private OnItemClickListener onItemClickListener;

    public LooperMessageView(Context context) {
        this(context, null);
    }

    public LooperMessageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LooperMessageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initTipFrame();
        initAnimation();
    }

    private void initTipFrame() {
        tv_tip_out = newTextView();
        tv_tip_in = newTextView();
        addView(tv_tip_in);
        addView(tv_tip_out);
    }

    private TextView newTextView() {
        TextView textView = new TextView(getContext());
        LayoutParams lp = new LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, Gravity.CENTER_VERTICAL);
        textView.setLayoutParams(lp);
        textView.setCompoundDrawablePadding(10);
        textView.setGravity(Gravity.CENTER_VERTICAL);
        textView.setLines(2);
        textView.setEllipsize(TextUtils.TruncateAt.END);
        textView.setTextColor(Color.parseColor(DEFAULT_TEXT_COLOR));
        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, DEFAULT_TEXT_SIZE);
        return textView;
    }

    /**
     * Convert the resource image to Drawable对象
     *
     * @param ResId
     * @return
     */
    private Drawable loadDrawable(int ResId) {
        Drawable drawable = getResources().getDrawable(ResId);
        drawable.setBounds(0, 0, drawable.getMinimumWidth() / 4, drawable.getMinimumHeight() / 4);
        return drawable;
    }

    private void initAnimation() {
        anim_out = newAnimation(0, -1);
        anim_in = newAnimation(1, 0);
        anim_in.setAnimationListener(new Animation.AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                updateTipAndPlayAnimationWithCheck();
            }
        });
    }

    private Animation newAnimation(float fromYValue, float toYValue) {
        Animation anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
                Animation.RELATIVE_TO_SELF, fromYValue, Animation.RELATIVE_TO_SELF, toYValue);
        anim.setDuration(ANIM_DURATION);
        anim.setStartOffset(ANIM_DELAYED_MILLIONS);
        anim.setInterpolator(new DecelerateInterpolator());
        return anim;
    }

    private void updateTipAndPlayAnimationWithCheck() {
        if (System.currentTimeMillis() - lastTimeMillis < 1000) {
            return;
        }
        lastTimeMillis = System.currentTimeMillis();
        updateTipAndPlayAnimation();
    }

    private void updateTipAndPlayAnimation() {
        if (curTipIndex % 2 == 0) {
            updateTip(tv_tip_out);
            tv_tip_in.startAnimation(anim_out);
            tv_tip_out.startAnimation(anim_in);
            this.bringChildToFront(tv_tip_in);
        } else {
            updateTip(tv_tip_in);
            tv_tip_out.startAnimation(anim_out);
            tv_tip_in.startAnimation(anim_in);
            this.bringChildToFront(tv_tip_out);
        }
    }

    private void updateTip(TextView tipView) {
        final MessageEntity tip = getNextTip();
        tipView.setCompoundDrawables(loadDrawable(tip.getImgRes()), null, loadDrawable(R.drawable.ic_more), null);
        if (!TextUtils.isEmpty(tip.getMessage())) {
            tipView.setText(tip.getMessage());
            tipView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    onItemClickListener.onClick(tip.getMessage());
                }
            });
        }
    }

    /**
     * 获取下一条消息
     *
     * @return
     */
    private MessageEntity getNextTip() {
        if (isListEmpty(tipList)) return null;
        return tipList.get(curTipIndex++ % tipList.size());
    }

    public static boolean isListEmpty(List list) {
        return list == null || list.isEmpty();
    }

    public void setTipList(List<MessageEntity> tipList) {
        this.tipList = tipList;
        curTipIndex = 0;
        updateTip(tv_tip_out);
        updateTipAndPlayAnimation();
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    interface OnItemClickListener {
        void onClick(String message);
    }
}

在布局中引入:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#e2e2e1"
    tools:context=".MainActivity">

    <com.zhuandian.loopermessageview.LooperMessageView
        android:id="@+id/lmv_news"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:padding="10dp"
        android:layout_marginTop="10px"
        android:background="#fff" />

</android.support.constraint.ConstraintLayout>

在Activity中,Binds a collection of messages to be rotated:


public class MainActivity extends AppCompatActivity {

    private LooperMessageView messageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        messageView = (LooperMessageView) findViewById(R.id.lmv_news);
        messageView.setTipList(generateTips());
        messageView.setOnItemClickListener(new LooperMessageView.OnItemClickListener() {
            @Override
            public void onClick(String message) {
                Toast.makeText(MainActivity.this, "About to jump to  " + message, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private List<MessageEntity> generateTips() {
        List<MessageEntity> tips = new ArrayList<>();
        tips.add(new MessageEntity(R.drawable.ic_friends, "There is a little friend Aite you"));
        tips.add(new MessageEntity(R.drawable.ic_friend_b, "Someone in the community has sent you a private message"));
        return tips;
    }
}

项目源码已上传github,欢迎拍砖.自定义viewRealize up and down rotationview(Client message alerts)

原网站

版权声明
本文为[Xie Dong _]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/221/202208091203557475.html