0

I was following this article. Unfortunatelly, badge isn't drawn. Of course I changed invalidateOptionsMenu method to supportInvalidateOptionsMenu method.

I was checking the log, step by step and found out that draw method in custom Drawable named BadgeDrawable is never called. Why is that?

I'm trying to use it in AppCompatActivity using Support Design Library version 23.0.1

I saw this answer but it seems to be out of date.

Is there anyone who managed to implement badger counter for MenuItem icon inside android.support.v7.widget.Toolbar? If the way shown in the article is wrong then could you suggest other way to achieve the result as in example below?: enter image description here

Here is a setup inside my application:

LayerDrawable XML ic_filter_notifications.xml:

<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/ic_filter_notification"
        android:drawable="@drawable/ic_filter_grey600_18dp"
        android:gravity="center"/>

    <!-- set a place holder Drawable so android:drawable isn't null -->
    <item android:id="@+id/ic_filter_badge"
        android:drawable="@drawable/ic_filter_grey600_18dp">

    </item>

</layer-list>

Menu that I use in the Toolbar menu_activity_main.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:cobytu="http://schemas.android.com/apk/res-auto" >

    <item
        android:id="@+id/menu_settings"
        android:orderInCategory="100"
        android:title="@string/menu_settings"
        cobytu:showAsAction="never"/>
    <item
        android:id="@+id/menu_logout"
        android:orderInCategory="1000000"
        android:title="@string/menu_logout"
        cobytu:showAsAction="never"/>
    <item
        android:id="@+id/action_filter"
        android:title="@string/filters"
        android:icon="@drawable/ic_filter_notifications"
        cobytu:showAsAction="always"/>
    <item
        android:id="@+id/action_location"
        android:icon="@drawable/ic_map_marker_radius_grey600_18dp"
        android:title="@string/location"
        cobytu:showAsAction="always"/>

</menu>

This is function sets the count int for new BadgeDrawable inside UsefulFunctions class - UsefulFunctions.java:

 public class UsefulFunctions {

     private Context ctx;

     public UsefulFunctions(Context context){
                ctx = context;
            }


       public static void setBadgeCount(Context context, LayerDrawable icon,
            int count) {

        BadgeDrawable badge;

        // Reuse drawable if possible
        Drawable reuse = icon.findDrawableByLayerId(R.id.ic_filter_badge);
        if (reuse != null && reuse instanceof BadgeDrawable) {
            badge = (BadgeDrawable) reuse;
        } else {
            Log.d("mTAG", UsefulFunctions.class.getName()
                    + " I'm creating new BadgeDrawable!");
            badge = new BadgeDrawable(context);
        }

        badge.setCount(count);
        icon.mutate();
        Log.d("mTAG",
                UsefulFunctions.class.getName() + " badge: " + badge.toString()
                        + " count: " + count);
        icon.setDrawableByLayerId(R.id.ic_filter_badge, badge);

    }
}

This is the important scrap of my MainActivity where I invoke BadgeDrawable creation. I also show what's inside onCreate and in onOptionsItemSelected, may be needed - MainActivity.java:

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,  DialogFragmentFilters.FiltersRefreshInterface{

    public String username;


    //CollapsingToolbarLayout
    private CollapsingToolbarLayout mCollapsingToolbarLayout;

    //Toolbar
    private Toolbar mToolbar;

    //TabLayout
    private TabLayout mTabLayout;
    private ViewPager mPager;
    private MyPagerAdapter mAdapter;

    //NavigationDraver
    private static final String SELECTED_ITEM_ID = "selected_item_id";
    private static final String FIRST_TIME = "first_time";
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private NavigationView mNavigationView;
    private int mSelectedId;
    private boolean mUserSawDrawer = false;
    private TextView mNavHeaderNameText;
    private TextView mNavHeaderEmailText;


    private  DatabaseHandler db;
    private  UserFunctions userFunctions;
    private AlertDialog.Builder dialogBuilder;
    private AlertDialog alertDialog;

    private JSONObject jsonLocation = new JSONObject();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        userFunctions = new UserFunctions();
        db = new DatabaseHandler(getApplicationContext());

        username = db.getUserDetails().get(DatabaseHandler.getKEY_USER_LOGIN());

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        setupToolbar();
        setupTablayout();


        mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
        mNavigationView.setNavigationItemSelectedListener(this);

        View header = LayoutInflater.from(MainActivity.this).inflate(R.layout.nav_header, null);
        mNavHeaderNameText = (TextView) header.findViewById(R.id.tv_nav_header_name);
        mNavHeaderNameText.setText("Siema "+username+"!");

        mNavHeaderEmailText = (TextView) header.findViewById(R.id.tv_nav_header_email);
        mNavHeaderEmailText.setText(db.getUserDetails().get(DatabaseHandler.getKEY_USER_EMAIL()));


        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,mToolbar, R.string.drawer_open, R.string.drawer_close);
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        mDrawerToggle.syncState();

        if (!didUserSeeDrawer()) {
            showDrawer();
            markDrawerSeen();
        } else {
            hideDrawer();
        }

        mSelectedId = savedInstanceState == null ? R.id.navigation_item_4 : savedInstanceState.getInt(SELECTED_ITEM_ID);
        navigate(mSelectedId);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);



    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
            showActionDialog(id);
            //noinspection SimplifiableIfStatement
        switch (id) {
        case R.id.menu_settings:
            return true;
        case R.id.menu_logout:
            dialogBuilder = new AlertDialog.Builder(new ContextThemeWrapper(
                    MainActivity.this, R.style.Theme_AppCompat_Light_Dialog));
            dialogBuilder
                    .setTitle(getResources().getString(R.string.logoutAlertTitle))
                    .setIcon(R.drawable.ic_logout).setMessage(getResources().getString(R.string.logoutAlertMessage)).setPositiveButton(getResources().getString(R.string.logoutAlertYesButton),
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {

                                    ((RelativeLayout) findViewById(R.id.fl_mainContent))
                                            .animate()
                                            .alpha(0f)
                                            .setListener(
                                                    new AnimatorListenerAdapter() {
                                                        public void onAnimationEnd(
                                                                Animator animation) {
                                                            mDrawerLayout
                                                                    .setVisibility(View.INVISIBLE);
                                                            mDrawerLayout
                                                                    .setAlpha(1f);
                                                            mDrawerLayout
                                                                    .animate()
                                                                    .setListener(null);
                                                        }
                                                    });

                                    userFunctions.logoutUser(getApplicationContext());

                                    Intent i = new Intent(MainActivity.this, LoginActivity.class);
                                    // MainActivity.this.deleteDatabase("cobytu_db");
                                    startActivity(i);
                                    finish();
                                }
                            })
                    .setNegativeButton(getResources().getString(R.string.logoutAlertNoButton),
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                    dialog.dismiss();

                                }
                            });
            alertDialog = dialogBuilder.create();
            alertDialog.show();
            return true;
        }

            return false;
        }

    public int filterCounter = 0;

    class FetchCountTask extends AsyncTask<Void, Void, Integer> {

        @Override
        protected Integer doInBackground(Void... params) {
            // example count. This is where you'd 
            // query your data store for the actual count.
            return 5; 
        }

        @Override
        public void onPostExecute(Integer count) {
            setNotifCount(count);
        }
    }

    private void setNotifCount(int count){
        filterCounter = count;
        supportInvalidateOptionsMenu();
    }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_activity_main, menu);
        MenuItem item = menu.findItem(R.id.action_filter);
        LayerDrawable icon = (LayerDrawable) item.getIcon();

        // Update LayerDrawable's BadgeDrawable
        Log.d("mTag", "onCreateOptionsMenu: this: " + this.toString());
        UsefulFunctions.setBadgeCount(this, icon, filterCounter);

        return true;
    }


    @Override
    public void onRefreshFilters(int counter) {
        setupTablayout();
        Toast.makeText(MainActivity.this, "List has been refreshed! " + counter, Toast.LENGTH_SHORT).show();
        filterCounter = counter;
        new FetchCountTask.execute();
    }



}
4

0 回答 0