Создание настраиваемого представления «значок» с индикатором количества уведомлений - PullRequest
0 голосов
/ 28 января 2019

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

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

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

РедактироватьЯ прошу прощения за широкий вопрос, но я отчаялся за последние несколько дней, я надеюсь, что он не слишком широкий и все еще соответствует правилам.

1 Ответ

0 голосов
/ 28 января 2019

Вы можете создать свой собственный пользовательский вид с пользовательским XML-макетом и сгенерировать растровое изображение для макета во время выполнения.Макет может быть таким, как показано ниже:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

    <ImageView android:layout_width="96dp"
               android:layout_height="96dp"
               android:src="@drawable/ic_message" app:layout_constraintEnd_toEndOf="parent"
               android:layout_marginEnd="8dp" app:layout_constraintStart_toStartOf="parent"
               android:layout_marginStart="8dp" android:layout_marginTop="8dp"
               app:layout_constraintTop_toTopOf="parent" android:layout_marginBottom="8dp"
               app:layout_constraintBottom_toBottomOf="parent" android:id="@+id/imageView"/>
    <TextView
            android:id="@+id/tvCounter"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="@+id/imageView"
            tools:text="1"
            android:textSize="16sp"
            android:textStyle="bold" app:layout_constraintStart_toStartOf="@+id/imageView"
            app:layout_constraintEnd_toEndOf="@+id/imageView" app:layout_constraintHorizontal_bias="0.9"
            app:layout_constraintBottom_toBottomOf="@+id/imageView" app:layout_constraintVertical_bias="0.100000024"
            android:textColor="@android:color/white"/>

</android.support.constraint.ConstraintLayout>

Затем создайте пользовательское представление, расширяющее ConstraintLayout.В этом представлении определите метод «init» для раздувания вашего пользовательского макета, как показано ниже, где custom_counter_layout - это имя макета, созданного вами с помощью xml:

 private void init() {
        inflate(getContext(), R.layout.custom_counter_layout, this);
        this.tvCounter = findViewById(R.id.tvCounter);
    }

На данный момент вы можете вызвать этот «init»метод в конструкторе CustomView, что-то вроде:

 public CustomCounterLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomCounterLayout(Context context) {
        super(context);
        init();
    }

    public CustomCounterLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

Затем определите метод "getBitmap ()", который генерирует растровое изображение из макета представления:

public Bitmap getBitmap(){
        DisplayMetrics displayMetrics = new DisplayMetrics();
        ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

        measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
        layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
        buildDrawingCache();
        Bitmap bitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmap);
        draw(canvas);
        //return the bitmap
        return bitmap;
    }

Кроме того, определитетакже удобный метод "setTvCounter" для установки номера для внешнего вида:

  public void setTvCounter(int counter) {
        tvCounter.setText(String.valueOf(counter));
    }

Это должен быть класс CustomCounterLayout, когда вы закончите:

package com.ngallazzi.stacktests;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.support.constraint.ConstraintLayout;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.TextView;

/**
 * StackTests
 * Created by Nicola on 1/28/2019.
 * Copyright © 2019 Zehus. All rights reserved.
 */
public class CustomCounterLayout extends ConstraintLayout {
    private TextView tvCounter;

    public CustomCounterLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomCounterLayout(Context context) {
        super(context);
        init();
    }

    public CustomCounterLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        inflate(getContext(), R.layout.custom_counter_layout, this);
        this.tvCounter = findViewById(R.id.tvCounter);
    }

    public Bitmap getBitmap(){
        DisplayMetrics displayMetrics = new DisplayMetrics();
        ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

        measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
        layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
        buildDrawingCache();
        Bitmap bitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmap);
        draw(canvas);
        //return the bitmap
        return bitmap;
    }

    public void setTvCounter(int counter) {
        tvCounter.setText(String.valueOf(counter));
    }
}

ВЧтобы настроить макет с правильным количеством элементов, используйте настраиваемое представление в макете своей деятельности, а затем используйте метод setTvCounter для обновления настраиваемого представления.Как только вы это сделаете, используйте метод getBitmap (), чтобы сгенерировать чертеж, который вы привязаете к макету вашего навигационного ящика.

...