Android自定义HeadView实现导航栏效果

前言

在Android应用的开发中少不了导航栏的使用,Android 3.0  推了 ActionBar, 5.0开始推出的一个 Material Design 风格的导航控件Toolbar,这些控件也是在致力于帮助我们在App中打造一个统一的导航栏规范,在App上显得更加整体化。Toolbar相比ActionBar更加灵活,可以放到布局中的任何位置,不局限于顶部,开放了很多API,留给了开发者更多的扩展余地,相信很多开发者更乐于使用Toolbar,但是在这里我不打算遵循传统。

在项目开发中谷歌提供的这些控件可能无法满足我们项目需求,这个时候就需要通过自定义来实现,当然,这里我们就自定义一个HeadView,同样可以实现灵活,可扩展性强的导航栏。

通过自定义控件不仅仅是实现了导航栏的功能,更重要的是我们对自定义流程的明晰和实践的总结。

先上效果图:


Android自定义HeadView实现导航栏效果_第1张图片
效果图

分析

导航栏一般分为三个内容区域:左侧区域,中间标题栏,右侧区域,左侧和右侧通常是一个按钮或者ImageView,中间标题为TextView.因此我们可以把它分为三部分来实现,整体的父布局采用RelativeLayout,里面的三个区域采用LinearLayout,对外提供设置方法传递资源文件和监听接口回调。

实现

整体父布局common_head.xml

Android自定义HeadView实现导航栏效果_第2张图片
common_head
Android自定义HeadView实现导航栏效果_第3张图片
common_head

style样式

Android自定义HeadView实现导航栏效果_第4张图片
style样式


左侧区域common_head_left_img.xml

Android自定义HeadView实现导航栏效果_第5张图片
common_head_left_img

右侧区域common_head_right_img.xml

Android自定义HeadView实现导航栏效果_第6张图片
common_head_right_img

layout_actionbar.xml

Android自定义HeadView实现导航栏效果_第7张图片
layout_actionbar


HeadView的实现


private LinearLayout header_leftview_container;

private LinearLayout header_layout_rightview_container;

private ImageView left_button;

private ImageView right_button;

private LayoutInflater mInflater;

private TextViewtv_title;

private View header;

private OnLeftClickListener onleftclicklistener;

private OnRightClickListener onrightclicklistener;

一个参数的构造方法

public HeadView(Context context) {

this(context,null);

}

两个参数的构造方法

public HeadView(Context context, AttributeSet attrs) {

this(context, attrs,0);

}

三个构造参数的方法里面进行初始化操作init()

public HeadView(Context context, AttributeSet attrs,intdefStyleAttr) {

super(context, attrs, defStyleAttr);

init(context);

}

初始化方法init()

@SuppressLint("InflateParams")

private void init(Context context) {

mInflater= LayoutInflater.from(context);

header=mInflater.inflate(R.layout.common_head,null);

addView(header);

initViews();

}

枚举类型用于标示显示的模式

/**

*

*@authorMersens

*枚举类型的标题栏显示类型DEFAULT--默认显示左侧图标,右侧图标和标题ONLYTITLE--只显示标题

*  LEFT--只显示左侧图标LEFTANDTITLE--只显示左侧图标和标题

*/

public enum HeaderStyle {

DEFAULT,ONLYTITLE,LEFT,LEFTANDTITLE,RIGHTANDTITLE;

}

对外提供init初始化方法,改方法传递一个枚举,用于初始化时候的模式

/**

*@authorMersens

根据类型进行初始化,可以通过addView()方法动态添加控件,然后设置其控件的显示

*@paramstyle

*/

public void init(HeaderStyle style) {

switch(style) {

caseDEFAULT:

removeViews();

defaultMethod();

break;

caseONLYTITLE:

removeViews();

tileMethod();

break;

caseLEFT:

removeViews();

leftMethod();

break;

caseLEFTANDTITLE:

removeViews();

backAndTitleMethod();

break;

caseRIGHTANDTITLE:

removeViews();

rightandtitle();

break;

}}

初始化右侧布局和title

private void rightandtitle() {

//设置title为可见

tv_title.setVisibility(View.VISIBLE);

View right_button_view =mInflater.inflate(

R.layout.common_head_right_img,null);

right_button= (ImageView) right_button_view

.findViewById(R.id.right_imageView);

//初始化右侧按钮,并添加到右侧父布局内

header_layout_rightview_container.addView(right_button_view);

right_button.setOnClickListener(newOnClickListener() {

@Override

public voidonClick(View v) {

//接口回调

if(onrightclicklistener!=null) {

onrightclicklistener.onClick();

}}});}

移除父布局内部的所有子控件

/**

*移除左右控件的子View

*/

private void removeViews() {

header_leftview_container.removeAllViews();

header_layout_rightview_container.removeAllViews();

}

初始化设置默认的模式,左侧,右侧和中间的标题都会显示

@SuppressLint("InflateParams")

public void defaultMethod() {

//设置title为可见

tv_title.setVisibility(View.VISIBLE);

View left_button_view =mInflater.inflate(

R.layout.common_head_left_img,null);

left_button= (ImageView) left_button_view.findViewById(R.id.imageView);

//初始化左侧按钮,并添加到左侧父布局内

header_leftview_container.addView(left_button_view);

View right_button_view =mInflater.inflate(

R.layout.common_head_right_img,null);

right_button= (ImageView) right_button_view

.findViewById(R.id.right_imageView);

//初始化右侧按钮,并添加到右侧父布局内

header_layout_rightview_container.addView(right_button_view);

left_button.setOnClickListener(newOnClickListener() {

@Override

public voidonClick(View v) {

//接口回调

if(onleftclicklistener!=null) {

onleftclicklistener.onClick();

}}});

right_button.setOnClickListener(newOnClickListener() {

@Override

public voidonClick(View v) {

//接口回调

if(onrightclicklistener!=null) {

onrightclicklistener.onClick();

}}});}

初始化只显示中间标题

public void tileMethod() {

tv_title.setVisibility(View.VISIBLE);

}

初始化左侧按钮布局

public void leftMethod() {

//初始化左侧按钮,并添加到左侧父布局内

View left_button_view =mInflater.inflate(

R.layout.common_head_left_img,null);

left_button= (ImageView) left_button_view.findViewById(R.id.imageView);

header_leftview_container.addView(left_button_view);

//添加监听事件

left_button.setOnClickListener(newOnClickListener() {

@Override

public voidonClick(View v) {

if(onleftclicklistener!=null) {

onleftclicklistener.onClick();

}}});}

对外提供设置左侧和中间标题的方法

private void backAndTitleMethod() {

tv_title.setVisibility(View.VISIBLE);

View left_button_view =mInflater.inflate(

R.layout.common_head_left_img,null);

left_button= (ImageView) left_button_view.findViewById(R.id.imageView);

header_leftview_container.addView(left_button_view);

left_button.setOnClickListener(newOnClickListener() {

@Override

public voidonClick(View v) {

if(onleftclicklistener!=null) {

onleftclicklistener.onClick();

}}});}

对外提供设置默认的显示模式,需要传递资源文件

public void setDefaultViewMethod(intleftsrcid, String title,

intrightsrcid, OnLeftClickListener onleftclicklistener,

OnRightClickListener onrightclicklistener) {

if(!TextUtils.isEmpty(title)) {

tv_title.setText(title);}

if(leftsrcid !=0)

left_button.setBackgroundResource(leftsrcid);

else

left_button.setBackgroundResource(R.mipmap.ic_menu_back);

if(rightsrcid !=0)

right_button.setBackgroundResource(rightsrcid);

else

right_button.setBackgroundResource(R.mipmap.ic_menu_camera);

setOnLeftClickListener(onleftclicklistener);

setOnRightClickListener(onrightclicklistener);

}

设置右侧和中间标题的方法

public void setRightAndTitleMethod(String title,intrightsrcid,

OnRightClickListeneronrightclicklistener) {

if(!TextUtils.isEmpty(title)) {

tv_title.setText(title);}

if(rightsrcid !=0)

right_button.setBackgroundResource(rightsrcid);

else

right_button.setBackgroundResource(R.mipmap.ic_menu_camera);

setOnRightClickListener(onrightclicklistener);

}

设置显示左侧和中间内容方法

public void setLeftWithTitleViewMethod(intleftsrcid, String title,

OnLeftClickListener onleftclicklistener) {

if(!TextUtils.isEmpty(title)) {

tv_title.setText(title);}

if(leftsrcid !=0)

left_button.setBackgroundResource(leftsrcid);

else

left_button.setBackgroundResource(R.mipmap.ic_menu_back);

setOnLeftClickListener(onleftclicklistener);

}

设置只显示中间标题的方法

public void setOnlyTileViewMethod(String title) {

if(!TextUtils.isEmpty(title)) {

tv_title.setText(title);

}}

设置只有右侧区域内容的方法

public void setLeftViewMethod(intleftsrcid,

OnLeftClickListener onleftclicklistener) {

if(leftsrcid !=0)

left_button.setBackgroundResource(leftsrcid);

else

left_button.setBackgroundResource(R.mipmap.ic_menu_back);

setOnLeftClickListener(onleftclicklistener);

}

左侧区域的点击回调接口

/**

*@author Mersens

*自定义接口回调,用于处理左侧按钮的点击事件

*/

public interfaceOnLeftClickListener {

voidonClick();

}

提供左侧区域set设置方法

public void setOnLeftClickListener(OnLeftClickListener onleftclicklistener) {

this.onleftclicklistener= onleftclicklistener;

}

右侧区域的点击回调接口

/**

*@author Mersens

*自定义接口回调,用于处理右侧侧按钮的点击事件

*/

public interface OnRightClickListener {

voidonClick();

}

提供右侧区域set设置方法

public void setOnRightClickListener(

OnRightClickListener onrightclicklistener) {

this.onrightclicklistener= onrightclicklistener;

}


我们在开发中通常会封装一些东西在BaseActivity中,当然,这里我们也采用封装的方式,我们写一个BaseActivity,让他继承AppCompatActivity,然后再内部提供设置的方法就可以:

设置默认方式

public void setDefaultViewMethod(intleftsrcid, String title,intrightsrcid, HeadView.OnLeftClickListener onleftclicklistener, HeadView.OnRightClickListener onrightclicklistener) {

mHeadView= (HeadView) findViewById(R.id.common_actionbar);

mHeadView.init(HeadView.HeaderStyle.DEFAULT);

mHeadView.setDefaultViewMethod(leftsrcid, title, rightsrcid, onleftclicklistener, onrightclicklistener);

}

设置右侧内容和标题

public void setRightAndTitleMethod(String title,intrightsrcid, HeadView.OnRightClickListener onRightClickListener) {

mHeadView= (HeadView) findViewById(R.id.common_actionbar);

mHeadView.init(HeadView.HeaderStyle.RIGHTANDTITLE);

mHeadView.setRightAndTitleMethod(title, rightsrcid, onRightClickListener);

}

设置左侧内容和标题

public void setLeftWithTitleViewMethod(intleftsrcid, String title, HeadView.OnLeftClickListener onleftclicklistener) {

mHeadView= (HeadView) findViewById(R.id.common_actionbar);

mHeadView.init(HeadView.HeaderStyle.LEFTANDTITLE);

mHeadView.setLeftWithTitleViewMethod(leftsrcid, title, onleftclicklistener);

}

设置仅显示标题文字

public void setOnlyTileViewMethod(String title) {

mHeadView= (HeadView) findViewById(R.id.common_actionbar);

mHeadView.init(HeadView.HeaderStyle.ONLYTITLE);

mHeadView.setOnlyTileViewMethod(title);

}

设置仅显示左侧区域内容

public void setLeftViewMethod(intleftsrcid, HeadView.OnLeftClickListener onleftclicklistener) {

mHeadView= (HeadView) findViewById(R.id.common_actionbar);

mHeadView.init(HeadView.HeaderStyle.LEFT);

mHeadView.setLeftViewMethod(leftsrcid, onleftclicklistener);

}


How to use

需要通过include把我们的HeadView添加到布局文件中

Android自定义HeadView实现导航栏效果_第8张图片
添加到布局文件中

在Activit中只需要调用BaseActivity中对外提供的设置方法就行

Android自定义HeadView实现导航栏效果_第9张图片

你可能感兴趣的:(Android自定义HeadView实现导航栏效果)