Search code examples
androidandroid-actionbarbadge

menu Item not showing if actionLayout is set


I'm trying to use a "badge" for an item on my actionBar, something like this but whithout numbers: enter image description here

The problem is, everytime I set app:actionLayout="@layout/actionbar_badge_layout" my sync Item is not showing (but the badge does). I'm using this code:

badge_noty.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">

    <solid android:color="@color/colorRed"/>
    <stroke android:color="@android:color/white" android:width="1dp"/>

</shape>

actionbar_sync.xml

<?xml version="1.0" encoding="utf-8"?>
<menu 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_sync"
        android:icon="@drawable/ic_sync"
        android:title="Sync"
        app:actionLayout="@layout/actionbar_badge_layout"
        app:showAsAction="always"
   />
</menu>

actionbar_badge_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    style="?attr/actionButtonStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clipToPadding="false"
    android:focusable="true"
    >

    <!-- Badge -->
    <ImageView
        android:id="@+id/img_badge_sync"
        android:layout_width="12dp"
        android:layout_height="12dp"
        android:src="@drawable/badge_noty" />

</FrameLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private ImageView syncBadge;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        ...............
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.actionbar_sync, menu);

        final MenuItem syncItem = menu.findItem(R.id.action_sync);
        View actionView = syncItem.getActionView();
        syncBadge = actionView.findViewById(R.id.img_badge_sync);

        return true;
    }

Why my sync icon is not showing?

Edit 1: I tried Imtiaz Abir answer, and it worked, but not as expected. Now, onOptionsItemSelected is not triggered when I click sync item. So, I think Imtiaz Abir answer is not the proper solution


Solution

  • As you have already defined app:actionLayout in your menu item of your actionbar_sync.xml menu file, the default android:icon attribute won't work. Therefore, the solution is to add your sync icon using an ImageView along with your ImageView with badge in your actionbar_badge_layout.xml file and remove android:icon attribute from your menu item.

    actionbar_sync.xml

    <?xml version="1.0" encoding="utf-8"?>
    <menu 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <item
            android:id="@+id/action_sync"
            android:title="Sync"
            app:actionLayout="@layout/actionbar_badge_layout"
            app:showAsAction="always"
       />
    </menu>
    

    actionbar_sync.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        style="?attr/actionButtonStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clipToPadding="false"
        android:focusable="true"
        >
    
        <!-- Badge -->
        <ImageView
            android:id="@+id/img_badge_sync"
            android:layout_width="12dp"
            android:layout_height="12dp"
            android:src="@drawable/badge_noty" />
    
         <!-- Sync image -->
         <ImageView
            android:id="@+id/icon_sync"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:src="@drawable/ic_sync" />
    
    </FrameLayout>