Android给控件添加消息提醒

来源:互联网 发布:eclipse java 贪吃蛇 编辑:程序博客网 时间:2024/05/05 11:41

Android给控件添加消息提醒

一、需求

IM有未读消息提醒或者购物车会有购物数量

二、一般有两种做法

1、传统做法

用一个framelayout布局或者是相对布局,然后使得两个空间重叠,达到右上角提醒的功能

2、自定义控件(今天重点)

自定义控件,要集成textview或者其它控件,然后在实现我们需要的功能就OK了。

三、自定义的实现类

package com.lingling.anwanfei.testan;import android.content.Context;import android.content.res.Resources;import android.graphics.Color;import android.graphics.Typeface;import android.graphics.drawable.ShapeDrawable;import android.graphics.drawable.shapes.RoundRectShape;import android.util.AttributeSet;import android.util.TypedValue;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.view.ViewParent;import android.view.animation.AccelerateInterpolator;import android.view.animation.AlphaAnimation;import android.view.animation.Animation;import android.view.animation.DecelerateInterpolator;import android.widget.FrameLayout;import android.widget.TabWidget;import android.widget.TextView;

/**
* 作者:
* 时间: 2017/7/9
* 邮箱:
* QQ:546513287
*/

public class BadgeView extends TextView {
/* 位于控件左上角 */
public static final int POSITION_TOP_LEFT = 1;
/* 位于控件右上角 */
public static final int POSITION_TOP_RIGHT = 2;
/* 位于控件右下角 */
public static final int POSITION_BOTTOM_LEFT = 3;
/* 位于控件左下角 */
public static final int POSITION_BOTTOM_RIGHT = 4;
/* 位于控件正中央 */
public static final int POSITION_CENTER = 5;

/* 默认margin */private static final int DEFAULT_MARGIN_DIP = 5;/* 默认左右padding */private static final int DEFAULT_LR_PADDING_DIP = 5;/* 默认添加控件的圆角 */private static final int DEFAULT_CORNER_RADIUS_DIP = 8;/* 默认位置:右上角 */private static final int DEFAULT_POSITION = POSITION_TOP_RIGHT;/* 默认标签的背景色为红色 */private static final int DEFAULT_BADGE_COLOR = Color.parseColor("#CCFF0000");/* 默认标签颜色为白色 */private static final int DEFAULT_TEXT_COLOR = Color.WHITE;/* 动画 */private static Animation fadeIn;private static Animation fadeOut;private Context context;private View target;private int badgePosition;private int badgeMarginH;private int badgeMarginV;private int badgeColor;private boolean isShown;private ShapeDrawable badgeBg;private int targetTabIndex;public BadgeView(Context context) {    this(context, (AttributeSet) null, android.R.attr.textViewStyle);}public BadgeView(Context context, AttributeSet attrs) {    this(context, attrs, android.R.attr.textViewStyle);}/** * Constructor - * <p> * create a new BadgeView instance attached to a target {@link View}. * * @param context context for this view. * @param target  the View to attach the badge to. */public BadgeView(Context context, View target) {    this(context, null, android.R.attr.textViewStyle, target, 0);}/** * Constructor - * <p> * create a new BadgeView instance attached to a target {@link TabWidget} * tab at a given index. * * @param context context for this view. * @param target  the TabWidget to attach the badge to. * @param index   the position of the tab within the target. */public BadgeView(Context context, TabWidget target, int index) {    this(context, null, android.R.attr.textViewStyle, target, index);}public BadgeView(Context context, AttributeSet attrs, int defStyle) {    this(context, attrs, defStyle, null, 0);}public BadgeView(Context context, AttributeSet attrs, int defStyle, View target, int tabIndex) {    super(context, attrs, defStyle);    init(context, target, tabIndex);}private void init(Context context, View target, int tabIndex) {    this.context = context;    this.target = target;    this.targetTabIndex = tabIndex;    // apply defaults    badgePosition = DEFAULT_POSITION;    badgeMarginH = dipToPixels(DEFAULT_MARGIN_DIP);    badgeMarginV = badgeMarginH;    badgeColor = DEFAULT_BADGE_COLOR;    setTypeface(Typeface.DEFAULT_BOLD);    int paddingPixels = dipToPixels(DEFAULT_LR_PADDING_DIP);    setPadding(paddingPixels, 0, paddingPixels, 0);    setTextColor(DEFAULT_TEXT_COLOR);    fadeIn = new AlphaAnimation(0, 1);    fadeIn.setInterpolator(new DecelerateInterpolator());    fadeIn.setDuration(200);    fadeOut = new AlphaAnimation(1, 0);    fadeOut.setInterpolator(new AccelerateInterpolator());    fadeOut.setDuration(200);    isShown = false;    if (this.target != null) {        applyTo(this.target);    } else {        show();    }}private void applyTo(View target) {    ViewGroup.LayoutParams lp = target.getLayoutParams();    ViewParent parent = target.getParent();    FrameLayout container = new FrameLayout(context);    if (target instanceof TabWidget) {        // set target to the relevant tab child container        target = ((TabWidget) target).getChildTabViewAt(targetTabIndex);        this.target = target;        ((ViewGroup) target).addView(container,                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));        this.setVisibility(View.GONE);        container.addView(this);    } else {        // TODO verify that parent is indeed a ViewGroup        ViewGroup group = (ViewGroup) parent;        int index = group.indexOfChild(target);        group.removeView(target);        group.addView(container, index, lp);        container.addView(target);        this.setVisibility(View.GONE);        container.addView(this);        group.invalidate();    }}/** * Make the badge visible in the UI. */public void show() {    show(false, null);}/** * Make the badge visible in the UI. * * @param animate flag to apply the default fade-in animation. */public void show(boolean animate) {    show(animate, fadeIn);}/** * Make the badge visible in the UI. * * @param anim Animation to apply to the view when made visible. */public void show(Animation anim) {    show(true, anim);}/** * Make the badge non-visible in the UI. */public void hide() {    hide(false, null);}/** * Make the badge non-visible in the UI. * * @param animate flag to apply the default fade-out animation. */public void hide(boolean animate) {    hide(animate, fadeOut);}/** * Make the badge non-visible in the UI. * * @param anim Animation to apply to the view when made non-visible. */public void hide(Animation anim) {    hide(true, anim);}/** * Toggle the badge visibility in the UI. */public void toggle() {    toggle(false, null, null);}/** * Toggle the badge visibility in the UI. * * @param animate flag to apply the default fade-in/out animation. */public void toggle(boolean animate) {    toggle(animate, fadeIn, fadeOut);}/** * Toggle the badge visibility in the UI. * * @param animIn  Animation to apply to the view when made visible. * @param animOut Animation to apply to the view when made non-visible. */public void toggle(Animation animIn, Animation animOut) {    toggle(true, animIn, animOut);}private void show(boolean animate, Animation anim) {    if (getBackground() == null) {        if (badgeBg == null) {            badgeBg = getDefaultBackground();        }        setBackgroundDrawable(badgeBg);    }    applyLayoutParams();    if (animate) {        this.startAnimation(anim);    }    this.setVisibility(View.VISIBLE);    isShown = true;}private void hide(boolean animate, Animation anim) {    this.setVisibility(View.GONE);    if (animate) {        this.startAnimation(anim);    }    isShown = false;}private void toggle(boolean animate, Animation animIn, Animation animOut) {    if (isShown) {        hide(animate && (animOut != null), animOut);    } else {        show(animate && (animIn != null), animIn);    }}/** * Increment the numeric badge label. If the current badge label cannot be converted to * an integer value, its label will be set to "0". * * @param offset the increment offset. */public int increment(int offset) {    CharSequence txt = getText();    int i;    if (txt != null) {        try {            i = Integer.parseInt(txt.toString());        } catch (NumberFormatException e) {            i = 0;        }    } else {        i = 0;    }    i = i + offset;    setText(String.valueOf(i));    return i;}/** * Decrement the numeric badge label. If the current badge label cannot be converted to * an integer value, its label will be set to "0". * * @param offset the decrement offset. */public int decrement(int offset) {    return increment(-offset);}private ShapeDrawable getDefaultBackground() {    int r = dipToPixels(DEFAULT_CORNER_RADIUS_DIP);    float[] outerR = new float[]{r, r, r, r, r, r, r, r};    RoundRectShape rr = new RoundRectShape(outerR, null, null);    ShapeDrawable drawable = new ShapeDrawable(rr);    drawable.getPaint().setColor(badgeColor);    return drawable;}private void applyLayoutParams() {    FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);    switch (badgePosition) {        case POSITION_TOP_LEFT:            lp.gravity = Gravity.LEFT | Gravity.TOP;            lp.setMargins(badgeMarginH, badgeMarginV, 0, 0);            break;        case POSITION_TOP_RIGHT:            lp.gravity = Gravity.RIGHT | Gravity.TOP;            lp.setMargins(0, badgeMarginV, badgeMarginH, 0);            break;        case POSITION_BOTTOM_LEFT:            lp.gravity = Gravity.LEFT | Gravity.BOTTOM;            lp.setMargins(badgeMarginH, 0, 0, badgeMarginV);            break;        case POSITION_BOTTOM_RIGHT:            lp.gravity = Gravity.RIGHT | Gravity.BOTTOM;            lp.setMargins(0, 0, badgeMarginH, badgeMarginV);            break;        case POSITION_CENTER:            lp.gravity = Gravity.CENTER;            lp.setMargins(0, 0, 0, 0);            break;        default:            break;    }    setLayoutParams(lp);}/** * Returns the target View this badge has been attached to. */public View getTarget() {    return target;}/** * Is this badge currently visible in the UI? */@Overridepublic boolean isShown() {    return isShown;}/** * Returns the positioning of this badge. * <p> * one of POSITION_TOP_LEFT, POSITION_TOP_RIGHT, POSITION_BOTTOM_LEFT, POSITION_BOTTOM_RIGHT, POSTION_CENTER. */public int getBadgePosition() {    return badgePosition;}/** * Set the positioning of this badge. * * @param layoutPosition one of POSITION_TOP_LEFT, POSITION_TOP_RIGHT, POSITION_BOTTOM_LEFT, POSITION_BOTTOM_RIGHT, POSTION_CENTER. */public void setBadgePosition(int layoutPosition) {    this.badgePosition = layoutPosition;}/** * Returns the horizontal margin from the target View that is applied to this badge. */public int getHorizontalBadgeMargin() {    return badgeMarginH;}/** * Returns the vertical margin from the target View that is applied to this badge. */public int getVerticalBadgeMargin() {    return badgeMarginV;}/** * Set the horizontal/vertical margin from the target View that is applied to this badge. * * @param badgeMargin the margin in pixels. */public void setBadgeMargin(int badgeMargin) {    this.badgeMarginH = badgeMargin;    this.badgeMarginV = badgeMargin;}/** * Set the horizontal/vertical margin from the target View that is applied to this badge. * * @param horizontal margin in pixels. * @param vertical   margin in pixels. */public void setBadgeMargin(int horizontal, int vertical) {    this.badgeMarginH = horizontal;    this.badgeMarginV = vertical;}/** * Returns the color value of the badge background. */public int getBadgeBackgroundColor() {    return badgeColor;}/** * Set the color value of the badge background. * * @param badgeColor the badge background color. */public void setBadgeBackgroundColor(int badgeColor) {    this.badgeColor = badgeColor;    badgeBg = getDefaultBackground();}private int dipToPixels(int dip) {    Resources r = getResources();    float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, r.getDisplayMetrics());    return (int) px;}    }

四、使用(直接上代码)

package com.lingling.anwanfei.testan;import android.graphics.Color;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.view.animation.Animation;import android.view.animation.ScaleAnimation;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends AppCompatActivity {private TextView textview;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    textview = (TextView) findViewById(R.id.textview);    final BadgeView badgeView = new BadgeView(this, textview);    //设置提示点的位置    badgeView.setBadgePosition(BadgeView.POSITION_TOP_RIGHT);    badgeView.setText("+9");    //显示,不调用此方法,不会显示,同理,也可以隐藏.hide()    badgeView.show();    badgeView.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View view) {            badgeView.hide();            Toast.makeText(MainActivity.this, "消息被干", Toast.LENGTH_SHORT).show();        }    });    //设置背景颜色    badgeView.setBadgeBackgroundColor(Color.RED);    //設置透明度    badgeView.setAlpha(0.9f);    //設置動畫    ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f,            Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);    scaleAnimation.setDuration(200);    badgeView.setAnimation(scaleAnimation);}}
原创粉丝点击