Добавить новое количество элементов к значку на кнопке - Android - PullRequest
80 голосов
/ 16 мая 2011

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

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

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

Portion of top navigation

Ответы [ 5 ]

155 голосов
/ 18 мая 2011

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

Рез / рисуем / 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-значными числами. Если этот эффект нежелателен, попробуйте подход с закругленными прямоугольниками, как показано ниже. С небольшими числами прямоугольник все равно будет выглядеть как круг, когда радиусы сходятся вместе.

Рез / рисуем / 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>

Надеюсь, этого достаточно, чтобы хотя бы указать вам правильное направление!

16 голосов
/ 24 сентября 2014

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

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

enter image description here

9 голосов
/ 23 сентября 2015

Android ViewBadger

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

Добавить .jar файл в папку libs

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

см. Пример на github

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

View target = findViewById(R.id.target_view);
BadgeView badge = new BadgeView(this, target);
badge.setText("1");
badge.show();
3 голосов
/ 18 ноября 2017

Самый простой взлом, придав стиль только 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

1 голос
/ 14 июня 2018

для тех, кто ищет 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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...