当前位置: 代码迷 >> Android >> Android SDK实例源码学习系列三 ActionBarCompat
  详细解决方案

Android SDK实例源码学习系列三 ActionBarCompat

热度:48   发布时间:2016-04-27 22:49:47.0
Android SDK范例源码学习系列三 ActionBarCompat
    (本系列基于Jelly Bean,Android OS4.2,API 17版本) 
操作栏Action Bar是在Android3.0版本中引入的,用来替代之前的标题栏。ActionBar提供了更丰富的导航效果,它可用来显示用户动作和全局的菜单选项,还可以增强标识,或者在Fragment之间切换,提供下拉导航栏、显示搜索和分享等动作。.    使用ActionBar很简单,在3.0以后的版本中都默认包含ActionBar组件。如果不想使用,需要将Activity的主题设置为Theme.Holo.NoActionBar:    <activity android:theme="@android:style/Theme.Holo.NoActionBar">    如果仅仅不想显示,可以调用ActionBar.hide()方法,这样当你想显示时,就可以用show()方法达到目的。    本范例中实现了不同版本中ActionBar的兼容功能,一共使用了8个类,下面一一介绍:    ActionBarHelper.class处理ActionBar基础功能的抽象类。实现这个类的是下面的两个类:    ActionBarHelperBase.class 在3.0以前版本中使用,弄明白这个类也就学会了自定义菜单栏的方法    ActionBarHelperHoneycomb在3.0以后版本中使用,后面的类继承了这个类    ActionBarHelperICS在4.0版本后使用,继承了上面类的大部分方法    SimpleMenu.class和SimpleMenuItem是 用于兼容的类,在低版本上使用。    然后就负责具体交互的Activity类MainActivity,继承自实现了ActionBar功能的ActionBarActivity。    下面着重分析ActionBarHelperBase类
package com.example.android.actionbarcompat;import org.xmlpull.v1.XmlPullParser;import org.xmlpull.v1.XmlPullParserException;import android.app.Activity;import android.content.Context;import android.content.res.XmlResourceParser;import android.os.Bundle;import android.view.InflateException;import android.view.Menu;import android.view.MenuInflater;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.view.Window;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ProgressBar;import android.widget.TextView;import java.io.IOException;import java.util.HashSet;import java.util.Set;/** * 实现了ActionBar的类,用于HoneyComb之前的操作系统版本 */public class ActionBarHelperBase extends ActionBarHelper {    private static final String MENU_RES_NAMESPACE = "http://schemas.android.com/apk/res/android";    private static final String MENU_ATTR_ID = "id";    private static final String MENU_ATTR_SHOW_AS_ACTION = "showAsAction";    protected Set<Integer> mActionItemIds = new HashSet<Integer>();    protected ActionBarHelperBase(Activity activity) {        super(activity);    }@Override    public void onCreate(Bundle savedInstanceState) {        mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);    }@Override    public void onPostCreate(Bundle savedInstanceState) {        mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,                R.layout.actionbar_compat);        setupActionBar();        SimpleMenu menu = new SimpleMenu(mActivity);        mActivity.onCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, menu);        mActivity.onPrepareOptionsMenu(menu);        for (int i = 0; i < menu.size(); i++) {            MenuItem item = menu.getItem(i);            if (mActionItemIds.contains(item.getItemId())) {                addActionItemCompatFromMenuItem(item);            }        }    }    /**     * 设置操作栏     */    private void setupActionBar() {        final ViewGroup actionBarCompat = getActionBarCompat();        if (actionBarCompat == null) {            return;        }        LinearLayout.LayoutParams springLayoutParams = new LinearLayout.LayoutParams(                0, ViewGroup.LayoutParams.FILL_PARENT);        springLayoutParams.weight = 1;        // 添加Home按钮     SimpleMenu tempMenu = new SimpleMenu(mActivity);        SimpleMenuItem homeItem = new SimpleMenuItem(                tempMenu, android.R.id.home, 0, mActivity.getString(R.string.app_name));        homeItem.setIcon(R.drawable.ic_home);        addActionItemCompatFromMenuItem(homeItem);        // 添加标题文本     TextView titleText = new TextView(mActivity, null, R.attr.actionbarCompatTitleStyle);        titleText.setLayoutParams(springLayoutParams);        titleText.setText(mActivity.getTitle());        actionBarCompat.addView(titleText);    }@Override   public void setRefreshActionItemState(boolean refreshing) {        View refreshButton = mActivity.findViewById(R.id.actionbar_compat_item_refresh);        View refreshIndicator = mActivity.findViewById(                R.id.actionbar_compat_item_refresh_progress);        if (refreshButton != null) {            refreshButton.setVisibility(refreshing ? View.GONE : View.VISIBLE);        }        if (refreshIndicator != null) {            refreshIndicator.setVisibility(refreshing ? View.VISIBLE : View.GONE);        }    }    /**     下面的代码用来隐藏选项按钮     */@Override  public boolean onCreateOptionsMenu(Menu menu) {        // Hides on-screen action items from the options menu.    for (Integer id : mActionItemIds) {            menu.findItem(id).setVisible(false);        }        return true;    }@Override  protected void onTitleChanged(CharSequence title, int color) {        TextView titleView = (TextView) mActivity.findViewById(R.id.actionbar_compat_title);        if (titleView != null) {            titleView.setText(title);        }    }    /**     * Returns a {@link android.view.MenuInflater} that can read action bar metadata on     * pre-Honeycomb devices.     */  public MenuInflater getMenuInflater(MenuInflater superMenuInflater) {        return new WrappedMenuInflater(mActivity, superMenuInflater);    }    /**     * ViewGroup作为View的一种,被用作容纳多个View的容器,这里返回操作栏上用到的ViewGroup,     * 如果是HoneyComb以上安卓版本,返回Null。     */  private ViewGroup getActionBarCompat() {        return (ViewGroup) mActivity.findViewById(R.id.actionbar_compat);    }    /**     * Adds an action button to the compatibility action bar, using menu information from a {@link* android.view.MenuItem}. If the menu item ID is <code>menu_refresh</code>, the menu item's     * state can be changed to show a loading spinner using     * {@link com.example.android.actionbarcompat.ActionBarHelperBase#setRefreshActionItemState(boolean)}.     */  private View addActionItemCompatFromMenuItem(final MenuItem item) {        final int itemId = item.getItemId();        final ViewGroup actionBar = getActionBarCompat();        if (actionBar == null) {            return null;        }        // 根据版本创建ImageButton  ImageButton actionButton = new ImageButton(mActivity, null,                itemId == android.R.id.home  ? R.attr.actionbarCompatItemHomeStyle  : R.attr.actionbarCompatItemStyle);        actionButton.setLayoutParams(new ViewGroup.LayoutParams(                (int) mActivity.getResources().getDimension(                        itemId == android.R.id.home  ? R.dimen.actionbar_compat_button_home_width  : R.dimen.actionbar_compat_button_width),                ViewGroup.LayoutParams.FILL_PARENT));        if (itemId == R.id.menu_refresh) {            actionButton.setId(R.id.actionbar_compat_item_refresh);        }        actionButton.setImageDrawable(item.getIcon());        actionButton.setScaleType(ImageView.ScaleType.CENTER);        actionButton.setContentDescription(item.getTitle());        actionButton.setOnClickListener(new View.OnClickListener() {            public void onClick(View view) {                mActivity.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);            }        });        actionBar.addView(actionButton);        if (item.getItemId() == R.id.menu_refresh) {            // Refresh buttons should be stateful, and allow for indeterminate progress indicators,            // so add those.    ProgressBar indicator = new ProgressBar(mActivity, null,                    R.attr.actionbarCompatProgressIndicatorStyle);            final int buttonWidth = mActivity.getResources().getDimensionPixelSize(                    R.dimen.actionbar_compat_button_width);            final int buttonHeight = mActivity.getResources().getDimensionPixelSize(                    R.dimen.actionbar_compat_height);            final int progressIndicatorWidth = buttonWidth / 2;            LinearLayout.LayoutParams indicatorLayoutParams = new LinearLayout.LayoutParams(                    progressIndicatorWidth, progressIndicatorWidth);            indicatorLayoutParams.setMargins(                    (buttonWidth - progressIndicatorWidth) / 2,                    (buttonHeight - progressIndicatorWidth) / 2,                    (buttonWidth - progressIndicatorWidth) / 2,                    0);            indicator.setLayoutParams(indicatorLayoutParams);            indicator.setVisibility(View.GONE);            indicator.setId(R.id.actionbar_compat_item_refresh_progress);            actionBar.addView(indicator);        }        return actionButton;    }    /**     * MenuInflater的子类,用来解析定义在Menu目录下的菜单布局文件.     */  private class WrappedMenuInflater extends MenuInflater {        MenuInflater mInflater;        public WrappedMenuInflater(Context context, MenuInflater inflater) {            super(context);            mInflater = inflater;        }        @Override  public void inflate(int menuRes, Menu menu) {            loadActionBarMetadata(menuRes);            mInflater.inflate(menuRes, menu);        }        /**         * Loads action bar metadata from a menu resource, storing a list of menu item IDs that         * should be shown on-screen (i.e. those with showAsAction set to always or ifRoom).*/  private void loadActionBarMetadata(int menuResId) {            XmlResourceParser parser = null;            try {                parser = mActivity.getResources().getXml(menuResId);                int eventType = parser.getEventType();                int itemId;                int showAsAction;                boolean eof = false;                while (!eof) {                    switch (eventType) {                        case XmlPullParser.START_TAG:                            if (!parser.getName().equals("item")) {                                break;                            }                            itemId = parser.getAttributeResourceValue(MENU_RES_NAMESPACE,                                    MENU_ATTR_ID, 0);                            if (itemId == 0) {                                break;                            }                            showAsAction = parser.getAttributeIntValue(MENU_RES_NAMESPACE,                                    MENU_ATTR_SHOW_AS_ACTION, -1);                            if (showAsAction == MenuItem.SHOW_AS_ACTION_ALWAYS ||                                    showAsAction == MenuItem.SHOW_AS_ACTION_IF_ROOM) {                                mActionItemIds.add(itemId);                            }                            break;                        case XmlPullParser.END_DOCUMENT:                            eof = true;                            break;                    }                    eventType = parser.next();                }            } catch (XmlPullParserException e) {                throw new InflateException("Error inflating menu XML", e);            } catch (IOException e) {                throw new InflateException("Error inflating menu XML", e);            } finally {                if (parser != null) {                    parser.close();                }            }        }    }}

版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案