ToolBar+ActionProvider的使用

来源:互联网 发布:淘宝鞋类三包规定 编辑:程序博客网 时间:2024/06/05 14:52

先看一下ActionProvider的官方解释:An ActionProvider can be optionally specified for a {@link android.view.MenuItem} and in such a case it will be responsible for creating the action view that appears in the {@link android.app.ActionBar} as a substitute for the menu item when the item is displayed as an action item. 

比较绕,需要先搞清楚几个概念,我的理解是这样的

 action view: 出现在actionbar里的view都可以成为一个action view, 比如导航图标,title等

我们在写menu的xml文件时会设置showAsAction,当这个属性为always时,这个item就会出现在toolbar中,这种item是action item,也属于action view

当我们设置为never时,出现在溢出框里的item就是menu item,这个就不属于action view了

所以ActionProvider的工作就是负责创建一个action view来代替action item(不是menu item),当然前提是menu文件中已经给该item指定了ActionProvider。

用于当item不固定,需要随着状态改变而变化时,比如硬件连接与断开需要显示不同的图标,或者购物车商品数量

ToolBar和actionbar都可以使用ActionProvider,本文使用ToolBar,实现的效果比较简单,点击按钮,item的title改变。

1 主题设置为NoActionBar

2 在布局文件中加入toolbar,activity中找到控件,并setSupportActionBar(toolbar)(一定要设置);

3 编写menu文件,activity中设置 toolbar.inflateMenu(R.menu.**);


准备ActionProvider

1 自定义类,继承ActionProvider

会提示重写两个方法,第二个方法是你要替换的控件,可以自己写一个布局再inflate,我就用了一个textview

public MyProvider(Context context) {        super(context);        this.context = context;    }    @Override    public View onCreateActionView() {        if (textView == null){            textView = new TextView(context);        }        textView.setOnClickListener(this);        textView.setTextColor(Color.WHITE);        return textView;    }
再加一些数据和背景设置的方法
public void setData(String string){        if (textView != null){            textView.setText(string);        }    }    public void setBackGround(Drawable backGround){        textView.setBackground(backGround);    }    public void setBackGround(int color){        textView.setBackgroundColor(color);    }    @Override    public void onClick(View v) {        Toast.makeText(context,"被点击了",Toast.LENGTH_SHORT).show();    }

2 ActionProvider就完成了,不要忘记在menu文件中给需要的item指定provider,格式是包名+类名

<?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/one"        android:title="one"        app:showAsAction="always"        app:actionProviderClass="com.myway.actionproviderdemo.MyProvider"/>    <item android:id="@+id/two"        android:title="two"        app:showAsAction="never"        app:actionProviderClass="com.myway.actionproviderdemo.MyProvider"/>    <item android:id="@+id/three"        android:title="three"        app:showAsAction="never"        app:actionProviderClass="com.myway.actionproviderdemo.MyProvider"/>    <item        android:id="@+id/four"        android:title="four"        app:showAsAction="never" /></menu>

3 接下来就是在activity中使用了

格式都是固定的,重写onCreateOptionsMenu方法,findItem参数是你指定的那个item,通过他得到provider的实例

当然如果要操作多个item,那就findItem多个MenuItem,创建多个provider的实例

@Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.hello, menu);        MenuItem item = menu.findItem(R.id.one);        actionProvider = (MyProvider) MenuItemCompat.getActionProvider(item);//       MenuItem item1 = menu.findItem(R.id.two);//       actionProvider1 = (MyProvider) MenuItemCompat.getActionProvider(item1);    return true;    }
//点击事件    public void setdata(View view) {        if (actionProvider != null) {            actionProvider.setBackGround(Color.RED);            actionProvider.setData("设置数据"); //          actionProvider1.setData("哈哈哈");}}

当点击按钮之后就会发现第一个item发生了变化


前面说过了,上述操作对于Action Menu才生效,但是可以看到menu文件中属性是never的item也与provider进行了关联,这就提到provider的另一个作用了

在provider中重写以下方法

@Override    public boolean onPerformDefaultAction() {        Log.i("hahahaha","onPerformDefaultAction 被调用");        return super.onPerformDefaultAction();    }
当用户没有为toolbar设置item的点击事件,但是点击了关联过provider的位于溢出框中的menu item时,系统会调用这个方法,响应点击事件,而没有关联的item是不会响应的;当然如果设置了点击事件,当点击menu item都会响应,点击action menu时只有在provider中设置的点击事件会相应。目前还不知道这个方法有什么实际用途。