Добавить новое количество элементов в значок на кнопке-Android


Я разработчик. Мне нужно реализовать дизайн, показанный ниже. У меня уже есть функциональное приложение, но интересно, как даже подойти к этому? В частности, меня интересует, как показать количество "новых" элементов под вкладками. То, что я знаю, как это сделать - это создавать новые иконки с красными точками и просто отображать их, когда новые вещи доступны.

но я понятия не имею, как заставить эти круглые круги плавать поверх названия и показывать номер внутри. У кого-нибудь есть предложения о том, что тоже ищут? Образцы? Направления?

второй вопрос о разделении деятельности. Должен ли я сделать контроль, чтобы объединить такие кнопки и просто надуть его на действия? В противном случае я могу создать активность с вкладками, но я не уверен, что ее можно стилизовать, чтобы она выглядела так.

5 75

5 ответов:

сделайте свой значок TextView, что позволяет установить числовое значение на все, что вам нравится, позвонив setText(). Установите фон TextView как XML <shape> drawable, с помощью которого можно создать сплошной или градиентный круг с границей. XML drawable будет масштабироваться в соответствии с представлением, поскольку он изменяет размер с большим или меньшим текстом.

res/drawable / badge_circle.XML-код:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="oval">
  <solid
    android:color="#F00" />
  <stroke
    android:width="2dip"
    android:color="#FFF" />
  <padding
    android:left="5dip"
    android:right="5dip"
    android:top="5dip"
    android:bottom="5dip" />
</shape>

вы должны будете взглянуть на то, как овал / круг масштабируется с большим 3-4 цифры, однако. Если этот эффект нежелателен, попробуйте использовать скругленный прямоугольник, как показано ниже. При малых числах прямоугольник будет по-прежнему выглядеть как круг, поскольку радиусы сходятся вместе.

res/drawable / badge_circle.XML-код:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="rectangle">
  <corners
    android:radius="10dip"/>
  <solid
    android:color="#F00" />
  <stroke
    android:width="2dip"
    android:color="#FFF" />
  <padding
    android:left="5dip"
    android:right="5dip"
    android:top="5dip"
    android:bottom="5dip" />
</shape>

при создании масштабируемого фона вы просто добавляете его в фон TextView, например:

<TextView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content" 
  android:text="10"
  android:textColor="#FFF"
  android:textSize="16sp"
  android:textStyle="bold"
  android:background="@drawable/badge_circle"/>

наконец, эти TextView значки можно поместить в вашем плане поверх соответствующие кнопки/вкладки. Я бы, вероятно, сделал это, группируя каждую кнопку с ее значком в RelativeLayout контейнер, вот так:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content">
  <Button
    android:id="@+id/myButton"
    android:layout_width="65dip"
    android:layout_height="65dip"/>
  <TextView
    android:id="@+id/textOne"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@id/myButton"
    android:layout_alignRight="@id/myButton" 
    android:text="10"
    android:textColor="#FFF"
    android:textSize="16sp"
    android:textStyle="bold"
    android:background="@drawable/badge_circle"/>
</RelativeLayout>

надеюсь, что это достаточно информации, чтобы по крайней мере вы указали в правильном направлении!

вместо использования овала, вы можете использовать форму кольца, чтобы нарисовать идеальный заполненный круг.

пожалуйста, смотрите мой ответ здесь.

enter image description here

Android ViewBadger

простой способ "значок" любой данный вид Android во время выполнения без необходимости обслуживать его в макете.

добавить .jar файл в папке libs

Нажмите, чтобы загрузить пример

посмотреть пример на github

простой пример:

View target = findViewById(R.id.target_view);
BadgeView badge = new BadgeView(this, target);
badge.setText("1");
badge.show();

самый простой хак, давая стиль TextView только.

        <TextView
                android:id="@+id/fabCounter"
                style="@style/Widget.Design.FloatingActionButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_centerVertical="true"
                android:layout_marginEnd="10dp"
                android:padding="5dp"
                android:text="10"
                android:textColor="@android:color/black"
                android:textSize="14sp" />

Result

для людей, которые ищут Xamarin Android можно использовать этот код

public class CountDrawable : Drawable
{
    private float mTextSize;
    private Paint mBadgePaint;
    private Paint mTextPaint;
    private Rect mTxtRect = new Rect();

    private String mCount = "";
    private bool mWillDraw = false;


    public CountDrawable(Context context)
    {
        float mTextSize = context.Resources.GetDimension(Resource.Dimension.badge_count_textsize);
        mBadgePaint = new Paint();
        // mBadgePaint.SetCol(ContextCompat.GetColor(context.ApplicationContext, Resource.Color.background_color));
        mBadgePaint.Color = new Color(Color.Red);
        mBadgePaint.AntiAlias = true;
        mBadgePaint.SetStyle(Paint.Style.Fill);

        mTextPaint = new Paint();
        mTextPaint.Color = new Color(Color.White);
        mTextPaint.SetTypeface(Typeface.DefaultBold);
        mTextPaint.TextSize = mTextSize;
        mTextPaint.AntiAlias = true;
        mTextPaint.TextAlign = Paint.Align.Center;
    }


    public override void Draw(Canvas canvas)
    {
        if(!mWillDraw)
        {
            return;
        }



        Rect bounds = GetBounds;
        float width = bounds.Right - bounds.Left;
        float height = bounds.Bottom - bounds.Top;

        float radius = ((Math.Max(width, height) / 2)) / 2;
        float centerX = (width - radius - 1) + 5;
        float centerY = radius - 5;
        if (mCount.Length <= 2)
        {
            // Draw badge circle.
            canvas.DrawCircle(centerX, centerY, (int)(radius + 5.5), mBadgePaint);
        }
        else
        {
            canvas.DrawCircle(centerX, centerY, (int)(radius + 6.5), mBadgePaint);
        }

        mTextPaint.GetTextBounds(mCount, 0, mCount.Length, mTxtRect);
        float textHeight = mTxtRect.Bottom - mTxtRect.Top;
        float textY = centerY + (textHeight / 2f);
        if (mCount.Length > 2)
            canvas.DrawText("99+", centerX, textY, mTextPaint);
        else
            canvas.DrawText(mCount, centerX, textY, mTextPaint);
    }

    public Rect GetBounds { get; set; }


    public void setCount(String count)
    {
        mCount = count;

        // Only draw a badge if there are notifications.
       // mWillDraw = !count.equalsIgnoreCase("0");
        mWillDraw = !string.Equals(count, "0", StringComparison.OrdinalIgnoreCase);
       // invalidateSelf();
    }

    public override void SetAlpha(int alpha)
    {

    }

    public override void SetColorFilter(ColorFilter colorFilter)
    {

    }

    public override int Opacity
    {
        get;
    }

}

и в MainActivity

public override bool OnCreateOptionsMenu(IMenu menu)
    {
        // return base.OnCreateOptionsMenu(menu);
        MenuInflater.Inflate(Resource.Menu.actionmenu, menu);
        // var dd = menu.FindItem(Resource.Id.icon_group);
        IMenuItem item = menu.FindItem(Resource.Id.ic_group);
        LayerDrawable icon = item.Icon as LayerDrawable;

        // LayerDrawable icon = (LayerDrawable)item.Icon;
        CountDrawable badge;
        Drawable reuse = icon.FindDrawableByLayerId(Resource.Id.ic_group_count);
        if (reuse != null && reuse is CountDrawable)
        {
            badge = (CountDrawable)reuse;
        }
        else
        {
            badge = new CountDrawable(this);

        }
        badge.setCount("8");
        badge.GetBounds=icon.Bounds;

        icon.Mutate();
        icon.SetDrawableByLayerId(Resource.Id.ic_group_count, badge);
        return true;
    }