Google örneklerinde olduğu gibi bir sayı ile işlem çubuğu bildirim simgesini göstermek için bir android standart rozeti veya yöntemi var mı?
Değilse, bunu yapmanın en iyi yolu nedir?
Android'de yeniyim, lütfen yardım edin.
Google örneklerinde olduğu gibi bir sayı ile işlem çubuğu bildirim simgesini göstermek için bir android standart rozeti veya yöntemi var mı?
Değilse, bunu yapmanın en iyi yolu nedir?
Android'de yeniyim, lütfen yardım edin.
Yanıtlar:
Bunun en iyi çözüm olup olmadığından emin değilim, ama ihtiyacım olan şey bu.
Daha iyi performans veya kalite için neyin değiştirilmesi gerektiğini biliyorsanız lütfen bana bildirin. Benim durumumda bir düğmem var.
Menümdeki özel öğe - main.xml
<item
android:id="@+id/badge"
android:actionLayout="@layout/feed_update_count"
android:icon="@drawable/shape_notification"
android:showAsAction="always">
</item>
Özel şekil çizilebilir (arka plan kare) - 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>
Görünümüm için düzen - 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 - görünümümü ayarlama ve güncelleme
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();
}
MenuItem item = menu.findItem(R.id.badge); MenuItemCompat.setActionView(item, R.layout.feed_update_count); notifCount = (Button) MenuItemCompat.getActionView(item);
android:icon="..."
XML menü öğesindeki öğesine ihtiyacınız yoktur . android:actionLayout="..."
Yeterince var. İçin Button
düzen XML, sen yapabilirsiniz kendiliğinden kapanan etiketi kullanmak <Button ... />
etiket içeriğe sahip olamaz çünkü. <shape>
Etiketi kapatmanız gerekir (tekrar: kendi kendine kapanma). Ve buna ihtiyacınız yok invalidateOptionsMenu()
. Benim için bu işe yaramıyor, çünkü rozet her zaman XML'den şişiriliyor. Yani bütün setNotifCount(...)
işe yaramaz. Sadece setText(...)
rozeti çağır . Ve yayınlayabileceğim getActionView()
için Button
doğrudan.
Düzenle Destek kitaplığının (veya androidx) 26. sürümünden bu yana OnLongClickListener
, araç ipucunu görüntülemek için artık bir özel uygulamanıza gerek yoktur . Basitçe şunu arayın:
TooltipCompat.setTooltipText(menu_hotlist, getString(R.string.hint_show_hot_message));
Birinin böyle bir şey istemesi durumunda kodumu paylaşacağım:
layout / menu / 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>
layout / action_bar_notifitcation_icon.xml
Not stili ve android: tıklanabilir özellikler. bunlar düzeni bir düğme boyutuna getirir ve dokunulduğunda arka planı gri yapar.
<?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>
drawable-xhdpi / ic_bell.png
Her taraftan 10 piksel genişliğinde dolguya sahip 64x64 piksel görüntü. 8 piksel genişliğinde dolgulara sahip olmanız gerekiyor, ancak çoğu varsayılan öğenin bundan biraz daha küçük olduğunu görüyorum. Elbette, farklı yoğunluklar için farklı boyutlar kullanmak isteyeceksiniz.
drawable / rounded_square.xml
Burada, # ff222222 (alpha #ff ile renk # 222222 (tamamen görünür)), Eylem Çubuğumun arka plan rengidir.
<?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>
com / ubergeek42 / WeechatAndroid / WeechatActivity.java
Burada onu tıklanabilir ve güncellenebilir hale getiriyoruz! OnLongClick'te Toast oluşturmayı sağlayan soyut bir dinleyici oluşturdum, kod ActionBarSherlock kaynaklarından alındı .
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;
}
}
app:actionLayout="@layout/action_bar_notifitcation_icon"
bunun yerine koymalısınız . API seviyesi <11 ile uyumlu değil.android:actionLayout="@layout/action_bar_notifitcation_icon"
MenuItemCompat.getActionView
menu.findItem(R.id.menu_hotlist).getActionView();
MenuItem.getActionView
android:actionLayout
:; AppCompat: app:actionLayout
menü öğenizde .
Sadece eklemek için. Birisi dolu bir daire balonu uygulamak isterse, kodu burada (adlandırın 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>
İhtiyacınıza göre kalınlığı ayarlamanız gerekebilir.
DÜZENLEME:
Düğme için düzen şu şekildedir (adlandırın 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>
Menüde öğe oluştur:
<item
android:id="@+id/menu_messages"
android:showAsAction="always"
android:actionLayout="@layout/badge_layout"/>
Gelen onCreateOptionsMenu
Menü öğesine olsun referansı:
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();
}
}
});
Mesajlar için bildirim aldıktan sonra, sayıyı ayarlayın:
itemMessagesBadgeTextView.setText("" + count);
itemMessagesBadgeTextView.setVisibility(View.VISIBLE);
iconButtonMessages.setTextColor(getResources().getColor(R.color.white));
Bu kod, Iconify-fontawesome kullanır .
compile 'com.joanzapata.iconify:android-iconify-fontawesome:2.1.+'
ActionView
Temelli çözümleri sevmiyorum , fikrim şu:
TextView
, TextView
uygulama tarafından doldurulurçizmeniz gerektiğinde MenuItem
:
2.1. düzeni şişirmek
2.2. call measure()
& layout()
(aksi takdirde view
0px x 0px olacaktır, çoğu kullanım durumu için çok küçüktür)
2.3. TextView
metnini ayarla
2.4. görünümün "ekran görüntüsünü" yapın
2.6. setin MenuItem
simgesi, 2.4'te oluşturulan bitmap tabanlı
kar!
yani sonuç şöyle bir şey olmalı
<?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
bu yeşil TextView
arka plan,
@drawable/ic_menu_gallery
burada gerçekten gerekli değil, sadece IDE'de mizanpajın sonucunu önizlemek için.
onCreateOptionsMenu
/ içine kod ekleonPrepareOptionsMenu
@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;
}
Simge oluşturma yöntemini uygulayın:
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);
}
Kodun tamamı burada: https://github.com/cvoronin/ActionBarMenuItemCounter
Tamam, @AndrewS çözümünün v7 appCompat kitaplığı ile çalışması için :
<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();
}
Kodun geri kalanı aynı.
android:actionLayout
hiç app:actionLayout
bu cazibe gibi workes.
Bu soruların cevaplarına, özellikle de örnek kodu olan ikinci soruya bakmayı deneyin:
Android'de menü öğesinde dinamik değerler nasıl uygulanır?
ActionBar Simgesinde nasıl metin elde edilir?
Gördüğüm kadarıyla, kendi özel ActionView
uygulamanızı oluşturmanız gerekecek . Bir alternatif bir gelenek olabilir Drawable
. Eylem Çubuğu için bildirim sayımının yerel bir uygulaması olmadığını unutmayın.
DÜZENLEME: Kodla aradığınız yanıt: Örnek uygulama ile Özel Bildirim Görünümü
Drawable
olarak, aşağıdaki iki bağlantıda görüldüğü gibi metinleri de yerleştirebilirsiniz : stackoverflow.com/questions/6691818/… ve stackoverflow.com/questions/3972445/…
Drawable
bağlantı gibi bir şey aracılığıyla burada ve daha sonra özel için bir öznitelik yapmak Drawable
tüm animasyonu oluşturmak, böylece üzerine metne sahip XML olarak ve istediğiniz gibi sığdırın. Alternatif olarak, bu çok zorsa, Çekilebilir'i Java'da ekleyebilirsiniz.
Araç çubuğunu kullandığınızda:
....
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);
}
ve yük verisi çağrınızda renewMenu ():
private void refreshMenu() {
comment_count.setVisibility(View.VISIBLE);
comment_count.setText("" + post_data.getComment_count());
}
Burada çok iyi bir çözüm buldum , onu kotlin ile kullanıyorum.
İlk olarak, çekilebilir klasörde şunları oluşturmanız gerekir 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>
Senin içinde Activity_Main
Düzen bazıları gibi:
<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>
Ve aşağıdaki gibi değiştirebilirsiniz:
btnBadge.setOnClickListener { view ->
Snackbar.make(view,"badge click", Snackbar.LENGTH_LONG) .setAction("Action", null).show()
txtBadge.text = "0"
}
Bunu yapmanın daha iyi bir yolunu buldum. bunun gibi bir şey kullanmak istersen
Bu bağımlılığı kullan
compile 'com.nex3z:notification-badge:0.1.0'
çekilebilir bir xml dosyası oluşturun ve Badge.xml olarak kaydedin
<?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>
Şimdi bu rozeti kullanmak istediğiniz her yerde xml'de aşağıdaki kodu kullanın. bunun yardımıyla o rozeti resminizin sağ üst köşesinde veya herhangi bir yerde görebileceksiniz.
<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>
Şimdi nihayet yourFile.java'da bu 2 basit şeyi kullanın .. 1) Tanımlayın
NotificationBadge mBadge;
2) döngünüzün veya bu sayıyı sayan herhangi bir şeyin bunu kullandığı yerde:
mBadge.setNumber(your_LoopCount);
burada mBadge.setNumber(0)
hiçbir şey gösterilmeyecek.
Umarım bu yardımcı olur.