xamarin.android 给View控件 添加数字提醒效果-BadgeView

本文代码从java项目移植到.net项目   java开源项目:https://github.com/jgilfelt/android-viewbadger

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Graphics;

using Java.Lang;
using Android.Util;
using Android.Content.Res;
using Android.Views.Animations;
using Android.Graphics.Drawables;
using Android.Graphics.Drawables.Shapes;
using static Android.Resource;
using static Android.App.ActionBar;

namespace Dorid.UI
{
    public class BadgeView : TextView
    {
        public const int POSITION_TOP_LEFT = 1;
        public const int POSITION_TOP_RIGHT = 2;
        public const int POSITION_BOTTOM_LEFT = 3;
        public const int POSITION_BOTTOM_RIGHT = 4;
        public const int POSITION_CENTER = 5;

        private const int DEFAULT_MARGIN_DIP = 5;
        private const int DEFAULT_LR_PADDING_DIP = 5;
        private const int DEFAULT_CORNER_RADIUS_DIP = 8;
        private const int DEFAULT_POSITION = POSITION_TOP_RIGHT;
        private static Android.Graphics.Color DEFAULT_BADGE_COLOR = Android.Graphics.Color.ParseColor("#CCFF0000"); //Color.RED;
        private static Android.Graphics.Color DEFAULT_TEXT_COLOR = Android.Graphics.Color.White;

        private static Android.Views.Animations.Animation fadeIn;
        private static Android.Views.Animations.Animation fadeOut;

        private Context context;
        private View target;

        private int badgePosition;
        private int badgeMarginH;
        private int badgeMarginV;
        private Android.Graphics.Color badgeColor;

        private bool isShown;

        private ShapeDrawable badgeBg;

        private int targetTabIndex;

        public BadgeView(Context context):this(context,(IAttributeSet)null, Android.Resource.Attribute.TextViewStyle)
        {
            
        }

        public BadgeView(Context context, IAttributeSet attrs) : this(context, attrs, Android.Resource.Attribute.TextViewStyle)
        {
            
        }

        /**
         * Constructor -
         * 
         * create a new BadgeView instance attached to a target {@link android.view.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.Resource.Attribute.TextViewStyle,target,0)
        {
            
        }

        /**
         * Constructor -
         * 
         * create a new BadgeView instance attached to a target {@link android.widget.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.Resource.Attribute.TextViewStyle,target,index)
        {
            
        }

        public BadgeView(Context context, IAttributeSet attrs, int defStyle):this(context,attrs,defStyle,null,0)
        {
            
        }

        public BadgeView(Context context, IAttributeSet attrs, int defStyle, View target, int tabIndex):base(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;


            Typeface = Typeface.DefaultBold;
            int paddingPixels = DipToPixels(DEFAULT_LR_PADDING_DIP);

            SetPadding(paddingPixels, 0, paddingPixels, 0);
            SetTextColor(DEFAULT_TEXT_COLOR);

            fadeIn = new AlphaAnimation(0, 1);
            fadeIn.Interpolator = new DecelerateInterpolator();
            fadeIn.Duration = 200;

            fadeOut = new AlphaAnimation(1, 0);
            fadeOut.Interpolator = new DecelerateInterpolator();
            fadeOut.Duration = 200;

            isShown = false;

            if (this.target != null)
            {
                ApplyTo(this.target);
            }
            else
            {
                Show();
            }

        }

        private void ApplyTo(View target)
        {

            ViewGroup.LayoutParams lp = target.LayoutParameters;
            IViewParent parent = target.Parent;
            FrameLayout container = new FrameLayout(context);

            if (target is TabWidget) {

                // set target to the relevant tab child container
                target = ((TabWidget)target).GetChildTabViewAt(targetTabIndex);
                this.target = target;

                ((ViewGroup)target).AddView(container,
                        new LayoutParams(LayoutParams.FillParent, LayoutParams.FillParent));

                this.Visibility= ViewStates.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.Visibility= ViewStates.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(bool 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(Android.Views.Animations.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(bool 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(Android.Views.Animations.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(bool 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(Android.Views.Animations.Animation animIn, Android.Views.Animations.Animation animOut)
        {
            Toggle(true, animIn, animOut);
        }

        private void Show(bool animate, Android.Views.Animations.Animation anim)
        {
            
            if (Background == null)
            {
                if (badgeBg == null)
                {
                    badgeBg = getDefaultBackground();
                }
                
                SetBackgroundDrawable(badgeBg);
            }
            ApplyLayoutParams();

            if (animate)
            {
                this.StartAnimation(anim);
            }
            this.Visibility = ViewStates.Visible;
            isShown = true;
        }

        private void Hide(bool animate, Android.Views.Animations.Animation anim)
        {
            this.Visibility = ViewStates.Gone;
            if (animate)
            {
                this.StartAnimation(anim);
            }
            isShown = false;
        }

        private void Toggle(bool animate, Android.Views.Animations.Animation animIn, Android.Views.Animations.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)
        {
            var txt = Text;
            int i;
            if (txt != null)
            {
                try
                {
                    i = Convert.ToInt32(txt.ToString());
                }
                catch (NumberFormatException e)
                {
                    i = 0;
                }
            }
            else
            {
                i = 0;
            }
            i = i + offset;
            //Text = 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.Paint.Color = badgeColor;

            return drawable;

        }

        private void ApplyLayoutParams()
        {

            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);

            switch (badgePosition)
            {
                case POSITION_TOP_LEFT:
                    lp.Gravity = GravityFlags.Left | GravityFlags.Top;
                    lp.SetMargins(badgeMarginH, badgeMarginV, 0, 0);
                    break;
                case POSITION_TOP_RIGHT:
                    lp.Gravity = GravityFlags.Right | GravityFlags.Top;
                    lp.SetMargins(0, badgeMarginV, badgeMarginH, 0);
                    break;
                case POSITION_BOTTOM_LEFT:
                    lp.Gravity = GravityFlags.Left | GravityFlags.Bottom;
                    lp.SetMargins(badgeMarginH, 0, 0, badgeMarginV);
                    break;
                case POSITION_BOTTOM_RIGHT:
                    lp.Gravity = GravityFlags.Right | GravityFlags.Bottom;
                    lp.SetMargins(0, 0, badgeMarginH, badgeMarginV);
                    break;
                case POSITION_CENTER:
                    lp.Gravity = GravityFlags.Center;
                    lp.SetMargins(0, 0, 0, 0);
                    break;
                default:
                    break;
            }

            LayoutParameters = lp;
        }

        /**
         * Returns the target View this badge has been attached to.
         * 
         */
        public View GetTarget()
        {
            return target;
        }

        /**
         * Is this badge currently visible in the UI?
         * 
         */
        public override bool IsShown
        {
            get
            {
                return isShown;
            }
        }

        /**
         * Returns the positioning of this badge.
         * 
         * 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(Android.Graphics.Color badgeColor)
        {
            this.badgeColor = badgeColor;
            badgeBg = getDefaultBackground();
        }

        private int DipToPixels(int dip)
        {
            Resources r =Resources;
            float px = TypedValue.ApplyDimension(ComplexUnitType.Dip, dip, r.DisplayMetrics);
            return (int)px;
        }
    }
}

 

使用方法:

    [Activity(Label = "BadgeActivity", MainLauncher = true)]
    public class BadgeActivity : Activity
    {
        private ZsCMS.Dorid.UI.BadgeView bv;
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.Badge);

            View buttion= FindViewById(Resource.Id.button1);
            bv = new UI.BadgeView(this, buttion);
            bv.Text = "600";
            bv.Show();

            buttion.Click += Buttion_Click;
            // Create your application here
        }

        private int i = 0;
        private void Buttion_Click(object sender, EventArgs e)
        {
            bv.Text = (++i).ToString();
        }
    }

 

posted @ 2016-06-15 17:19 mycing 阅读(...) 评论(...) 编辑 收藏