Apakah ada lencana atau metode standar android untuk menampilkan ikon pemberitahuan bilah tindakan dengan jumlah seperti pada contoh Google?
Jika tidak, lalu apa cara terbaik untuk membuatnya?
Saya baru mengenal android, tolong bantu.
Apakah ada lencana atau metode standar android untuk menampilkan ikon pemberitahuan bilah tindakan dengan jumlah seperti pada contoh Google?
Jika tidak, lalu apa cara terbaik untuk membuatnya?
Saya baru mengenal android, tolong bantu.
Jawaban:
Saya tidak yakin apakah ini solusi terbaik atau tidak, tetapi itulah yang saya butuhkan.
Tolong beritahu saya jika Anda tahu apa yang perlu diubah untuk kinerja atau kualitas yang lebih baik. Dalam kasus saya, saya punya tombol.
Item khusus pada menu saya - main.xml
<item
android:id="@+id/badge"
android:actionLayout="@layout/feed_update_count"
android:icon="@drawable/shape_notification"
android:showAsAction="always">
</item>
Drawable bentuk kustom (latar belakang persegi) - 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>
Layout untuk tampilan saya - 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 - mengatur dan memperbarui pandangan saya
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="..."
dalam item menu XML. Sudah android:actionLayout="..."
cukup, di sana. Untuk Button
dalam tata letak XML, Anda dapat menggunakan tag penutup sendiri <Button ... />
karena tag tidak dapat memiliki konten. Anda harus menutup <shape>
tag (sekali lagi: menutup sendiri). Dan Anda tidak membutuhkannya invalidateOptionsMenu()
. Bagi saya, itu bahkan tidak berhasil, karena lencana selalu meningkat dari XML lagi. Jadi, keseluruhannya setNotifCount(...)
tidak berguna. Panggil saja setText(...)
lencananya. Dan Anda dapat getActionView()
memilih Button
langsung.
Edit Sejak versi 26 dari perpustakaan dukungan (atau androidx) Anda tidak perlu lagi menerapkan kebiasaan OnLongClickListener
untuk menampilkan tooltip. Cukup panggil ini:
TooltipCompat.setTooltipText(menu_hotlist, getString(R.string.hint_show_hot_message));
Saya hanya akan membagikan kode saya jika seseorang menginginkan sesuatu seperti ini:
tata letak / 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
Perhatikan gaya dan android: properti yang dapat diklik . ini membuat tata letak ukuran tombol dan membuat latar belakang abu-abu saat disentuh.
<?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
Gambar 64x64 piksel dengan bantalan lebar 10 piksel dari semua sisi. Anda seharusnya memiliki bantalan lebar 8 piksel, tetapi saya menemukan sebagian besar item bawaan sedikit lebih kecil dari itu. Tentu saja, Anda ingin menggunakan ukuran yang berbeda untuk kepadatan yang berbeda.
drawable / rounded_square.xml
Di sini, # ff222222 (warna # 222222 dengan alpha #ff (sepenuhnya terlihat)) adalah warna latar belakang dari Bilah Tindakan saya.
<?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
Di sini kita membuatnya dapat diklik dan diupdate! Saya membuat pendengar abstrak yang menyediakan pembuatan Toast di onLongClick, kode itu diambil dari sumber 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;
}
}
app:actionLayout="@layout/action_bar_notifitcation_icon"
alih-alih android:actionLayout="@layout/action_bar_notifitcation_icon"
jika Anda menggunakan MenuItemCompat.getActionView
alih-alih menu.findItem(R.id.menu_hotlist).getActionView();
untuk masalah kompatibilitas. MenuItem.getActionView
tidak kompatibel dengan level API <11.
android:actionLayout
; AppCompat: app:actionLayout
di item menu Anda.
Hanya untuk menambahkan. Jika seseorang ingin menerapkan gelembung lingkaran yang diisi, inilah kode (beri nama 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>
Anda mungkin harus menyesuaikan ketebalan sesuai dengan kebutuhan Anda.
EDIT:
Berikut tata letak tombol (beri nama 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>
Di Menu buat item:
<item
android:id="@+id/menu_messages"
android:showAsAction="always"
android:actionLayout="@layout/badge_layout"/>
Dalam onCreateOptionsMenu
mendapatkan referensi ke item Menu:
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();
}
}
});
Setelah menerima pemberitahuan untuk pesan, atur hitungan:
itemMessagesBadgeTextView.setText("" + count);
itemMessagesBadgeTextView.setVisibility(View.VISIBLE);
iconButtonMessages.setTextColor(getResources().getColor(R.color.white));
Kode ini menggunakan Iconify-fontawesome .
compile 'com.joanzapata.iconify:android-iconify-fontawesome:2.1.+'
Saya tidak suka ActionView
solusi berbasis, ide saya adalah:
TextView
, yang TextView
akan diisi oleh aplikasiketika Anda perlu menggambar MenuItem
:
2.1. tata letak mengembang
2.2. panggil measure()
& layout()
(jika tidak view
akan 0px x 0px, terlalu kecil untuk kebanyakan kasus penggunaan)
2.3. atur TextView
teks
2.4. buat "tangkapan layar" dari tampilan
2.6. MenuItem
ikon set berdasarkan bitmap dibuat pada 2.4
keuntungan!
jadi, hasilnya harus seperti
<?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
adalah TextView
latar belakang hijau itu,
@drawable/ic_menu_gallery
tidak benar-benar diperlukan di sini, hanya untuk melihat hasil layout di IDE.
tambahkan kode ke 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;
}
Terapkan metode 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);
}
Kode lengkapnya ada di sini: https://github.com/cvoronin/ActionBarMenuItemCounter
Ok, untuk solusi @AndrewS untuk bekerja dengan pustaka appCompat v7 :
<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();
}
Sisa kode sama.
android:actionLayout
ke app:actionLayout
workes seperti pesona.
Coba lihat jawaban untuk pertanyaan-pertanyaan ini, terutama yang kedua yang memiliki kode sampel:
Bagaimana menerapkan nilai-nilai dinamis pada item menu di Android
Bagaimana cara mendapatkan teks pada Ikon ActionBar?
Dari apa yang saya lihat, Anda harus membuat ActionView
implementasi kustom Anda sendiri . Alternatif mungkin kebiasaan Drawable
. Perhatikan bahwa tampaknya tidak ada implementasi asli dari penghitungan pemberitahuan untuk Bilah Tindakan.
EDIT: Jawaban yang Anda cari, dengan kode: Tampilan Pemberitahuan Kustom dengan penerapan sampel
Drawable
s seperti yang terlihat dalam dua tautan berikut: stackoverflow.com/questions/6691818/… dan stackoverflow.com/questions/3972445/…
Drawable
sesuatu seperti tautan di sini dan kemudian membuat atribut untuk kustom Anda Drawable
yang memiliki teks di atasnya sehingga Anda dapat membuat semuanya dalam XML dan paskan sesuai keinginan. Atau, Anda bisa menambahkan Drawable di Java jika ini terlalu sulit.
Saat Anda menggunakan bilah alat:
....
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);
}
dan di panggilan data refresh Anda refreshMenu ():
private void refreshMenu() {
comment_count.setVisibility(View.VISIBLE);
comment_count.setText("" + post_data.getComment_count());
}
Saya menemukan solusi yang sangat baik di sini , saya menggunakannya dengan kotlin.
Pertama, di folder yang dapat digambar, Anda harus membuat 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>
Di Activity_Main
Layout Anda, beberapa seperti:
<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>
Dan Anda dapat memodifikasi seperti:
btnBadge.setOnClickListener { view ->
Snackbar.make(view,"badge click", Snackbar.LENGTH_LONG) .setAction("Action", null).show()
txtBadge.text = "0"
}
Saya menemukan cara yang lebih baik untuk melakukannya. jika Anda ingin menggunakan sesuatu seperti ini
Gunakan ketergantungan ini
compile 'com.nex3z:notification-badge:0.1.0'
buat satu file xml dalam drawable dan Simpan sebagai 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>
Sekarang di mana pun Anda ingin menggunakan lencana itu, gunakan kode berikut dalam xml. dengan bantuan ini, Anda akan dapat melihat lencana itu di sudut kanan atas gambar Anda atau apa pun.
<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>
Sekarang akhirnya di YourFile.java gunakan 2 hal sederhana ini .. 1) Tentukan
NotificationBadge mBadge;
2) di mana loop Anda atau apa pun yang menghitung nomor ini gunakan ini:
mBadge.setNumber(your_LoopCount);
di sini, mBadge.setNumber(0)
tidak akan menunjukkan apa pun.
Semoga bantuan ini.