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. js和JQuery中offset等属性对比

    HTML: 内容在滚动条下面 <div id="outerDiv"> <div id="myDiv" class="myDiv&qu ...

  2. 执行命令npm install XXX后仍然提示 Cannot find Module XXX

    最近遇到一个问题,在服务器上配置完node环境后 执行npm start 命令后提示 Cannot find Module "Jquery" 然后就知道可能没有安装jquery 就 ...

  3. 如何在Ubuntu server中修改IP

    详细请移步至博客https://blog.csdn.net/shenzhen_zsw/article/details/74025066 方法一. sudo  ifconfig eth0 100.100 ...

  4. linux 命令——5 rm(转)

    昨天学习了创建文件和目录的命令mkdir ,今天学习一下linux中删除文件和目录的命令: rm命令.rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所 ...

  5. co-dialog弹出框组件-版本v2.0.0

    co-dialog theme 访问git:co-dialog 版本v2.0.0 主题2 coog.app('.theme2').use({ title: 'JUST CHECKING.', mess ...

  6. UVA 10375 Choose and divide(大数的表示)

    紫上给得比较奇怪,其实没有必要用唯一分解定理.我觉得这道题用唯一分解只是为了表示大数. 但是分解得到的幂,累乘的时候如果顺序很奇怪也可能溢出.其实直接边乘边除就好了.因为答案保证不会溢出, 设定一个精 ...

  7. Aizu 2300 Calender Colors(暴力)

    状压以后,直接暴力枚举,2^20约等于1e6,而且满足bitcount = m的状态很少. #include<bits/stdc++.h> using namespace std; +; ...

  8. 【BZOJ1925】 [SDOI2010] 地精部落(带有一堆性质的动态规划)

    点此看题面 大致题意: 问你有多少长度为\(n\)的数列,它当中每个数字要么比旁边两个数字都小,要么比旁边两个数字都大. 性质 这题应该比较显然是一道动态规划题,但刚看到这题时我却无从下手. 其实,了 ...

  9. 《剑指offer》【调整数组顺序使奇数位于偶数前面】(python版)

    题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分 思路: 我认真看了一下,题目应该是要求在原地调整,所以这里不能再 ...

  10. javascript同步和异步的区别与实现方式

    javascript语言是单线程机制.所谓单线程就是按次序执行,执行完一个任务再执行下一个. 对于浏览器来说,也就是无法在渲染页面的同时执行代码. 单线程机制的优点在于实现起来较为简单,运行环境相对简 ...