自定义控件,代码如下public class ActionBar extends LinearLayout {    public static final int NONE = 0;    public enum Type {
        Normal,
        Dashboard,
        Empty
    }    public interface OnActionBarListener {        /**
         * Index used to indicate the ActionBar home item has been clicked.
         */
        int HOME_ITEM = -1;        void onActionBarItemClicked(int position);
    }    private TextView mTitleView;
    private ImageButton mHomeButton;
    private ImageView mHomeView;    private boolean mMerging = false;    private CharSequence mTitle;
    private ActionBar.Type mType;
    private OnActionBarListener mOnActionBarListener;
    private LinkedList<ActionBarItem> mItems;    private Drawable mDividerDrawable;
    private Drawable mHomeDrawable;
    private int mDividerWidth;    private int mMaxItemsCount;    public ActionBar(Context context) {
        this(context, null);
    }    public ActionBar(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.gdActionBarStyle);
    }    public ActionBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs);        initActionBar();        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar, defStyle, 0);        mTitle = a.getString(R.styleable.ActionBar_title);        mDividerDrawable = a.getDrawable(R.styleable.ActionBar_dividerDrawable);
        mDividerWidth = a.getDimensionPixelSize(R.styleable.ActionBar_dividerWidth, -1);
        mHomeDrawable = a.getDrawable(R.styleable.ActionBar_homeDrawable);
        mMaxItemsCount = a.getInt(R.styleable.ActionBar_maxItems, 3);
        if (mHomeDrawable == null) {
            mHomeDrawable = new ActionBarDrawable(context, R.drawable.gd_action_bar_home);
        }        int layoutID;
        int type = a.getInteger(R.styleable.ActionBar_type, -1);
        switch (type) {
            case 2:
                mType = Type.Empty;
                layoutID = R.layout.gd_action_bar_empty;
                break;
            case 1:
                mType = Type.Dashboard;
                layoutID = R.layout.gd_action_bar_dashboard;
                break;
            case 0:
            default:
                mType = Type.Normal;
                layoutID = R.layout.gd_action_bar_normal;
                break;
        }        // HACK Cyril: Without this, the onFinishInflate is called twice !?!
        // This issue is due to a bug when Android inflates a layout with a
        // parent - which is compulsory with a <merge /> tag. I've reported this
        // bug to Romain Guy who fixed it (patch will probably be available in
        // the Gingerbread release).
        mMerging = true;
        LayoutInflater.from(context).inflate(layoutID, this);
        mMerging = false;        a.recycle();
    }    private void initActionBar() {
        mItems = new LinkedList<ActionBarItem>();
    }    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();        if (!mMerging) {            switch (mType) {
                case Dashboard:
//                    mHomeButton = (ImageButton) findViewById(R.id.gd_action_bar_home_item);
//                    mHomeButton.setOnClickListener(mClickHandler);
                
                 mHomeView = (ImageView) findViewById(R.id.gd_action_bar_home_item);
                 mHomeView.setImageDrawable(mHomeDrawable);
                 mTitleView = (TextView) findViewById(R.id.gd_action_bar_title);
                    setTitle(mTitle);
                    break;                case Empty:
                    mTitleView = (TextView) findViewById(R.id.gd_action_bar_title);
                    setTitle(mTitle);
                    break;                case Normal:
                default:
                    mHomeButton = (ImageButton) findViewById(R.id.gd_action_bar_home_item);
                    mHomeButton.setOnClickListener(mClickHandler);
                    mHomeButton.setImageDrawable(mHomeDrawable);
                    mHomeButton.setContentDescription(getContext().getString(R.string.gd_go_home));
                    mTitleView = (TextView) findViewById(R.id.gd_action_bar_title);
                    setTitle(mTitle);
                    break;            }
        }
    }    /**
     * Register a callback to be invoked when the user interacts with the
     * {@link ActionBar}.
     * 
     * @param listener The callback that will run.
     */
    public void setOnActionBarListener(OnActionBarListener listener) {
        mOnActionBarListener = listener;
    }    /**
     * @param title The title to set to this {@link ActionBar}
     */
    public void setTitle(CharSequence title) {
        mTitle = title;
        if (mTitleView != null) {
            mTitleView.setText(title);
        }
    }    /**
     * @param actionBarItemType
     * @return
     */
    public ActionBarItem addItem(ActionBarItem.Type actionBarItemType) {
        return addItem(ActionBarItem.createWithType(this, actionBarItemType), NONE);
    }    /**
     * @param actionBarItemType
     * @param itemId
     * @return
     */
    public ActionBarItem addItem(ActionBarItem.Type actionBarItemType, int itemId) {
        return addItem(ActionBarItem.createWithType(this, actionBarItemType), itemId);
    }    /**
     * @param item
     * @return
     */
    public ActionBarItem addItem(ActionBarItem item) {
        return addItem(item, NONE);
    }    /**
     * @param item
     * @param itemId
     * @return
     */
    public ActionBarItem addItem(ActionBarItem item, int itemId) {        if (mItems.size() >= mMaxItemsCount) {
            /*
             * An ActionBar must contain as few items as possible. So let's keep
             * a limit :)
             */
            return null;
        }        if (item != null) {            item.setItemId(itemId);            if (mDividerDrawable != null) {
                ImageView divider = new ImageView(getContext());
                int dividerWidth = (mDividerWidth > 0) ? mDividerWidth : mDividerDrawable.getIntrinsicWidth();
                final LinearLayout.LayoutParams lp = new LayoutParams(dividerWidth, LayoutParams.FILL_PARENT);
                divider.setLayoutParams(lp);
                divider.setBackgroundDrawable(mDividerDrawable);
                addView(divider);
            }            final View itemView = item.getItemView();
            itemView.findViewById(R.id.gd_action_bar_item).setOnClickListener(mClickHandler);            final int size = (int) getResources().getDimension(R.dimen.gd_action_bar_height);
            addView(itemView, new LayoutParams(size, LayoutParams.FILL_PARENT));            mItems.add(item);
        }        return item;
    }    /**
     * @param position
     * @return
     */
    public ActionBarItem getItem(int position) {
        if (position < 0 || position >= mItems.size()) {
            return null;
        }
        return mItems.get(position);
    }    /**
     * @param item
     */
    public void removeItem(ActionBarItem item) {
        removeItem(mItems.indexOf(item));
    }    /**
     * @param position
     */
    public void removeItem(int position) {        if (position < 0 || position >= mItems.size()) {
            return;
        }        final int viewIndex = indexOfChild(mItems.get(position).getItemView());
        final int increment = (mDividerDrawable != null) ? 1 : 0;
        removeViews(viewIndex - increment, 1 + increment);
        mItems.remove(position);
    }    /**
     * @param type
     */
    public void setType(Type type) {
        if (type != mType) {            removeAllViews();            int layoutId = 0;
            switch (type) {
                case Empty:
                    layoutId = R.layout.gd_action_bar_empty;
                    break;
                case Dashboard:
                    layoutId = R.layout.gd_action_bar_dashboard;
                    break;
                case Normal:
                    layoutId = R.layout.gd_action_bar_normal;
                    break;
            }            mType = type;
            LayoutInflater.from(getContext()).inflate(layoutId, this);            // Reset all items
            LinkedList<ActionBarItem> itemsCopy = new LinkedList<ActionBarItem>(mItems);
            mItems.clear();
            for (ActionBarItem item : itemsCopy) {
                addItem(item);
            }
        }
    }    /**
     * @param klass
     * @return
     */
    public ActionBarItem newActionBarItem(Class<? extends ActionBarItem> klass) {
        try {
            ActionBarItem item = klass.newInstance();
            item.setActionBar(this);
            return item;
        } catch (Exception e) {
            throw new IllegalArgumentException("The given klass must have a default constructor");
        }
    }    private OnClickListener mClickHandler = new OnClickListener() {        public void onClick(View v) {
            if (mOnActionBarListener != null) {                if (v == mHomeButton) {
                    mOnActionBarListener.onActionBarItemClicked(OnActionBarListener.HOME_ITEM);
                    return;
                }                final int itemCount = mItems.size();
                for (int i = 0; i < itemCount; i++) {
                    final ActionBarItem item = mItems.get(i);
                    final View itemButton = item.getItemView().findViewById(R.id.gd_action_bar_item);
                    if (v == itemButton) {
                        item.onItemClicked();
                        mOnActionBarListener.onActionBarItemClicked(i);
                        break;
                    }
                }
            }
        }    };}自定义控件Android加载xmlBinary

解决方案 »

  1.   

    引用自定义控件的xml文件如下<?xml version="1.0" encoding="utf-8"?>
    <!-- 定义一个垂直排列的LinearLayout -->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:bar="http://schemas.android.com/apk/res/com.ht.pm.activity"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:divider="?android:attr/dividerHorizontal"
        android:orientation="vertical"
        android:showDividers="middle" > <com.leaf.actionbar.ActionBar
            android:id="@id/gd_action_bar" 
    android:layout_height="@dimen/gd_action_bar_height"
    android:layout_width="fill_parent"
    android:background="?attr/gdActionBarBackground"
    bar:type="normal"
    bar:title="Test ActionBar" />
    <FrameLayout
    android:id="@+id/discount_fl_container"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="3" />
    </LinearLayout>
      

  2.   

    log如下05-31 10:00:55.340: E/AndroidRuntime(24514): FATAL EXCEPTION: main
    05-31 10:00:55.340: E/AndroidRuntime(24514): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ht.pm.activity/com.ht.pm.discount.DiscountActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class com.leaf.actionbar.ActionBar
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.os.Handler.dispatchMessage(Handler.java:99)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.os.Looper.loop(Looper.java:137)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.app.ActivityThread.main(ActivityThread.java:4745)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at java.lang.reflect.Method.invokeNative(Native Method)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at java.lang.reflect.Method.invoke(Method.java:511)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:810)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:577)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at dalvik.system.NativeStart.main(Native Method)
    05-31 10:00:55.340: E/AndroidRuntime(24514): Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class com.leaf.actionbar.ActionBar
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.view.LayoutInflater.createView(LayoutInflater.java:613)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:256)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.app.Activity.setContentView(Activity.java:1867)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at com.ht.pm.discount.DiscountActivity.onCreate(DiscountActivity.java:28)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.app.Activity.performCreate(Activity.java:5008)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  ... 11 more
    05-31 10:00:55.340: E/AndroidRuntime(24514): Caused by: java.lang.reflect.InvocationTargetException
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at java.lang.reflect.Constructor.constructNative(Native Method)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.view.LayoutInflater.createView(LayoutInflater.java:587)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  ... 22 more
    05-31 10:00:55.340: E/AndroidRuntime(24514): Caused by: android.content.res.Resources$NotFoundException: Resource is not a Drawable (color or path): TypedValue{t=0x2/d=0x7f010001 a=-1}
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.content.res.Resources.loadDrawable(Resources.java:1892)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.view.View.<init>(View.java:3336)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.view.ViewGroup.<init>(ViewGroup.java:427)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.widget.LinearLayout.<init>(LinearLayout.java:176)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at android.widget.LinearLayout.<init>(LinearLayout.java:172)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at com.leaf.actionbar.ActionBar.<init>(ActionBar.java:133)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  at com.leaf.actionbar.ActionBar.<init>(ActionBar.java:129)
    05-31 10:00:55.340: E/AndroidRuntime(24514):  ... 25 more
      

  3.   

    主要是句错误java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ht.pm.activity/com.ht.pm.discount.DiscountActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class com.leaf.actionbar.ActionBar
      

  4.   

    是xml的问题看看layout里面是不是哪个控件没有resource
    问题是这里导致的 Caused by: android.content.res.Resources$NotFoundException: Resource is not a Drawable (color or path): TypedValue{t=0x2/d=0x7f010001 a=-1}
      

  5.   

    同意楼上,重点看下mHomeDrawable这个变量。