自定义View/ViewGroup的步骤和实现
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的步骤和实现的更多相关文章
- 【Android - 自定义View】之自定义View浅析
1.概述 Android自定义View / ViewGroup的步骤大致如下: 1) 自定义属性: 2) 选择和设置构造方法: 3) 重写onMeasure()方法: 4) 重写onDraw()方法: ...
- 自定义View完全解析
自定义View主要包括以下3种方式: 一.组合控件,利用已有控件的组合,来满足自己的需求. 例子:顶部导航栏 二.继承已有View,比如继承TextView.ImageView等,根据需要重写相应的方 ...
- 自定义View分类与流程
自定义View分类与流程(进阶篇)## 转载出处: http://www.gcssloop.com/customview/CustomViewProcess/ 自定义View绘制流程函数调用链(简化版 ...
- Android 自定义view(二) —— attr 使用
前言: attr 在前一篇文章<Android 自定义view -- attr理解>已经简单的进行了介绍和创建,那么这篇文章就来一步步说说attr的简单使用吧 自定义view简单实现步骤 ...
- Android查缺补漏(View篇)--自定义View利器Canvas和Paint详解
上篇文章介绍了自定义View的创建流程,从宏观上给出了一个自定义View的创建步骤,本篇是上一篇文章的延续,介绍了自定义View中两个必不可少的工具Canvas和Paint,从细节上更进一步的讲解自定 ...
- 自定义View的实现流程
1.继承View组件,比如,LabelView继承了View 2.重写两个构造方法,比如,对于自定义View LabelView LabelView(Context context),如果该自 ...
- [原] Android 自定义View步骤
例子如下:Android 自定义View 密码框 例子 1 良好的自定义View 易用,标准,开放. 一个设计良好的自定义view和其他设计良好的类很像.封装了某个具有易用性接口的功能组合,这些功能能 ...
- 自定义View系列教程07--详解ViewGroup分发Touch事件
深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Andr ...
- 自定义的ViewGroup中添加自定义View 造成的无法显示问题(个人)
首先说一下我在网上找了很久没有找到说明方法所以我就自己试着写了一下 1.我自定义了一个继承了RelativeLayout的ViewGroup java代码如下: /** * 简单自定义三头像 * @a ...
随机推荐
- P1736 创意吃鱼法80
题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...
- IDEA集成tomcat启动时控制台打印中文乱码
转载:https://blog.csdn.net/nan_cheung/article/details/79337273 idea启动tomcat控制台出现乱码,每个人可能引发该问题的原因不同,可以就 ...
- css盒子模型 css3盒子相关样式
1.内边距(内边距在content外,边框内) 内边距属性: padding 设置所有边距 padding-bottom 底边距 padding-left ...
- JDBC连接数据库(Servlet+JSP)
JDBC(Java Database connectivity),是连接数据库的一种方式.后面的框架Mybatis和Hibernate等都封装的是JDBC.在JDBC中常用的API有4个:Driver ...
- intellij idea中设置SVN插件教程
1.选择VCS→Browser VCS Repository→Browse Subversion Repository 2.在弹出的SVN Repository菜单中,选择左上角的绿色“+”号,填写S ...
- mybatis-动态sql1
在多条件查询的情况下必须用到动态sql 沿用之前的项目 1.在dao中添加多添件查询方法 package com.java1234.mappers; import java.util.List;imp ...
- 【BZOJ1433】[ZJOI2009] 假期的宿舍(二分图匹配入门)
点此看题面 大致题意:有\(n\)个学生,其中一部分是在校学生,一部分不是,而在校学生中一部分回家,一部分不回家,并且我们用一个01矩阵表示学生之间相互认识关系.已知每个学生只能睡自己认识的人的床(当 ...
- Java8函数之旅 (三) --几道关于流的练习题
为什么要有练习题? 所谓学而不思则罔,思而不学则殆,在系列第一篇就表明我认为写博客,既是分享,也是自己的巩固,我深信"纸上得来终觉浅,绝知此事要躬行"的道理,因此之后的几篇博 ...
- Drupal相关网站推荐
http://nodeone.se/ drupal7安装过程中,如果选择简体中文,到导入翻译时出现错误,原因是执行超时了. 方法一: 修改php.ini文件:memory_limit = 256M ( ...
- IPython安装过程 @win7 64bit
http://www.360doc.com/content/14/0902/11/16740871_406476389.shtml 为了测验测验一下IPython的应用,今天折腾了好久的从安装包msi ...