美文网首页android控件自定义ViewAndroid进阶之路
Android自定义HeadView实现导航栏效果

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

作者: Mersens | 来源:发表于2016-10-23 22:20 被阅读1789次

    前言

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

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

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

    先上效果图:

    效果图

    分析

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

    实现

    整体父布局common_head.xml

    common_head common_head

    style样式

    style样式

    左侧区域common_head_left_img.xml

    common_head_left_img

    右侧区域common_head_right_img.xml

    common_head_right_img

    layout_actionbar.xml

    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添加到布局文件中

    添加到布局文件中

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

    相关文章

      网友评论

        本文标题:Android自定义HeadView实现导航栏效果

        本文链接:https://www.haomeiwen.com/subject/xbskuttx.html