Android进阶篇 自定义ActionBar的设计理念

      上次看到有一款省电软件,每一个页面都有一个菜单导航栏,瞬间联想到Android 原生的ActionBar,但是原生的ActionBar使用起来比较蛋疼,从事Android开发三年多了,一直没用过!所以,自己写了一个简单的ActionBar,来实现Android原生ActionBar的效果,更多地想阐述一下开发的设计理念!(纯粹胡扯,欢迎拍砖)

请看这个页面顶部有三处可变区域, 这个顶部的导航栏是一个控件,ActionBarView



为了设计这样一个控件,我们来分步拆解:

1、定义视图控件ActionBarView和接口ActionBarFactory接口

     ActionBarView负责展示视图,ActionBarFactory规定视图展示内容的样式和点击事件等

    1)ActionBarFactory.java

        createXAction返回的是每一个视图, getXSize返回的是每一个视图的尺寸(width x height), onXActioClick则是每一个视图的单击事件回调

package com.xiaojianjian.powermaster.component.actionbar;
 
import android.view.View;
/**
 * @author MarkTola
 * */
public interface ActionBarFactory {
     
    /**
     * return left action view
     * */
    public View createLeftAction();
     
    /**
     * return center action view
     * */
    public View createCenterAction();
     
    /**
     * return right action view
     * */
    public View createRightAction();
     
    /**
     * return w & h
     * */
    public int[] getLeftSize();
     
    /**
     * return w & h
     * */
    public int[] getCenterSize();
     
    /**
     * return w & h
     * */
    public int[] getRightSize();
     
    /**
     * on left click action callback
     * */
    public void onLeftActionClick(View v);
     
    /**
     * on center click action callback
     * */
    public void onCenterActionClick(View v);
     
    /**
     * on right click action callback
     * */
    public void onRightActionClick(View v);
}


2) ActionBarView

        ActionBarView的fillViews则负责组装左中右的控件

package com.xiaojianjian.powermaster.component.actionbar;
 
import com.xiaojianjian.lib.utils.ViewUtils;
 
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RelativeLayout;
/**
 * @author MarkTola
 * */
public class ActionBarView extends RelativeLayout {
    private final static String TAG = "ActionBarView";
    private ActionBarFactory mFactory;
    private View mLeftAction;
    private View mCenterAction;
    private View mRightAction;
    private int[] mLeftSize;
    private int[] mCenterSize;
    private int[] mRightSize;
    public ActionBarView(Context context) {
        this(context, null);
    }
     
    public ActionBarView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
     
    public ActionBarView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
     
    public void fillViews(ActionBarFactory factory) {
        removeAllViews();
        mFactory = factory;
        if (factory == null) {
            invalidate();
            return;
        }
         
        mLeftSize = factory.getLeftSize();
        mCenterSize = factory.getCenterSize();
        mRightSize = factory.getRightSize();
         
        mLeftAction = factory.createLeftAction();
        if (mLeftAction != null) {
            mLeftAction.setOnClickListener(mOnActionClick);
            LayoutParams leftParams = (LayoutParams) mLeftAction.getLayoutParams();
            if (leftParams == null) {
                LogUtils.d(TAG, "left params is null, recreate");
                leftParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
            }
            leftParams.width = (mLeftSize != null && mLeftSize.length > 0 ? mLeftSize[0] : LayoutParams.WRAP_CONTENT);
            leftParams.height = (mLeftSize != null && mLeftSize.length > 1 ? mLeftSize[1] : LayoutParams.FILL_PARENT);
            leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            leftParams.addRule(RelativeLayout.CENTER_VERTICAL);
            addView(mLeftAction, leftParams);
        }
         
        mCenterAction = factory.createCenterAction();
        if (mCenterAction != null) {
            mCenterAction.setOnClickListener(mOnActionClick);
            LayoutParams centerParams = (LayoutParams) mCenterAction.getLayoutParams();
            if (centerParams == null) {
                LogUtils.d(TAG, "center params is null, recreate");
                centerParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
            }
            centerParams.leftMargin = (mLeftSize != null && mLeftSize.length > 0 ? mLeftSize[0] : 0);
            centerParams.rightMargin = (mRightSize != null && mRightSize.length > 0 ? mRightSize[0] : 0);
             
            centerParams.width = (mCenterSize != null && mCenterSize.length > 0 ? mCenterSize[0] : LayoutParams.WRAP_CONTENT);
            centerParams.height = (mCenterSize != null && mCenterSize.length > 1 ? mCenterSize[1] : LayoutParams.FILL_PARENT);
             
            centerParams.addRule(RelativeLayout.CENTER_IN_PARENT);
            addView(mCenterAction, centerParams);
        }
         
        mRightAction = factory.createRightAction();
        if (mRightAction != null) {
            mRightAction.setOnClickListener(mOnActionClick);
            LayoutParams rightParams = (LayoutParams) mRightAction.getLayoutParams();
            if (rightParams == null) {
                LogUtils.d(TAG, "right params is null, recreate");
                rightParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
            }
            rightParams.width = (mRightSize != null && mRightSize.length > 0 ? mRightSize[0] : LayoutParams.WRAP_CONTENT);
            rightParams.height = (mRightSize != null && mRightSize.length > 1 ? mRightSize[1] : LayoutParams.FILL_PARENT);
            rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            rightParams.addRule(RelativeLayout.CENTER_VERTICAL);
            addView(mRightAction, rightParams);
        }
    }
     
    private OnClickListener mOnActionClick = new OnClickListener() {
         
        @Override
        public void onClick(View v) {
            if (mFactory == null 
                    || v == null) {
                return;
            }
            if (v.equals(mLeftAction)) {
                mFactory.onLeftActionClick(v);
            }
            else if (v.equals(mCenterAction)) {
                mFactory.onCenterActionClick(v);
            }
            else if (v.equals(mRightAction)) {
                mFactory.onRightActionClick(v);
            }
            else {
                // unknown
            }
        }
    };
}

自此,自定义ActionBarView 控件大工告成

2、如何使用

   1)在activity的xml中引用控件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
 
    <com.xiaojianjian.powermaster.component.actionbar.ActionBarView
        android:id="@+id/abv_action_bar"
        android:layout_width="fill_parent"
        android:layout_height="@dimen/action_bar_height" />
</LinearLayout>

  2) Activity 实现ActionBarFactory接口

       getXAction 返回具体的视图,返回null则是不显示视图;getXSize指定具体视图的尺寸,onXActionClick则是具体的执行点击事件

public class AboutUsActivity extends Activity implements ActionBarFactory {
    private ActionBarView mActionBar;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_about_us);
        initViews();
    }
     
    private void initViews() {
        mActionBar = (ActionBarView) findViewById(R.id.abv_action_bar);
        mActionBar.fillViews(this);
        }
         
        @Override
    public View createLeftAction() {
        return LayoutInflater.from(getApplicationContext()).inflate(R.layout.action_bar_back_left, null);
    }
 
    @Override
    public View createCenterAction() {
        TextView view = new TextView(getApplicationContext());
        view.setTextColor(getResources().getColorStateList(R.color.action_bar_title));
        view.setText(R.string.about_us_title);
        view.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.action_bar_title_size));
        view.setGravity(Gravity.CENTER);
        return view;
    }
 
    @Override
    public View createRightAction() {
        // TODO Auto-generated method stub
        return null;
    }
 
    @Override
    public int[] getLeftSize() {
        return new int[] {ViewUtils.dp2px(50), RelativeLayout.LayoutParams.FILL_PARENT};
    }
 
    @Override
    public int[] getCenterSize() {
        // TODO Auto-generated method stub
        return null;
    }
 
    @Override
    public int[] getRightSize() {
        // TODO Auto-generated method stub
        return null;
    }
 
    @Override
    public void onLeftActionClick(View v) {
        finish();
    }
 
    @Override
    public void onCenterActionClick(View v) {
        // TODO Auto-generated method stub
         
    }
 
    @Override
    public void onRightActionClick(View v) {
        // TODO Auto-generated method stub
         
    }
}

好的,说到这就这样了,体验demo可以在这里下载:

http://android.myapp.com/myapp/detail.htm?apkName=com.xiaojianjian.powermaster





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值