上次看到有一款省电软件,每一个页面都有一个菜单导航栏,瞬间联想到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