1.设置属性(供XML调用)

在res目录新建attrs.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyTopBar">
<attr name="title" format="string"/>
<attr name="titleSize" format="dimension"/>
<attr name="titleColor" format="color"/> <attr name="leftButtonText" format="string"/>
<attr name="leftButtonTextSize" format="dimension"/>
<attr name="leftButtonTextColor" format="color"/>
<attr name="leftButtonTextBackGround" format="reference|color"/> <attr name="rightButtonText" format="string"/>
<attr name="rightButtonTextSize" format="dimension"/>
<attr name="rightButtonTextColor" format="color"/>
<attr name="rightButtonTextBackGround" format="reference|color"/> <attr name="rightButtonText2" format="string"/>
<attr name="rightButtonTextSize2" format="dimension"/>
<attr name="rightButtonTextColor2" format="color"/>
<attr name="rightButtonTextBackGround2" format="reference|color"/>
</declare-styleable>
</resources>

2.创建自定义继承于(view/viewGroup/各种组件)

public class MyTopBar extends RelativeLayout {
//TopBar容器包含的组件
private Button mLeftButton, mRightButton, mRightButton2;
private TextView mTitleTextView; // 布局属性,用来控制组件元素在ViewGroup中的位置
private LayoutParams mLeftParams, mTitleParams, mRightParams, mRightParams2; //定义title属性
private String mTitle;
private int mTitleColor;
private float mTitleSize;
//定义leftButton属性
private String mLeftButtonText;
private float mLeftButtonTextSize;
private int mLeftButtonTextColor;
private Drawable mLeftButtonTextBackGround;
//定义最右边的RightButton属性
private String mRightButtonText;
private float mRightButtonTextSize;
private int mRightButtonTextColor;
private Drawable mRightButtonTextBackGround;
//定义倒数第二个rightButton的属性
private String mRightButtonText2;
private float mRightButtonTextSize2;
private int mRightButtonTextColor2;
private Drawable mRightButtonTextBackGround2; // 映射传入的接口对象
private topBarClickListener mListener; public MyTopBar(Context context) {
super(context);
} //这个构造函数是包含attrs的,XML在加载时候会调用这个构造函数
public MyTopBar(Context context, AttributeSet attrs) {
super(context, attrs);
/*
1.把所有的attrs的值添加到TypeArray中
*/
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyTopBar);
//把TypeArray中的值取出来
mTitle = typedArray.getString(R.styleable.MyTopBar_title);
mTitleColor = typedArray.getColor(R.styleable.MyTopBar_titleColor, 0);
mTitleSize = typedArray.getDimension(R.styleable.MyTopBar_titleSize, 10); mLeftButtonText = typedArray.getString(R.styleable.MyTopBar_leftButtonText);
mLeftButtonTextColor = typedArray.getColor(R.styleable.MyTopBar_leftButtonTextColor, 0);
mLeftButtonTextSize = typedArray.getDimension(R.styleable.MyTopBar_leftButtonTextSize, 10);
mLeftButtonTextBackGround = typedArray.getDrawable(R.styleable.MyTopBar_leftButtonTextBackGround); mRightButtonText = typedArray.getString(R.styleable.MyTopBar_rightButtonText);
mRightButtonTextColor = typedArray.getColor(R.styleable.MyTopBar_rightButtonTextColor, 0);
mRightButtonTextSize = typedArray.getDimension(R.styleable.MyTopBar_rightButtonTextSize, 10);
mRightButtonTextBackGround = typedArray.getDrawable(R.styleable.MyTopBar_rightButtonTextBackGround); mRightButtonText2 = typedArray.getString(R.styleable.MyTopBar_rightButtonText2);
mRightButtonTextColor2 = typedArray.getColor(R.styleable.MyTopBar_rightButtonTextColor2, 0);
mRightButtonTextSize2 = typedArray.getDimension(R.styleable.MyTopBar_rightButtonTextSize2, 10);
mRightButtonTextBackGround2 = typedArray.getDrawable(R.styleable.MyTopBar_rightButtonTextBackGround2);
//取完不要忘记recycle,防止下次调用失败
typedArray.recycle(); /*
2.组合控件
*/
mTitleTextView = new TextView(context);
mLeftButton = new Button(context);
mRightButton = new Button(context);
mRightButton2 = new Button(context); //为元素添加设置属性,来自XML的值会自动在这里进行设置
mTitleTextView.setText(mTitle);
mTitleTextView.setTextColor(mTitleColor);
mTitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP,mTitleSize); mLeftButton.setText(mLeftButtonText);
mLeftButton.setTextSize(TypedValue.COMPLEX_UNIT_SP,mLeftButtonTextSize);
mLeftButton.setTextColor(mLeftButtonTextColor);
mLeftButton.setBackground(mLeftButtonTextBackGround);
mLeftButton.setId(R.id.topBar_left_button); mRightButton.setText(mRightButtonText);
mRightButton.setTextColor(mRightButtonTextColor);
mRightButton.setTextSize(TypedValue.COMPLEX_UNIT_SP,mRightButtonTextSize);
mRightButton.setBackground(mRightButtonTextBackGround);
mRightButton.setId(R.id.topBar_right_button);//这个id需要在res文件中添加ids.xml文件 mRightButton2.setText(mRightButtonText2);
mRightButton2.setTextColor(mRightButtonTextColor2);
mRightButton2.setTextSize(TypedValue.COMPLEX_UNIT_SP,mRightButtonTextSize2);
mRightButton2.setBackground(mRightButtonTextBackGround2);
//为组件设置布局
mLeftParams = new LayoutParams(
200,
ViewGroup.LayoutParams.WRAP_CONTENT);
mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);//居于父布局左侧
addView(mLeftButton,mLeftParams);//添加到ViewGroup mRightParams = new LayoutParams(
200,
ViewGroup.LayoutParams.MATCH_PARENT);
mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);//居于父布局右侧
addView(mRightButton,mRightParams); mRightParams2 = new LayoutParams(
//px = dp*(dpi/160)这里是像素
80,
80);
mRightParams2.addRule(RelativeLayout.LEFT_OF,R.id.topBar_right_button);//居于最右侧按键左侧
mRightParams2.addRule(RelativeLayout.CENTER_VERTICAL,TRUE);
addView(mRightButton2,mRightParams2); mTitleParams = new LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
mTitleParams.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE);
mTitleParams.addRule(RelativeLayout.RIGHT_OF,R.id.topBar_left_button);//居于最左侧按键右侧
addView(mTitleTextView,mTitleParams); //定义事件监听
mLeftButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.leftButtonClick();
}
}); mRightButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.RightButtonClick();
}
}); mRightButton2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.RightButtonClick2();
}
});
} /*
3.定义接口,留给调用者实现
*/
public interface topBarClickListener {
//左按键
void leftButtonClick();
//右按键
void RightButtonClick();
//右按键2
void RightButtonClick2();
} // 暴露一个方法给调用者来注册接口回调
// 通过接口来获得回调者对接口方法的实现
public void setOnTopBarClickListener(topBarClickListener mListener) {
this.mListener = mListener;
}
}

3.可见性设置

   /*
4.高度自定义
*/
public void setButtonVisible(int id, boolean flag) {
if (flag) {
if (id == 0) {
mLeftButton.setVisibility(View.VISIBLE);
} else if (id == 1) {
mRightButton.setVisibility(View.VISIBLE);
} else {
mRightButton2.setVisibility(View.VISIBLE);
}
} else {
if (id == 0) {
mLeftButton.setVisibility(View.GONE);
} else if (id == 1) {
mRightButton.setVisibility(View.GONE);
} else {
mRightButton2.setVisibility(View.GONE);
}
}
}

自定义View/ViewGroup的步骤和实现的更多相关文章

  1. 【Android - 自定义View】之自定义View浅析

    1.概述 Android自定义View / ViewGroup的步骤大致如下: 1) 自定义属性: 2) 选择和设置构造方法: 3) 重写onMeasure()方法: 4) 重写onDraw()方法: ...

  2. 自定义View完全解析

    自定义View主要包括以下3种方式: 一.组合控件,利用已有控件的组合,来满足自己的需求. 例子:顶部导航栏 二.继承已有View,比如继承TextView.ImageView等,根据需要重写相应的方 ...

  3. 自定义View分类与流程

    自定义View分类与流程(进阶篇)## 转载出处: http://www.gcssloop.com/customview/CustomViewProcess/ 自定义View绘制流程函数调用链(简化版 ...

  4. Android 自定义view(二) —— attr 使用

    前言: attr 在前一篇文章<Android 自定义view -- attr理解>已经简单的进行了介绍和创建,那么这篇文章就来一步步说说attr的简单使用吧 自定义view简单实现步骤 ...

  5. Android查缺补漏(View篇)--自定义View利器Canvas和Paint详解

    上篇文章介绍了自定义View的创建流程,从宏观上给出了一个自定义View的创建步骤,本篇是上一篇文章的延续,介绍了自定义View中两个必不可少的工具Canvas和Paint,从细节上更进一步的讲解自定 ...

  6. 自定义View的实现流程

    1.继承View组件,比如,LabelView继承了View   2.重写两个构造方法,比如,对于自定义View LabelView   LabelView(Context context),如果该自 ...

  7. [原] Android 自定义View步骤

    例子如下:Android 自定义View 密码框 例子 1 良好的自定义View 易用,标准,开放. 一个设计良好的自定义view和其他设计良好的类很像.封装了某个具有易用性接口的功能组合,这些功能能 ...

  8. 自定义View系列教程07--详解ViewGroup分发Touch事件

    深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Andr ...

  9. 自定义的ViewGroup中添加自定义View 造成的无法显示问题(个人)

    首先说一下我在网上找了很久没有找到说明方法所以我就自己试着写了一下 1.我自定义了一个继承了RelativeLayout的ViewGroup java代码如下: /** * 简单自定义三头像 * @a ...

随机推荐

  1. MySQL 返回指定长度的字符串

    今天在做 iblog 项目时,有一个需求是,从 MySQL 返回某个字段的值要时要指定长度,上网搜到的方法是使用 MySQL 的字符串处理函数,如 left(str, length),right(st ...

  2. js中的load先执行还是Jquery的ready先执行问题

    onload需要页面上所有的资源都加载上之后执行,而ready则是DOM文档树已经解析完成时,说ready比onload快最显著的是比如一个页面上有一个很大的图片,加载要好久,onload只有在图片加 ...

  3. 超链接显示网站 A,访问后进入网站 B

    #前端黑魔法# 出一个思考题:如何用最少的字符实现下图效果.即超链接显示网站 A,访问后进入网站 B. 当然这个是上古时代的黑魔法了,稍懂前端的都知道原理.所以这里只问最短的实现~ 一个简单的演示:( ...

  4. centos6.2安装内核

    http://vault.centos.org/6.2/updates/Source/SPackages/ yum install rpm-build redhat-rpm-config unifde ...

  5. 调试工具DEBUG的使用(8086)

    有关CPU和存储单元的概念在前一节我们已经了解,那么如何观察实际机器内部的情况呢?能不能看到具体的寄存器.标志.存储单元的内容呢?可不可以修改和控制它们呢? DEBUG这个有力工具,就可以深入到机器内 ...

  6. python脚本执行报错:SyntaxError: Non-ASCII character '\xe6' in file ip.py on line 4...

    报错信息 [root@chenbj ~]# python ip.py 192.168.1.1 File "ip.py", line 4 SyntaxError: Non-ASCII ...

  7. React后台管理系统-登录页面

    登录页面 <div className="col-md-4 col-md-offset-4">                <div className=&qu ...

  8. Mybatis自查询递归查找子

    先看一下数据库 主键id,名称product_code,父parent,和kind 设计菜单类 setter,getter Dao public interface ProductMapper { L ...

  9. sql注入问题 java中将MySQL的数据库验证秘密加上 ' or '1'= '1 就可以出现万能密码

    password的字符串中,加上 ' or '1'= '1 就可以制作出万能密码. 原因如下: 原代码中密码是123456 执行数据库查询语句 实际上执行的SQL语句是: select * from ...

  10. Android驱动开发读书笔记六

    第六章 Linux 驱动的工作和访问方式是 Linux 的亮点之一,Linux 系统将每一个驱动都映射成一个文件.这些文件称为设备文件或驱动文件,都保存在/dev目录中,由于大多数Linux驱动都有与 ...