ActionBar扩展

AcrionBar可以包含基本的按钮以及抽屉图标来展示导航抽屉,我们将要了解怎样使用AppCompatActivity 来支持所有的android版本和一些有力的可扩展的ActionBar特征:
- 使用拆分的action bar 来获得一个顶部个底部的菜单
- 增加ActionView(app:action_layout)和SearchView 组件
- 配置图标的顺序
- 使用ActionProviderShareActionProvider 来获得丰富的作用。
- 配置home图标来向上导航
- 在ActionBar中从碎片中转换菜单图标

建立AppCompatActivity

让你的活动继承AppCompatActivity来获得良好的兼容性以及改变主题使其更加兼容例如Theme.AppCompat.Light.DarkActionBar

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>
</resources>

现在ActionBar已经配置完成,但是我们还要在menu菜单中加入app:showAsAction = "ifRoom" 这可以增加我们对于增加项的支持。

填充动作按钮

action bar为用户提供了进入当前页面最重要的动作项的权限,像之前一样重写onCreateOptionMenu 加载相应的菜单布局。

配置ActionBar图标的顺序

使用orderinCategory 来为每一项指定一个整数,越小的整数优先权越高android:orderInCategory = "20"

自定义风格

通过创建自己的ActionBar主题风格来配置风格和相关属性。

<resources>

    <!-- Define your colors in `res/values/colors.xml` -->
    <color name="simple_yellow">#ECD078</color>
    <color name="primary_blue">#53777A</color>

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:actionBarStyle">@style/MyActionBar</item>
        <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item>

        <!-- Support library compatibility -->
        <item name="actionBarStyle">@style/MyActionBar</item>
        <item name="actionBarTabTextStyle">@style/MyActionBarTabText</item>
    </style>

    <style name="MyActionBar" parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
        <item name="android:background">@color/simple_yellow</item>
        <item name="android:titleTextStyle">@style/MyActionBar.TitleTextStyle</item>

        <!-- Support library compatibility -->
        <item name="background">@color/simple_yellow</item>
        <item name="titleTextStyle">@style/MyActionBar.TitleTextStyle</item>
    </style>

    <style name="MyActionBar.TitleTextStyle"
        parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
        <item name="android:textColor">@color/primary_blue</item>
    </style>

    <style name="MyActionBarTabText" parent="@style/Widget.AppCompat.ActionBar.TabText">
        <item name="android:textColor">@color/primary_blue</item>
    </style>

</resources>

然后应用主题

<application
        ...
        android:theme="@style/AppTheme" >

自定义布局

我们可以用我们自己的XML文件替换自动的标题。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="@string/app_title"
        android:textColor="#ffffff"
        android:id="@+id/mytext"
        android:textSize="18dp" />
</LinearLayout>

然后在代码中 getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);//展示自定义的view getSupportActionBar().setCustomView(R.layout.actionbar_title);
如果想要在自定义的布局中展示图标的话需要附加一个值getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME)
我们仍然可以重写onCreateOptionMenu 来添加自定义的动作按钮。

添加ActionView项

如果想要添加一个不只是简单的图标或者是文本的项,例如一个交互功能更加强的控件,一个Actionview可以让你这样做,常见的是SearchView 平时是一个折叠的搜索图标,然后展开显示一个EditText 文本,首先我们需要创建一个布局文件作为ActionView以便以后可以嵌入到ActionBar中。

LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
    <Button
        android:id="@+id/btnCustomAction"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />
</LinearLayout>

我们可以将此布局文件可以加载到任何一项通过制定app:action_layout 属性

<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/miActionButton"
        app:showAsAction="ifRoom"
        app:actionLayout="@layout/action_view_button" 
        android:title="Loading..." />
</menu>

我们可以通过重写onPrepareOprionsMenu 来获得ActionView的引用

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    MenuItem actionViewItem = menu.findItem(R.id.miActionButton);
        // Retrieve the action-view from menu
    View v = MenuItemCompat.getActionView(actionViewItem);
        // Find the button within action-view
    Button b = (Button) v.findViewById(R.id.btnCustomAction);
    // Handle button click here
    return super.onPrepareOptionsMenu(menu);
}

使用SearchView

首先我们在menu文件中加入SearchView

<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" >
   <item android:id="@+id/action_search"
          android:orderInCategory="5"
          android:title="Search"
          android:icon="@android:drawable/ic_menu_search"
          app:showAsAction="ifRoom|collapseActionView"
          app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>

collapseActionView 表明平时将actionview折叠成图标,点击展开
现在我们需要在搜索时添加一个监听器:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main, menu);
    MenuItem searchItem = menu.findItem(R.id.action_search);
    final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
    searchView.setOnQueryTextListener(new OnQueryTextListener() {
       @Override
       public boolean onQueryTextSubmit(String query) {
            // perform query here

            // workaround to avoid issues with some emulators and keyboard devices firing twice if a keyboard enter is used
            // see https://code.google.com/p/android/issues/detail?id=24599
            searchView.clearFocus();

            return true;
       }

       @Override
       public boolean onQueryTextChange(String newText) {
           return false;
       }
   });
   return super.onCreateOptionsMenu(menu);
}

自定义图标和文本颜色:

MenuItem searchItem = menu.findItem(R.id.action_search);
    final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
    // Use a custom search icon for the SearchView in AppBar
    int searchImgId = android.support.v7.appcompat.R.id.search_button; 
    ImageView v = (ImageView) searchView.findViewById(searchImgId);
    v.setImageResource(R.drawable.search_btn);
    // Customize searchview text and hint colors
    int searchEditId = android.support.v7.appcompat.R.id.search_src_text;
    EditText et = (EditText) searchView.findViewById(searchEditId);
    et.setTextColor(Color.BLACK);
    et.setHintTextColor(Color.BLACK);
}

使用图标向上导航

使用setDisplayHomenAsUpEnabled 方法,Up 相对于返回键是带领用户返回逻辑上的屏幕,这不是基于导航的历史而是屏幕之间的关系,例如在邮件客户端返回键可能会带领用户回到之前的邮件,而up 会一直将用户带回邮件列表。
首先我们指定home用作up

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

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

}

我们也可以明确的重写up按钮,通过检查android.R.id.home id是否被选择

@Override
  public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
      // This is the up button
      case android.R.id.home:
          NavUtils.navigateUpFromSameTask(this);
          // overridePendingTransition(R.animator.anim_left, R.animator.anim_right);
          return true;
      default:
          return super.onOptionsItemSelected(item);
      }
  }

这样的话允许我们配置up键按下时的过度效果。

编译时的配置

为了指定up 导向的上一个活动,我们可以在AndroidManifest.xml 文件中设置逻辑上的父项。

<activity 
        android:name="com.example.myfirstapp.ChildActivity"
        android:label="@string/title_activity_display_message"
        android:parentActivityName="com.example.myfirstapp.ParentActivity" >
        <!-- Parent activity meta-data to support API level 7+ -->
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.ParentActivity" />
</activity>

现在每当home图标按下都会导航到父活动,如果你想父活动保持他的状态可以为父活动指定状态为android:launchMode:"SingleTop" 当栈顶活动为父活动时不会在创建新的活动。

运行时配置

如果我们想动态设置up 键而不想在注册文件中的话,我们可以重写getSupportParentActivityIntent() 方法返回想要的基于传入的参数的intent。

public static final String PACKAGE_NAME = "com.myapplication.";
public static final String PARENT_NAME_EXTRA = "ParentClassName";

@Override
public Intent getSupportParentActivityIntent() {
    //获得父类的intent
    Intent parentIntent = getIntent();
    String className = parentIntent.getStringExtra(PARENT_NAME_EXTRA);
    // 基于父类名称创造一个意图
    Intent newIntent = null;
    try {
         //使用包名定义类
         newIntent = new Intent(this, Class.forName(PACKAGE_NAME + className));
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    // 随着`up`活动返回intent
    return newIntent;
}

然后当我们想要启动新的活动时候,我们需要应用ParentClassNmae 作为父类额外的控制

Intent intent = new Intent(this, ChildActivity.class);
intent.putExtra(ChildActivity.PARENT_NAME|_EXTRA, "PrentActivity");
startActivity(intent);

从碎片配置ActionBar

从碎片中配置actionbar和从活动中非常的相似,但是有点区别。
自动的,android嘉定碎片不想想actionbar提供items,当一个碎片确实想要向actionbar添加项时,需要告知安卓系统,setHasOptionMenu(true) 在onCreate()方法中

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // ...

    setHasOptionsMenu(true);
}

现在安卓会调用onCreateOptionsMenu(..) 和相关的方法
要记住任何由碎片添加的items将会衣服在任何现存的items上,包括了由所包含的活动添加的项,你可以使用orderInCategory 来控制顺序。
与活动中相似,在碎片中安卓提供了一个MenuInflater:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.my_menu, menu);
}

处理点击事件也和活动中相同,不同之处在于碎片的onOptionItemSelected(...) 方法只在活动中的此方法不处理点击事件时才会被调用

@Override
public boolean onOptionItemSelected(MenuItem item) {
    //处理选项
    switch (item.getItemId()) {
        case R.id.my_item:
        //处理点击
            return truedefault: 
            return super.onOptionItemSelected(item);
    }
}

配置Split-Action Bar

。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值