Activity中最常见的页面结构就是顶部返回键+标题(+副标题)+右侧的菜单/编辑按钮/“提交”/“发布”,将此结构封装并设置多个属性,使用时一个View即可搞定。

实现效果



图一实现代码

<包名.widgets.NavBarandroid:id="@+id/nav_bar"android:layout_width="match_parent"android:layout_height="wrap_content"app:leftIconColor="@color/black"app:navBackground="@color/background"app:navTitle="详情"app:navTitleColor="@color/black"app:rightIcon="@drawable/collect"app:showBack="true" />

attrs.xml

    <!--    顶部导航栏--><declare-styleable name="NavBar"><attr name="showBack" format="boolean" /><!--是否展示背景--><attr name="navTitle" format="string" /><!--标题文本--><attr name="navTitleColor" format="color" /><!--标题颜色--><attr name="navSubTitle" format="string" /><!--副标题文本--><attr name="leftIcon" format="reference" /><!--左侧图标--><attr name="leftIconColor" format="color" /><!--左侧图标颜色--><attr name="showLeftText" format="boolean" /><!--左侧文本--><attr name="rightIcon" format="reference" /><!--右侧图标--><attr name="navBackground" format="color" /><!--背景色--><attr name="navRightText" format="string" /><!--右侧文本--><attr name="navRightTextColor" format="color" /><!--右侧文本颜色--></declare-styleable>

NavBar.java

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;/*添加import R类*//*** 顶部导航栏*/
public class NavBar extends FrameLayout {private ImageView mIvLeft, mIvRight;private TextView mTvTitle, mTvSubTitle, mTvRight, mTvLeft;private RelativeLayout mRlRoot;/*** 显示返回*/private boolean mShowBack;/*** 显示取消*/private boolean mShowLeftText;@DrawableResprivate int mLeftSrc, mRightSrc;@ColorIntprivate int mBackgroundColor, mTitleColor, mLeftColor, mRightTextColor;private String mTitle, mSubTitle;public NavBar(@NonNull Context context) {this(context, null, 0);}public NavBar(@NonNull Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public NavBar(@NonNull final Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);// init//高度WrapContentfinal TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(new int[]{android.R.attr.actionBarSize});styledAttributes.recycle();String textRight = null;if (attrs != null) {TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.NavBar, defStyleAttr, 0);mShowBack = typedArray.getBoolean(R.styleable.NavBar_showBack, false);mTitle = typedArray.getString(R.styleable.NavBar_navTitle);mTitleColor = typedArray.getColor(R.styleable.NavBar_navTitleColor, 0);mLeftColor = typedArray.getColor(R.styleable.NavBar_leftIconColor, 0);mShowLeftText = typedArray.getBoolean(R.styleable.NavBar_showLeftText, false);mRightTextColor = typedArray.getColor(R.styleable.NavBar_navRightTextColor, 0);mSubTitle = typedArray.getString(R.styleable.NavBar_navSubTitle);mLeftSrc = typedArray.getResourceId(R.styleable.NavBar_leftIcon, 0);mRightSrc = typedArray.getResourceId(R.styleable.NavBar_rightIcon, 0);mBackgroundColor = typedArray.getColor(R.styleable.NavBar_navBackground,ContextCompat.getColor(context, R.color.colorPrimary));textRight = typedArray.getString(R.styleable.NavBar_navRightText);typedArray.recycle();}View v = LayoutInflater.from(context).inflate(R.layout.base_view_top_bar, this, false);mRlRoot = v.findViewById(R.id.rl_root);mTvTitle = v.findViewById(R.id.base_tv_title);mTvSubTitle = v.findViewById(R.id.base_tv_sub_title);mIvLeft = v.findViewById(R.id.iv_left);mTvLeft = v.findViewById(R.id.tv_left);mIvRight = v.findViewById(R.id.iv_right);mTvRight = v.findViewById(R.id.tv_right);if (mTitleColor != 0) {mTvTitle.setTextColor(mTitleColor);}if (mLeftColor != 0) {mIvLeft.setColorFilter(mLeftColor);}v.setBackgroundColor(mBackgroundColor);if (mShowBack) {mIvLeft.setVisibility(VISIBLE);mIvLeft.setImageResource(R.drawable.base_ic_back_white);mIvLeft.setOnClickListener((view) -> {((Activity) context).onBackPressed();});if (mShowLeftText) {mTvLeft.setVisibility(VISIBLE);mTvLeft.setOnClickListener((view) -> {if (context instanceof Activity) {((Activity) context).onBackPressed();}});}} else {if (mLeftSrc != 0) {mIvLeft.setVisibility(VISIBLE);mIvLeft.setImageResource(mLeftSrc);} else {mIvLeft.setVisibility(INVISIBLE);}}if (mSubTitle != null) {mTvSubTitle.setText(mSubTitle);mTvSubTitle.setVisibility(VISIBLE);} else {mTvSubTitle.setVisibility(GONE);}if (mRightSrc != 0) {mIvRight.setVisibility(VISIBLE);mIvRight.setImageResource(mRightSrc);} else {mIvRight.setVisibility(INVISIBLE);}if (textRight != null) {mTvRight.setVisibility(VISIBLE);mTvRight.setText(textRight);if (mRightTextColor != 0) {mTvRight.setTextColor(mRightTextColor);}} else {mTvRight.setVisibility(GONE);}mTvTitle.setText(mTitle);addView(v);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int heightMode = MeasureSpec.getMode(heightMeasureSpec);if (heightMode == MeasureSpec.EXACTLY) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);measureChildren(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),MeasureSpec.getSize(heightMeasureSpec));} else {super.onMeasure(widthMeasureSpec, heightMeasureSpec);measureChildren(widthMeasureSpec, heightMeasureSpec);}}@Overrideprotected void measureChildren(int widthMeasureSpec, int heightMeasureSpec) {super.measureChildren(widthMeasureSpec, heightMeasureSpec);}public RelativeLayout getRoot() {return mRlRoot;}/*** 获取左边imageView*/public ImageView getLeftImageView() {return mIvLeft;}/*** 获取右边ImageView*/public ImageView getRightImageView() {return mIvRight;}/*** 获取标题** @return {@link TextView}*/public TextView getTitleTextView() {return mTvTitle;}/*** 获取副标题*/public TextView getSubTitleTextView() {return mTvSubTitle;}/*** 获取左面的TextView*/public TextView getLeftTextView() {return mTvLeft;}/*** 获取右侧文本*/public TextView getRightTextView() {return mTvRight;}
}

base_view_top_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/rl_root"android:layout_width="match_parent"android:layout_height="50dp"android:background="@android:color/transparent"android:paddingLeft="10dp"android:paddingTop="10dp"android:paddingRight="10dp"android:paddingBottom="10dp"tools:background="@color/colorPrimary"><ImageViewandroid:id="@+id/iv_left"android:layout_width="30dp"android:layout_height="35dp"android:layout_centerVertical="true"android:scaleType="centerInside"android:src="@drawable/base_ic_back_dark" /><TextViewandroid:id="@+id/tv_left"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_toRightOf="@id/iv_left"android:text="取消"android:textColor="@color/black"android:textSize="18sp"android:visibility="gone" /><ImageViewandroid:id="@+id/iv_right"android:layout_width="40dp"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_centerVertical="true"android:scaleType="centerInside" /><TextViewandroid:id="@+id/tv_right"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_alignParentRight="true"android:gravity="center_vertical"android:lines="1"android:paddingStart="5dp"android:paddingEnd="5dp"android:singleLine="true"android:textColor="#FF333333"android:textSize="18sp"android:visibility="gone"tools:text="确定" /><TextViewandroid:id="@+id/base_tv_sub_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:layout_marginBottom="8dp"android:drawablePadding="3dp"android:lines="1"android:singleLine="true"android:textColor="#FF333333"android:textSize="10sp"android:visibility="gone" /><TextViewandroid:id="@+id/base_tv_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_above="@id/base_tv_sub_title"android:layout_centerInParent="true"android:layout_marginStart="30dp"android:layout_marginEnd="30dp"android:layout_toLeftOf="@id/iv_right"android:layout_toRightOf="@id/iv_left"android:ellipsize="end"android:gravity="center"android:lines="1"android:singleLine="true"android:textColor="@color/black"android:textFontWeight="500"android:textSize="18sp" />
</RelativeLayout>

Android自定义View 顶部导航栏相关推荐

  1. Vue自定义网页顶部导航栏

    Vue自定义web网页顶部导航栏 说明:此组件是为论坛类项目定制的一个实用的顶部导航栏,当然也可以用于其他的Web项目,只需要稍作修改便可以达到想要的效果.其中导航栏包含了搜索栏,用户头像,以及基本的 ...

  2. 微信小程序自定义navigationBar顶部导航栏,兼容安卓ios

    1.设置导航栏自定义"navigationStyle":"custom" "pages": [ //pages数组中第一项表示应用启动页,参 ...

  3. 小程序自定义顶部导航栏

    上篇博客自定义了一个底部导航栏,效果还可以,但是我在开发过程中又遇到了一个棘手的问题.就是在底部导航栏的第一个页面需要将页面沉浸到状态栏去,这就麻烦了,因为中间的容器页面无论第几个都是在外面的主界面里 ...

  4. php仿微信底部菜单,Android实现简单底部导航栏 Android仿微信滑动切换效果

    Android仿微信滑动切换最终实现效果: 大体思路: 1. 主要使用两个自定义View配合实现; 底部图标加文字为一个自定义view,底部导航栏为一个载体,根据需要来添加底部图标; 2. 底部导航栏 ...

  5. android仿微信的activity平滑水平切换动画,Android实现简单底部导航栏 Android仿微信滑动切换效果...

    Android实现简单底部导航栏 Android仿微信滑动切换效果 发布时间:2020-10-09 19:48:00 来源:脚本之家 阅读:96 作者:丶白泽 Android仿微信滑动切换最终实现效果 ...

  6. android滑动菜单图标,Android实现简单底部导航栏 Android仿微信滑动切换效果

    Android仿微信滑动切换最终实现效果: 大体思路: 1. 主要使用两个自定义View配合实现; 底部图标加文字为一个自定义view,底部导航栏为一个载体,根据需要来添加底部图标; 2. 底部导航栏 ...

  7. android 底部滑动效果怎么做,Android实现简单底部导航栏 Android仿微信滑动切换效果...

    android仿微信滑动切换最终实现效果: 大体思路: 1. 主要使用两个自定义view配合实现; 底部图标加文字为一个自定义view,底部导航栏为一个载体,根据需要来添加底部图标; 2. 底部导航栏 ...

  8. 微信小程序实现顶部导航栏渐变

    在小程序开发的过程中,会遇到一些页面上的要求,要求实现顶部导航栏的渐变如何实现,因为小程序做了一些封装,下面看看页面的布局图: 如图所示,实际上我们能够操作的页面只有中间那一块,那么,如果客户需要使用 ...

  9. android 顶部导航栏 自定义,Android自定义NavigationController - 安卓自定义导航栏 --【WJ】...

    注意: 本文主要介绍安卓自定义顶部导航栏(iOS中成为NavigationBar):写的不尽如人意的地方,请见谅~ 概述如下: 环境 :Android Studio 1.4 for Mac 语言 :如 ...

  10. Android 开发:(十四)NavigationBar篇-自定义顶部导航栏

    本篇记录了navigation bar顶部导航栏的自定义方法,抛砖引玉,简单实现了常用的布局,在此基础上可添加较复杂的布局. 第一步:新建NavigationBar文件,继承与FrameLayout. ...

最新文章

  1. tf热保护怎么安装_SEW-电机热保护说明
  2. C语言学习之有4个圆塔,圆心分别为(2,2)、(-2,2)、(-2,-2)、(2,-2),圆半径为1
  3. pay-as-you-go
  4. nginx windows 下安装和配置
  5. 外设驱动库开发笔记8:GPIO模拟I2C驱动
  6. Linux下WebLogic 12c启动、部署命令行
  7. 【转】context和getApplicationContext()介绍
  8. OBS( Open Broadcaster Software )录制视频黑屏问题录制方法
  9. PIL图像处理时使用np.unit8转化报错: Cannot handle this data type: (1, 1), |O
  10. 03.Web大前端时代之:HTML5+CSS3入门系列~H5功能元素
  11. c++ vector排序_C++ vector动态数组的常见操作
  12. Java词法分析器的设计与实现
  13. r语言和python的区别-Python和R语言的区别?
  14. wifi 小米pro 驱动 黑苹果_小米Pro 15.6英寸(i7 8550U-MX110)游戏本黑苹果
  15. 3DSMAX联机渲染、网络渲染、分布式渲染效率评测
  16. VMware如何导出和导入OVF文件
  17. SQLMAP进阶使用 --tamper
  18. 三大主流Mac清理软件实测:Cleaner One | 柠檬清理 | CleanmyMac
  19. 《腾讯数字生活报告2019》发布,互联网时代新马斯洛需求金字塔预示什么?
  20. noj 2112 拯救活动室的男女比例(最大费用最大流)

热门文章

  1. Chrome打不开baidu首页的问题
  2. 解决登录雅虎邮箱提示您在所用浏览器上启用Javascript 功能
  3. cubemx配置时调试SYS显示警报
  4. 注册页面获取手机验证码
  5. Hadoop大数据技术课程总结2021-2022学年第1学期
  6. db mysql导入_db mysql导入数据库
  7. lis =[2,3,'k',['qwe',20,['k1',['tt',3,'1']],89],'ab','adv'] 将列表lis中的'tt'变成大写(用两种方式)。...
  8. 陕甘回变——关陕残月(二)
  9. ppt背景图片怎么更换应用到全部
  10. 阿里云服务器使用宝塔面板管理以及项目部署