动态更新Toolbar Menu以及Menu中同时显示文字和图标

2019-03-17 22:19:28

参看网址 动态更新Toolbar Menu以及Menu中同时显示文字和图标

动态更新Toolbar Menu以及Menu中同时显示文字和图标

我们经常会有这样的需求,在切换Fragment或者点击某个按钮后动态更新Toolbar上Menu项.但是onCreateOptionsMenu方法只在创建Activity的时候调用一次,以后就不再调用了,所以就不能在onCreateOptionsMenu中做处理了。
不过系统提供了另外的一个方法onPrepareOptionsMenu,我们可以在这个方法中做一些逻辑处理,然后在需要更新Menu的地方调用invalidateOptionsMenu方法。
效果图如下:

点击管理专辑按钮更换Menu,

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);        return super.onCreateOptionsMenu(menu);
    }
@Override
    public boolean onPrepareOptionsMenu(Menu menu) {        if (mIsEditStatus) {
            menu.findItem(R.id.action_share).setVisible(false);
            menu.findItem(R.id.action_edit).setVisible(true);
        } else {
            menu.findItem(R.id.action_share).setVisible(true);
            menu.findItem(R.id.action_edit).setVisible(false);
        }        return super.onPrepareOptionsMenu(menu);
    }
invalidateOptionsMenu(); //重新绘制menu

另外的一个需求是在Menu中要显示图标和文字,虽然在menu.xml文件中配置了图标和文字,但是在有图标的情况下文字是不会显示的,即使设置 app:showAsAction="always|withText" 但是我在运行的时候发现并没有显示文字,处理方法是通过另外一个属性实现app:actionLayout.
首先menu.xml定义如下:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      tools:context=".album.AlbumDetailActivity">

    <item android:id="@+id/action_share"
          android:title="分享"
          android:orderInCategory="80"
          android:icon="@drawable/icon_share_white"
          app:showAsAction="always|withText" />

    <item android:id="@+id/action_edit"
          android:title=""
          android:orderInCategory="60"
          app:showAsAction="always"
          app:actionLayout="@layout/menu_action_album_edit"
        /></menu>

app:actionLayout指向了一个布局,可以在这个布局中定义你想要的控件。我的定义是这样的。
menu_action_album_edit.xml

<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:paddingLeft="10dip"
          android:paddingRight="10dip"
          android:gravity="center"
          android:text="@string/app_edit"
          android:drawableLeft="@drawable/album_edit_white"
          android:textColor="@color/white"
          android:clickable="true" />

android:drawableLeft中指定你的图标。
然后还要在onCreateOptionsMenu中重写一下Menu的点击事件,现在onCreateOptionsMenu方法是这样的:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);        final MenuItem item = menu.findItem(R.id.action_edit);
        item.getActionView().setOnClickListener(new View.OnClickListener() {            @Override
            public void onClick(View v) {
                onOptionsItemSelected(item);
            }
        });        return super.onCreateOptionsMenu(menu);
    }

然后像普通的Menu item一样在onOptionsItemSelected中处理点击事件就可以了。


  • 2020-11-18 14:34:00

    当你写爬虫抓不到APP请求包的时候该怎么办?

    提示:因为高级篇以后的APP将无法使用很通用的方式处理,每种类型甚至是每个APP的反抓包处理方式都会有差别,所以这个系列以后会以【高级篇-具体类型】的形式来写。

  • 2020-11-21 20:41:51

    Kotlin Sealed class类详解

    Sealed class(密封类) 是一个有特定数量子类的类,看上去和枚举有点类似,所不同的是,在枚举中,我们每个类型只有一个对象(实例);而在密封类中,同一个类可以拥有几个对象。

  • 2020-11-22 20:53:43

    Dagger2之Kotlin写法

    修饰构造方法 修饰变量,在宿主类里,引入要注入的实例

  • 2020-11-22 20:56:13

    Dagger2使用详解

    简单的说,就是一个工厂模式,由Dagger负责创建工厂,帮忙生产instance。遵从Java规范JSR 330,可以使用这些注解。现在不研究Dagger2是如何根据注解去生成工厂的,先来看看工厂是什么东西,理解为什么可以实现了DI(Dependency Injection),如何创建IoC(Inverse of Control)容器。

  • 2020-11-22 21:00:28

    dagger.android--Fragment,BaseFragment

    1 使用Fragment参数来代替Activity参数 2 使用 @FragmentKey来代替@ActivityKey 3 使用HasFragmentInjector来代替@HasActivityInjector 4 AndroidInjection.inject(Fragment)方法,在Fragment的onAttach()中调用,而不是在onCreate()中 5 Fragment的Module添加位置,和Activity是不同的,它取决于Fragment需要的其他依赖注入

  • 2020-11-22 21:12:30

    Dependency Injection with Dagger2,Fragment

    標註@Provides的method若有parameter的話,Dagger會找出其擁有的該型態物件來使用。我們在Module內新增了DataModel將其列入Dagger的管理下,接著在provideFactory()增加parameter變成provideFactory(DataModel dataModel),Dagger就會找出其管理的DataModel給provideFactory使用。

  • 2020-11-22 22:58:52

    Android LiveData Transformations

    有时候有这样的需求,需要在LiveData将变化的数据通知给观察者前,改变数据的类型;或者是返回一个不一样的LiveData。

  • 2020-11-22 23:00:16

    androidx中的lifecycle组件

    Lifecycle-aware components生命周期感知组件执行操作,以响应另一个组件生命周期状态的更改,例如Activity和Fragment。这些组件可以帮助您生成更有组织、更容易维护的轻量级代码。