Есть ли стандартный значок или метод Android для отображения значка уведомления панели действий с подсчетом, как на примерах Google?
Если нет, то каков наилучший способ сделать это?
Я новичок в android, помогите.
Есть ли стандартный значок или метод Android для отображения значка уведомления панели действий с подсчетом, как на примерах Google?
Если нет, то каков наилучший способ сделать это?
Я новичок в android, помогите.
Я не уверен, что это лучшее решение или нет, но это то, что мне нужно.
Скажите, пожалуйста, знаете ли вы, что нужно менять для лучшей производительности или качества. В моем случае у меня есть кнопка.
Пользовательский элемент в моем меню - main.xml
<item
android:id="@+id/badge"
android:actionLayout="@layout/feed_update_count"
android:icon="@drawable/shape_notification"
android:showAsAction="always">
</item>
Пользовательская форма для рисования (квадрат фона) - shape_notification.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:color="#22000000" android:width="2dp"/>
<corners android:radius="5dp" />
<solid android:color="#CC0001"/>
</shape>
Макет для моего представления - feed_update_count.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/notif_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="32dp"
android:minHeight="32dp"
android:background="@drawable/shape_notification"
android:text="0"
android:textSize="16sp"
android:textColor="@android:color/white"
android:gravity="center"
android:padding="2dp"
android:singleLine="true">
</Button>
MainActivity - настройка и обновление моего представления
static Button notifCount;
static int mNotifCount = 0;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.main, menu);
View count = menu.findItem(R.id.badge).getActionView();
notifCount = (Button) count.findViewById(R.id.notif_count);
notifCount.setText(String.valueOf(mNotifCount));
return super.onCreateOptionsMenu(menu);
}
private void setNotifCount(int count){
mNotifCount = count;
invalidateOptionsMenu();
}
Редактирование Начиная с версии 26 библиотеки поддержки (или androidx) вам больше не нужно реализовывать пользовательский OnLongClickListener
для отображения всплывающей подсказки. Просто назовите это:
TooltipCompat.setTooltipText(menu_hotlist, getString(R.string.hint_show_hot_message));
Я просто поделюсь своим кодом, если кто-то захочет что-то вроде этого:
Макет/меню/menu_actionbar.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
...
<item android:id="@+id/menu_hotlist"
android:actionLayout="@layout/action_bar_notifitcation_icon"
android:showAsAction="always"
android:icon="@drawable/ic_bell"
android:title="@string/hotlist" />
...
</menu>
макет/action_bar_notifitcation_icon.xml
Примечание стиль и Android: кликабельные свойства. они делают макет размером с кнопку и делают серый фон при касании.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center"
android:layout_gravity="center"
android:clickable="true"
style="@android:style/Widget.ActionButton">
<ImageView
android:id="@+id/hotlist_bell"
android:src="@drawable/ic_bell"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_margin="0dp"
android:contentDescription="bell"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/hotlist_hot"
android:layout_width="wrap_content"
android:minWidth="17sp"
android:textSize="12sp"
android:textColor="#ffffffff"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@null"
android:layout_alignTop="@id/hotlist_bell"
android:layout_alignRight="@id/hotlist_bell"
android:layout_marginRight="0dp"
android:layout_marginTop="3dp"
android:paddingBottom="1dp"
android:paddingRight="4dp"
android:paddingLeft="4dp"
android:background="@drawable/rounded_square"/>
</RelativeLayout>
вытяжка-xhdpi/ic_bell.png
Изображение 64x64 пикселей с отступами шириной 10 пикселей со всех сторон. Предполагается, что у вас есть отступы шириной 8 пикселей, но я считаю, что большинство элементов по умолчанию немного меньше этого. Конечно, вы захотите использовать разные размеры для разных плотностей.
рисуем /rounded_square.xml
Здесь, # ff222222 (цвет # 222222 с альфа #ff (полностью видимым)) является цветом фона моей панели действий.
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="2dp" />
<solid android:color="#ffff0000" />
<stroke android:color="#ff222222" android:width="2dp"/>
</shape>
ком /ubergeek42/WeechatAndroid/WeechatActivity.java
Здесь мы делаем его кликабельным и обновляемым! Я создал абстрактный слушатель, который обеспечивает создание Toast на onLongClick, код был взят из источников ActionBarSherlock.
private int hot_number = 0;
private TextView ui_hot = null;
@Override public boolean onCreateOptionsMenu(final Menu menu) {
MenuInflater menuInflater = getSupportMenuInflater();
menuInflater.inflate(R.menu.menu_actionbar, menu);
final View menu_hotlist = menu.findItem(R.id.menu_hotlist).getActionView();
ui_hot = (TextView) menu_hotlist.findViewById(R.id.hotlist_hot);
updateHotCount(hot_number);
new MyMenuItemStuffListener(menu_hotlist, "Show hot message") {
@Override
public void onClick(View v) {
onHotlistSelected();
}
};
return super.onCreateOptionsMenu(menu);
}
// call the updating code on the main thread,
// so we can call this asynchronously
public void updateHotCount(final int new_hot_number) {
hot_number = new_hot_number;
if (ui_hot == null) return;
runOnUiThread(new Runnable() {
@Override
public void run() {
if (new_hot_number == 0)
ui_hot.setVisibility(View.INVISIBLE);
else {
ui_hot.setVisibility(View.VISIBLE);
ui_hot.setText(Integer.toString(new_hot_number));
}
}
});
}
static abstract class MyMenuItemStuffListener implements View.OnClickListener, View.OnLongClickListener {
private String hint;
private View view;
MyMenuItemStuffListener(View view, String hint) {
this.view = view;
this.hint = hint;
view.setOnClickListener(this);
view.setOnLongClickListener(this);
}
@Override abstract public void onClick(View v);
@Override public boolean onLongClick(View v) {
final int[] screenPos = new int[2];
final Rect displayFrame = new Rect();
view.getLocationOnScreen(screenPos);
view.getWindowVisibleDisplayFrame(displayFrame);
final Context context = view.getContext();
final int width = view.getWidth();
final int height = view.getHeight();
final int midy = screenPos[1] + height / 2;
final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
Toast cheatSheet = Toast.makeText(context, hint, Toast.LENGTH_SHORT);
if (midy < displayFrame.height()) {
cheatSheet.setGravity(Gravity.TOP | Gravity.RIGHT,
screenWidth - screenPos[0] - width / 2, height);
} else {
cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
}
cheatSheet.show();
return true;
}
}
Просто добавьте. Если кто-то хочет реализовать заполненный пузырь круга, то он код (назовите его bage_circle.xml
):
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring"
android:useLevel="false"
android:thickness="9dp"
android:innerRadius="0dp"
>
<solid
android:color="#F00"
/>
<stroke
android:width="1dip"
android:color="#FFF" />
<padding
android:top="2dp"
android:bottom="2dp"/>
</shape>
Возможно, вам придется отрегулировать толщину в соответствии с вашими потребностями.
EDIT:
Здесь макет кнопки (name it badge_layout.xml
):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.joanzapata.iconify.widget.IconButton
android:layout_width="44dp"
android:layout_height="44dp"
android:textSize="24sp"
android:textColor="@color/white"
android:background="@drawable/action_bar_icon_bg"
android:id="@+id/badge_icon_button"/>
<TextView
android:id="@+id/badge_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/badge_icon_button"
android:layout_alignRight="@id/badge_icon_button"
android:layout_alignEnd="@id/badge_icon_button"
android:text="10"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:paddingLeft="8dp"
android:gravity="center"
android:textColor="#FFF"
android:textSize="11sp"
android:background="@drawable/badge_circle"/>
</RelativeLayout>
В меню create item:
<item
android:id="@+id/menu_messages"
android:showAsAction="always"
android:actionLayout="@layout/badge_layout"/>
В onCreateOptionsMenu
получить ссылку на пункт меню:
itemMessages = menu.findItem(R.id.menu_messages);
badgeLayout = (RelativeLayout) itemMessages.getActionView();
itemMessagesBadgeTextView = (TextView) badgeLayout.findViewById(R.id.badge_textView);
itemMessagesBadgeTextView.setVisibility(View.GONE); // initially hidden
iconButtonMessages = (IconButton) badgeLayout.findViewById(R.id.badge_icon_button);
iconButtonMessages.setText("{fa-envelope}");
iconButtonMessages.setTextColor(getResources().getColor(R.color.action_bar_icon_color_disabled));
iconButtonMessages.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (HJSession.getSession().getSessionId() != null) {
Intent intent = new Intent(getThis(), HJActivityMessagesContexts.class);
startActivityForResult(intent, HJRequestCodes.kHJRequestCodeActivityMessages.ordinal());
} else {
showLoginActivity();
}
}
});
После получения уведомлений для сообщений установите счетчик:
itemMessagesBadgeTextView.setText("" + count);
itemMessagesBadgeTextView.setVisibility(View.VISIBLE);
iconButtonMessages.setTextColor(getResources().getColor(R.color.white));
В этом коде используется Iconify-fontawesome.
compile 'com.joanzapata.iconify:android-iconify-fontawesome:2.1.+'
Мне не нравятся решения на основе ActionView
моя идея:
TextView
, который TextView
будет заполнен
приложение когда вам нужно нарисовать a MenuItem
:
2,1. раздувание макета
2,2. вызов measure()
и layout()
(иначе view
будет 0px x 0px, он слишком мал для большинства случаев использования)
2,3. установите текст TextView
2,4. сделать "снимок экрана" вида
2,6. установить значок MenuItem
на основе растрового изображения, созданного на 2.4
прибыль!
поэтому результат должен быть чем-то вроде
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/counterPanel" android:layout_width="32dp" android:layout_height="32dp" android:background="@drawable/ic_menu_gallery"> <RelativeLayout android:id="@+id/counterValuePanel" android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:id="@+id/counterBackground" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/unread_background" /> <TextView android:id="@+id/count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="1" android:textSize="8sp" android:layout_centerInParent="true" android:textColor="#FFFFFF" /> </RelativeLayout> </FrameLayout>
@drawable/unread_background
- это зеленый фон TextView
,
@drawable/ic_menu_gallery
здесь не требуется, это просто для просмотра результата макета в среде IDE.
добавить код в onCreateOptionsMenu
/onPrepareOptionsMenu
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem menuItem = menu.findItem(R.id.testAction);
menuItem.setIcon(buildCounterDrawable(count, R.drawable.ic_menu_gallery));
return true;
}
Реализовать метод build-the-icon:
private Drawable buildCounterDrawable(int count, int backgroundImageId) {
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.counter_menuitem_layout, null);
view.setBackgroundResource(backgroundImageId);
if (count == 0) {
View counterTextPanel = view.findViewById(R.id.counterValuePanel);
counterTextPanel.setVisibility(View.GONE);
} else {
TextView textView = (TextView) view.findViewById(R.id.count);
textView.setText("" + count);
}
view.measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.setDrawingCacheEnabled(true);
view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
return new BitmapDrawable(getResources(), bitmap);
}
Полный код находится здесь: https://github.com/cvoronin/ActionBarMenuItemCounter
Хорошо, для решения @AndrewS для работы с библиотекой v7 appCompat :
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:someNamespace="http://schemas.android.com/apk/res-auto" >
<item
android:id="@+id/saved_badge"
someNamespace:showAsAction="always"
android:icon="@drawable/shape_notification" />
</menu>
.
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.main, menu);
MenuItem item = menu.findItem(R.id.saved_badge);
MenuItemCompat.setActionView(item, R.layout.feed_update_count);
View view = MenuItemCompat.getActionView(item);
notifCount = (Button)view.findViewById(R.id.notif_count);
notifCount.setText(String.valueOf(mNotifCount));
}
private void setNotifCount(int count){
mNotifCount = count;
supportInvalidateOptionsMenu();
}
Остальная часть кода одинаков.
Попробуйте найти ответы на эти вопросы, в частности, второй, который содержит пример кода:
Как реализовать динамические значения в пункте меню в Android
Как получить текст в значке ActionBar?
Из того, что я вижу, вам нужно создать свою собственную реализацию ActionView
. Альтернативой может быть пользовательский Drawable
. Обратите внимание, что, по-видимому, не существует встроенной версии подсчета уведомлений для панели действий.
EDIT: ответ, который вы искали, с кодом: Пользовательский просмотр уведомлений с sample реализация
Когда вы используете панель инструментов:
....
private void InitToolbar() {
toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
toolbartitle = (TextView) findViewById(R.id.titletool);
toolbar.inflateMenu(R.menu.show_post);
toolbar.setOnMenuItemClickListener(this);
Menu menu = toolbar.getMenu();
MenuItem menu_comments = menu.findItem(R.id.action_comments);
MenuItemCompat
.setActionView(menu_comments, R.layout.menu_commentscount);
View v = MenuItemCompat.getActionView(menu_comments);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// Your Action
}
});
comment_count = (TextView) v.findViewById(R.id.count);
}
а в вашем загрузочном сообщении refreshMenu():
private void refreshMenu() {
comment_count.setVisibility(View.VISIBLE);
comment_count.setText("" + post_data.getComment_count());
}
Вместо управления настраиваемой формой и возможностью рисования, почему бы не использовать встроенный механизм Android?
Стиль значка можно использовать в 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" />
Я нашел лучший способ сделать это. если вы хотите использовать что-то вроде этого
Используйте эту зависимость
compile 'com.nex3z:notification-badge:0.1.0'
создайте один XML файл в Drawable и сохраните его как Badge.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="#66000000"/>
<size android:width="30dp" android:height="40dp"/>
</shape>
</item>
<item android:bottom="1dp" android:right="0.6dp">
<shape android:shape="oval">
<solid android:color="@color/Error_color"/>
<size android:width="20dp" android:height="20dp"/>
</shape>
</item>
</layer-list>
Теперь везде, где вы хотите использовать этот значок, используйте следующий код в XML. с помощью этого вы сможете увидеть этот значок в правом верхнем углу вашего изображения или что-нибудь еще.
<com.nex3z.notificationbadge.NotificationBadge
android:id="@+id/badge"
android:layout_toRightOf="@id/Your_ICON/IMAGE"
android:layout_alignTop="@id/Your_ICON/IMAGE"
android:layout_marginLeft="-16dp"
android:layout_marginTop="-8dp"
android:layout_width="28dp"
android:layout_height="28dp"
app:badgeBackground="@drawable/Badge"
app:maxTextLength="2"
></com.nex3z.notificationbadge.NotificationBadge>
Теперь, наконец, на yourFile.java используйте эту 2 простую вещь.. 1) Определите
NotificationBadge mBadge;
2) где ваш цикл или все, что считает это число, использует это:
mBadge.setNumber(your_LoopCount);
здесь mBadge.setNumber(0)
ничего не показывает.
Надеюсь, это поможет.
Я нашел очень хорошее решение здесь, я использую его с kotlin.
Сначала в папке item_count.xml
вы должны создать item_count.xml
:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="8dp" />
<solid android:color="#f20000" />
<stroke
android:width="2dip"
android:color="#FFF" />
<padding
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp" />
</shape>
В вашем Макете Activity_Main
некоторые похожи:
<RelativeLayout
android:id="@+id/badgeLayout"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_toRightOf="@+id/badge_layout1"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="5dp">
<RelativeLayout
android:id="@+id/relative_layout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/btnBadge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/ic_notification" />
</RelativeLayout>
<TextView
android:id="@+id/txtBadge"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_alignRight="@id/relative_layout1"
android:background="@drawable/item_count"
android:text="22"
android:textColor="#FFF"
android:textSize="7sp"
android:textStyle="bold"
android:gravity="center"/>
</RelativeLayout>
И вы можете изменить как:
btnBadge.setOnClickListener { view ->
Snackbar.make(view,"badge click", Snackbar.LENGTH_LONG) .setAction("Action", null).show()
txtBadge.text = "0"
}