Google과 같은 작업 표시 줄 알림 수 아이콘 (배지) 아이콘을 표시하는 Android 표준

Google 예제와 같이 액션 바 알림 아이콘을 표시하는 Android 표준 배지 또는 방법이 있습니까?

그림에서 3을 세다

그렇지 않다면, 그것을 만드는 가장 좋은 방법은 무엇입니까?
나는 안드로이드를 처음 사용합니다. 도와주세요.



답변

이것이 최선의 해결책인지 확실하지 않지만 그것이 필요한 것입니다.

더 나은 성능이나 품질을 위해 무엇을 변경해야하는지 알고 있다면 알려주십시오. 제 경우에는 버튼이 있습니다.

내 메뉴의 사용자 정의 항목-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();
}


답변

편집 지원 라이브러리 (또는 androidx) 버전 26 이후 더 이상 OnLongClickListener툴팁을 표시 하기 위해 사용자 정의 를 구현할 필요가 없습니다 . 간단히 이것을 호출하십시오 :

TooltipCompat.setTooltipText(menu_hotlist, getString(R.string.hint_show_hot_message));

누군가가 다음과 같은 것을 원할 경우를 대비하여 코드를 공유합니다.
여기에 이미지 설명을 입력하십시오

  • 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

    참고 스타일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>
  • drawable-xhdpi / ic_bell.png

    모든면에서 10 픽셀 너비의 패딩이있는 64×64 픽셀 이미지. 8 픽셀 너비의 패딩이 있어야하지만 대부분의 기본 항목은 그보다 약간 작습니다. 물론 밀도에 따라 다른 크기를 사용하고 싶을 것입니다.

  • drawable / rounded_square.xml

    여기서 # ff222222 (알파 #ff가있는 색상 # 222222 (완전히 표시))는 내 작업 표시 줄의 배경색입니다.

    <?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

    여기에서 클릭과 업데이트가 가능합니다! onLongClick에서 Toast 생성을 제공하는 추상 리스너를 만들었습니다. 코드는 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;
        }
    }

답변

추가하기 만하면됩니다. 누군가가 채워진 원 버블을 구현하려면 다음 코드를 사용하십시오 (name 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>

필요에 따라 두께를 조정해야 할 수도 있습니다.

여기에 이미지 설명을 입력하십시오

편집 :
다음은 버튼의 레이아웃입니다 (이름 지정 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>

메뉴에서 항목 생성 :

<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기반 솔루션을 좋아하지 않습니다 . 제 아이디어는 다음과 같습니다.

  1. 와 레이아웃 작성 TextView, TextView응용 프로그램에 의해 채워집니다를
  2. 당신이 그릴 때 MenuItem:

    2.1. 레이아웃을 부 풀리다

    2.2. 전화 measure()& layout()(그렇지 않으면 view0px x 0px, 대부분의 경우에는 너무 작습니다)

    2.3. TextView의 텍스트를 설정

    2.4. 뷰의 “스크린 샷”을 만듭니다.

    2.6. MenuItem2.4에서 생성 된 비트 맵을 기반으로 아이콘 설정

  3. 이익!

결과는 다음과 같아야합니다.
여기에 이미지 설명을 입력하십시오

  1. 여기에 레이아웃을 만드십시오 간단한 예입니다
<?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에서 레이아웃의 결과를 미리 보는 것입니다.

  1. 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;
    }
  2. 아이콘 빌드 방법을 구현하십시오.

    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구현 을 만들어야합니다 . 대안은 custom 일 수 있습니다 Drawable. 작업 표시 줄에 대한 알림 수의 기본 구현이없는 것 같습니다.

편집 : 당신이 찾고 있던 답, 코드 : 사용자 정의 알림보기 샘플 구현을


답변

툴바를 사용하는 경우 :

....
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());
}