自定义Android titleBar

简介: 自定义Android titleBar

640.jpg

Android titleBar可以直接集成到每一个页面不需include布局文件,在BaseActivity集成。 不需要重新设置title,也不需要include。 加载页面的速度也提高很多;

一,自定义导航栏

1,通过TitleBuilder类构建自定义的的导航栏,左边显示返回键,中间的标题栏及副标题,右边显示菜单栏;

 * title栏根布局
 */
protected View mTitleView;// titleView
protected  RelativeLayout mTitleBgColor;
protected RelativeLayout mTitleLeftRelativeLayout;//title左边布局
protected RelativeLayout mTitleMiddleRelativeLayout;//title中间布局
protected RelativeLayout mTitleRightRelativeLayout;//title右边布局
protected ImageView mTitleLeftImageView;//title左边icon显示
protected Button mTitleLeftButton;//title左边文本显示
protected TextView mTitleMiddleTextView;//title中间文本显示
protected TextView mSubTitleTextView;//副标题文本显示
protected TextView mTitleRightTextView;//title右边文本显示
protected ImageView mTitleRightImageView;//title右边图片显示
protected ImageView mTitleRightTips;//title右边小红点提示

2,通过代码创建动态布局,省去了加载xml文件,则提高代码运行效率;

/**
     *设置一个布局容器,装载title_layout和传进来的layoutId 返回一个View视图
     * @param layoutId
     * @return
     */
    protected  View initBar(int layoutId){
        relativeLayout = new RelativeLayout(activity);
        mScrollView = new ScrollView(activity);
        RelativeLayout.LayoutParams rootLl = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
        relativeLayout.setLayoutParams(rootLl);
        mTitleView = activity.getLayoutInflater().inflate(R.layout.title_layout_activity,null);
        mTitleBgColor = (RelativeLayout) mTitleView.findViewById(R.id.title_bar_id);
        mTitleLeftRelativeLayout = (RelativeLayout) mTitleView.findViewById(R.id.left_relative_layout);
        mTitleMiddleRelativeLayout = (RelativeLayout) mTitleView.findViewById(R.id.mid_relative_layout);
        mTitleRightRelativeLayout = (RelativeLayout) mTitleView.findViewById(R.id.right_relative_layout);
        mTitleLeftImageView = (ImageView) mTitleView.findViewById(R.id.left_icon_title);
        mTitleLeftButton = (Button) mTitleView.findViewById(R.id.left_btn);
        mTitleMiddleTextView = (TextView) mTitleView.findViewById(R.id.middle_text);
        mSubTitleTextView = (TextView) mTitleView.findViewById(R.id.middle_sub_text);
        mTitleRightTextView = (TextView) mTitleView.findViewById(R.id.title_right_text);
        mTitleRightImageView = (ImageView) mTitleView.findViewById(R.id.title_right_image_view);
        mTitleRightTips = (ImageView) mTitleView.findViewById(R.id.right_new_info);
        mRootView = LayoutInflater.from(activity).inflate(layoutId,null);//activity布局文件
        RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
        rl.addRule(RelativeLayout.BELOW, R.id.title_bar_id);
        relativeLayout.addView(mTitleView);
        relativeLayout.setClipToPadding(false);
        relativeLayout.setFitsSystemWindows(true);
        relativeLayout.addView(mRootView);
        mRootView.setLayoutParams(rootLl);
//        RelativeLayout.LayoutParams rl = (RelativeLayout.LayoutParams) mRootView.getLayoutParams();//面板没有全屏
        Log.e("qxf","mRootView.getWidth():"+mRootView.getWidth()+"mRootView.getHeight():"+mRootView.getHeight()+"mRootView.getMeasuredWidth():"+mRootView.getMeasuredWidth());
        mTitleLeftButton.setOnClickListener(this);
        mTitleLeftRelativeLayout.setOnClickListener(this);
        mTitleRightRelativeLayout.setOnClickListener(this);
        mTitleMiddleRelativeLayout.setOnClickListener(this);
        return  relativeLayout;
    }

3,注册监听事件

  /**
     * 设置监听事件
     * @param mTitleBuilderListener
     */
    public void setTitleBuilderListener(TitleBuilderListener mTitleBuilderListener){
        this.mListener = mTitleBuilderListener;
    }
    @Override
    public void onClick(View view) {
        if (mListener == null) {
            return;
        }
        if (view == mTitleLeftImageView|| view == mTitleLeftButton ||  view == mTitleLeftRelativeLayout){
            mListener.onButtonClicked(TitleButton.LEFT);
        }else if (view == mTitleMiddleTextView || view == mTitleMiddleRelativeLayout){
            mListener.onButtonClicked(TitleButton.MIDDLE);
        }
        else if(view == mTitleRightRelativeLayout || view == mTitleRightImageView || view == mTitleRightTextView){
            mListener.onButtonClicked(TitleButton.RIGHT);
        }
    }
    public interface TitleBuilderListener {
        void onButtonClicked(TitleButton clicked);
    }
}

二,在BaseActivty中集成

1、baseActivity是基类,集成过导航栏,其他activity不需要再次编写导航栏了,也不用include xml布局文件,可以统一的处理导航栏,来试试吧;

public abstract class  BaseActivity extends Activity  implements TitleBuilder.TitleBuilderListener {
    public TitleBuilder mTitleBuilder;
    private int TitleBarVisible;
    private boolean isChanageStatus = true;
    private boolean isFullScreen = false;
    private boolean isFirst = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // setContentView(R.layout.activity_main);
    }
    @Override
    public void setContentView(int id) {
        this.TitleBarVisible = View.VISIBLE;
        mTitleBuilder = new TitleBuilder(this);
        this.setToolBarVisible(this.TitleBarVisible);
        super.setContentView(mTitleBuilder.initBar(id));
        this.initToolBar(mTitleBuilder);
        this.setFullScreen(isFullScreen);
        mTitleBuilder.setTitleBuilderListener(this);
        setStatusBar(this.getTitleColor(),isChanageStatus);
    }
    @Override
    public void onButtonClicked(TitleBuilder.TitleButton clicked) {
        switch (clicked) {
            case LEFT:
                finish();
                Toast.makeText(this, "this is back", Toast.LENGTH_SHORT).show();
                break;
        }
    }
    public abstract void initToolBar(TitleBuilder mTitleBuilder);
    /**
     * 设置title是否可见  默认是可见状态
     *
     * @param visible
     */
    public void setToolBarVisible(int visible) {
        if (this.mTitleBuilder.mTitleView != null) {
            if (this.TitleBarVisible == visible)
                return;
            this.mTitleBuilder.mTitleView.setVisibility(visible);
        }
        this.TitleBarVisible = visible;
    }
    /**
     * 设置状态的属性
     *
     * @param statusBar
     */
    public void setStatusBar(int statusColor,boolean statusBar) {
        this.isChanageStatus = statusBar;
        if (statusBar) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                Window win = getWindow();
                WindowManager.LayoutParams winParams = win.getAttributes();
                final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
                winParams.flags |= bits;
                win.setAttributes(winParams);
            }
            //透明状态栏
            SystemBarTintManager tintManager = new SystemBarTintManager(this);
            tintManager.setStatusBarTintEnabled(true);
            tintManager.setStatusBarTintColor(statusColor);
            //getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            tintManager.setNavigationBarTintEnabled(true);
            //透明导航栏
            // getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }
    public void setFullScreen(boolean isFullScreen) {
//        if (isFullScreen) {
//            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//        }else{
//            //getWindow().setFlags(WindowManager.LayoutParams.F,WindowManager.LayoutParams.FLAG_FULLSCREEN);
//        }
        this.isFullScreen = isFullScreen;
        if (isFullScreen) {
            WindowManager.LayoutParams lp = getWindow().getAttributes();
            lp.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
            getWindow().setAttributes(lp);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
            this.setToolBarVisible(View.GONE);
        } else {
            WindowManager.LayoutParams attr = getWindow().getAttributes();
            attr.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().setAttributes(attr);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
            this.setToolBarVisible(View.VISIBLE);
        }
    }
    @Override
    protected void onResume() {
        this.setContentScreen();
        super.onResume();
    }
    private float getScreenHeight() {
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.heightPixels;
    }
    private void setContentScreen() {
        int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        mTitleBuilder.mRootView.measure(widthSpec, heightSpec);
        mTitleBuilder.mTitleView.measure(widthSpec, heightSpec);
            mTitleBuilder.mRootView.getViewTreeObserver().addOnPreDrawListener(
                    new ViewTreeObserver.OnPreDrawListener() {
                        @Override
                        public boolean onPreDraw() {
                            float height;
                            if(isFullScreen){
                                height = mTitleBuilder.mRootView.getMeasuredHeight();
                            }else if (TitleBarVisible == View.GONE){
                                height = mTitleBuilder.mRootView.getMeasuredHeight() + getStatusBarHeight();
                            }else{
                                height = mTitleBuilder.mRootView.getMeasuredHeight() + mTitleBuilder.mTitleView.getMeasuredHeight() + getStatusBarHeight();
                            }
                            Log.e("qxf", "height:" + height + "getScreenHeight():" + getScreenHeight() + "content" + mTitleBuilder.mRootView.getMeasuredHeight());
                            if (!isFirst) {
                                if (height+1 > getScreenHeight()) {
                                    isFirst = true;
                                    Log.e("qxf", "height:" + height + "getScreenHeight():" + getScreenHeight());
                                    ViewGroup viewParent = (ViewGroup) mTitleBuilder.mRootView.getParent();
                                    Log.e("qxf", viewParent + "111111111");
                                    if (viewParent != null)
                                        viewParent.removeView(mTitleBuilder.mRootView);
                                    ScrollView scrollView = new ScrollView(BaseActivity.this);
                                    RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                                    rl.addRule(RelativeLayout.BELOW, R.id.title_bar_id);
                                    scrollView.setLayoutParams(rl);
                                    scrollView.setBackgroundColor(getResources().getColor(R.color.withe));
//                              viewParent.addView(mTitleBuilder.mTitleView);
                                    scrollView.addView(mTitleBuilder.mRootView);
                                    viewParent.addView(scrollView);
                                } else {
                                    Log.e("qxf", "getScreenHeight():" + getScreenHeight() + "mTitleBuilder.mRootView.getHeight()" + height);
                                }
                            }
                            return true;
                        }
                        });
    }
    private float getStatusBarHeight() {
        Class<?> c = null;
        Object obj = null;
        Field field = null;
        int x = 0, sbar = 0;
        try {
            c = Class.forName("com.android.internal.R$dimen");
            obj = c.newInstance();
            field = c.getField("status_bar_height");
            x = Integer.parseInt(field.get(obj).toString());
            sbar = getResources().getDimensionPixelSize(x);
        } catch (Exception e1) {
            Log.e("qxf", "get status bar height fail" + e1);
            e1.printStackTrace();
        }
       return  sbar;
    }

测试效果图:











相关文章
|
2月前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
32 1
|
3月前
|
Android开发 开发者
安卓应用开发中的自定义视图
【9月更文挑战第37天】在安卓开发的海洋中,自定义视图犹如一座座小岛,等待着勇敢的探索者去发现其独特之处。本文将带领你踏上这段旅程,从浅滩走向深海,逐步揭开自定义视图的神秘面纱。
45 3
|
3月前
|
数据可视化 Android开发 开发者
安卓应用开发中的自定义View组件
【10月更文挑战第5天】在安卓应用开发中,自定义View组件是提升用户交互体验的利器。本篇将深入探讨如何从零开始创建自定义View,包括设计理念、实现步骤以及性能优化技巧,帮助开发者打造流畅且富有创意的用户界面。
116 0
|
2月前
|
搜索推荐 前端开发 Android开发
安卓应用开发中的自定义视图实现
【10月更文挑战第30天】在安卓开发的海洋中,自定义视图是那抹不可或缺的亮色,它为应用界面的个性化和交互体验的提升提供了无限可能。本文将深入探讨如何在安卓平台创建自定义视图,并展示如何通过代码实现这一过程。我们将从基础出发,逐步引导你理解自定义视图的核心概念,然后通过一个实际的代码示例,详细讲解如何将理论应用于实践,最终实现一个美观且具有良好用户体验的自定义控件。无论你是想提高自己的开发技能,还是仅仅出于对安卓开发的兴趣,这篇文章都将为你提供价值。
|
2月前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
44 5
|
3月前
|
XML 前端开发 Java
安卓应用开发中的自定义View组件
【10月更文挑战第5天】自定义View是安卓应用开发的一块基石,它为开发者提供了无限的可能。通过掌握其原理和实现方法,可以创造出既美观又实用的用户界面。本文将引导你了解自定义View的创建过程,包括绘制技巧、事件处理以及性能优化等关键步骤。
|
4月前
|
Android开发 开发者
安卓开发中的自定义视图:从入门到精通
【9月更文挑战第19天】在安卓开发的广阔天地中,自定义视图是一块充满魔力的土地。它不仅仅是代码的堆砌,更是艺术与科技的完美结合。通过掌握自定义视图,开发者能够打破常规,创造出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战应用,一步步展示如何用代码绘出心中的蓝图。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往创意和效率的大门。让我们一起探索自定义视图的秘密,将你的应用打造成一件艺术品吧!
73 10
|
缓存 Java Android开发
|
1月前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
55 19
|
1月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
60 14