Android自定义带标题边框的Layout
今天工作中又碰到个小问题,项目需要用到像Java Swing的JPanel一样带标题边框的布局,Android里没有类似控件,想到这个也不难,自己画了一个,是继承LinearLayout的一个自定义布局,当然,可以根据需要继承其他布局,基本都是一样的过程。
当然这个自定义布局有点瑕疵,就是标题占用了布局的一部分高度,子控件需要调整在布局中的垂直位置来避免和标题边框靠得过紧。
------------------本博客如未明正声明转载,皆为原创,转载请注明出处!------------------
下面贴代码:
/**
* 一个像java swing的JPanel控件一样可以带标题边框的布局,可以指定标题位置、颜色、字体大小。
* 另外还可以控制边框大小和边框的颜色。但是,子控件指定垂直布局适应的时候,子控件看起来并不在布局中间,
* 因为标题高度占用了布局的一部分垂直空间,使用时子控件需要指定Margin Top,否则可能和标题重叠。
*
* This is a layout with title border, you can set a title just like Java-Swing JPanel.
* and you can control the position, the color and the size of the title. In addition,
* the border's color and size are always controlled.
*
* !FIXME: The title has its own height, so when the children's gravity set as {@link Gravity#CENTER}
* or {@link Gravity#CENTER_VERTICAL} do not work well.
*
* @date 2013/09/24
* @author Wison
*/
public class TitleBorderLayout extends LinearLayout { /** 默认情况下标题在总长度的1/10处显示 */
private static float DEFAULT_TITLE_POSITION_SCALE = 0.1f;
public static int DEFAULT_BORDER_SIZE = 1;
public static int DEFAULT_BORDER_COLOR = Color.GRAY;
public static int DEAFULT_TITLE_COLOR = Color.BLACK; /** 边框面板的高度 */
private int mBorderPaneHeight ; private Paint mBorderPaint;
private float mBorderSize; private TextPaint mTextPaint;
private CharSequence mTitle;
private int mTitlePosition; public TitleBorderLayout(Context context) {
this(context, null);
} /**
* Construct a new TitleBorderLayout with default style, overriding specific style
* attributes as requested.
* @param context
* @param attrs
*/
public TitleBorderLayout(Context context, AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(false); mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
Resources res = getResources();
mTextPaint.density = res.getDisplayMetrics().density; TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TitleBorderLayout); mTitle = a.getText(R.styleable.TitleBorderLayout_title);
int titleColor = a.getColor(R.styleable.TitleBorderLayout_titleTextColor, DEAFULT_TITLE_COLOR);
mTextPaint.setColor(titleColor); float titleTextSize = a.getDimension(R.styleable.TitleBorderLayout_titleTextSize, 0);
if (titleTextSize > 0) {
mTextPaint.setTextSize(titleTextSize);
} mTitlePosition = a.getDimensionPixelSize(R.styleable.TitleBorderLayout_titlePosition, -1); mBorderSize = a.getDimensionPixelSize(R.styleable.TitleBorderLayout_borderSize, DEFAULT_BORDER_SIZE); int borderColor = a.getColor(R.styleable.TitleBorderLayout_borderColor, DEFAULT_BORDER_COLOR);
mBorderPaint.setColor(borderColor); a.recycle();
} /**
* Get the color of border.
* @return
*/
public int getBorderColor() {
return mBorderPaint.getColor();
} /**
* Set the color of border.
* @param borderColor
*/
public void setBorderColor(int borderColor) {
mBorderPaint.setColor(borderColor);
requestLayout();
} /**
* Get the size of border.
* @return
*/
public float getBorderSize() {
return mBorderSize;
} /**
* Set the size of border.
* @param borderSize
*/
public void setBorderSize(float borderSize) {
mBorderSize = borderSize;
requestLayout();
} /**
* Get the color of title.
* @return
*/
public int getTitleColor() {
return mTextPaint.getColor();
} /**
* Set the color of title.
* @param titleColor
*/
public void setTitleColor(int titleColor) {
mTextPaint.setColor(titleColor);
requestLayout();
} /**
* Get the size of title.
* @return
*/
public float getTitleTextSize() {
return mTextPaint.getTextSize();
} /**
* Set the size of title.
* @param titleTextSize
*/
public void setTitleTextSize(float titleTextSize) {
mTextPaint.setTextSize(titleTextSize);
requestLayout();
} /**
* Get the title.
* @return
*/
public CharSequence getTitle() {
return mTitle;
} /**
* Set the title which will be shown on the top of border pane.
* @param title
*/
public void setTitle(CharSequence title) {
mTitle = title;
requestLayout();
} /**
* Get the position of title.
* @return
*/
public int getTitlePosition() {
return mTitlePosition;
} /**
* Set the position of title where the paint will start to draw.
* @param titlePosition
*/
public void setTitlePosition(int titlePosition) {
mTitlePosition = titlePosition;
requestLayout();
} /**
* Get the height of border pane, it's different from the layout height!
* @return
*/
public int getBorderPaneHeight() {
return mBorderPaneHeight;
} /**
* Draw the title border
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); FontMetrics fm = mTextPaint.getFontMetrics();
final float titleHeight = fm.descent - fm.ascent; final CharSequence titleText = (mTitle == null) ? "" : mTitle;
final float titleWidth = Layout.getDesiredWidth(titleText, mTextPaint); final int width = getWidth();
final int height = getHeight(); if (mTitlePosition <= 0 || mTitlePosition + titleWidth > width) {
mTitlePosition = (int) (DEFAULT_TITLE_POSITION_SCALE * width);
} final float topBorderStartY = titleHeight / 3f - mBorderSize / 2; mBorderPaneHeight = (int) Math.ceil(height - topBorderStartY);
/* 画标题边框 */
// 上
canvas.drawRect(0, topBorderStartY, mTitlePosition, topBorderStartY + mBorderSize, mBorderPaint);
canvas.drawText(titleText.toString(), mTitlePosition, titleHeight / 3 * 2f, mTextPaint); // 标题
canvas.drawRect(mTitlePosition + titleWidth, topBorderStartY, width, topBorderStartY + mBorderSize, mBorderPaint);
// 左
canvas.drawRect(0, topBorderStartY, mBorderSize, height, mBorderPaint);
// 右
canvas.drawRect(width - mBorderSize, topBorderStartY, width, height, mBorderPaint);
// 下
canvas.drawRect(0, height - mBorderSize, width, height, mBorderPaint);
} }
以下为属性声明:
<declare-styleable name="TitleBorderLayout">
<!-- The title of BorderTitleLayout. -->
<attr name="title" format="string" />
<!-- The size of title. -->
<attr name="titleTextSize" format="dimension" />
<!-- The title start postion. -->
<attr name="titlePosition" format="dimension" />
<!-- The color of title. -->
<attr name="titleTextColor" format="reference|color" />
<!-- The size of border. -->
<attr name="borderSize" format="dimension" />
<!-- The color of border. -->
<attr name="borderColor" format="reference|color" />
</declare-styleable>
下面是效果图:
Android自定义带标题边框的Layout的更多相关文章
- Android 自定义带刻度的seekbar
自定义带刻度的seekbar 1.布局 <span style="font-family:SimHei;font-size:18px;"><com.imibaby ...
- Android -- 自定义带进度条的按钮
1. 实现了一个带进度条的按钮,完成后显示提示信息,并设置按钮为不可再次被点击
- Android自定义EditText去除边框并添加下划线
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- Android 自定义带回调的Dialog 及EditText相关
import android.app.Activity; import android.content.Context; import android.text.Editable; import ...
- android自定义圆角实线边框,圆角虚线边框,直实线,虚实线,半圆角边框
先上图 在现实项目开发中,单纯的Button,EditText等控件远远不能满足我们项目的UI设计需求,这时候,我们就需要自己动手丰衣足食啦.接下来先给大家介绍一些属性,备注写的都非常清楚啦,我就不啰 ...
- Android实现自定义带文字和图片的Button
Android实现自定义带文字和图片的Button 在Android开发中经常会需要用到带文字和图片的button,下面来讲解一下常用的实现办法. 一.用系统自带的Button实现 最简单的一种办法就 ...
- [转]Android UI:看看Google官方自定义带旋转动画的ImageView-----RotateImageView怎么写(附 图片淡入淡出效果)
http://blog.csdn.net/yanzi1225627/article/details/22439119 众所周知,想要让ImageView旋转的话,可以用setRotation()让其围 ...
- 我的Android进阶之旅------>Android自定义View实现带数字的进度条(NumberProgressBar)
今天在Github上面看到一个来自于 daimajia所写的关于Android自定义View实现带数字的进度条(NumberProgressBar)的精彩案例,在这里分享给大家一起来学习学习!同时感谢 ...
- Android自定义控件 -- 带边框的TextView
使用xml实现边框 原来使用带边框的TextView时一般都是用XML定义来完成,在drawable目录中定义如下所示的xml文件: <?xml version="1.0" ...
随机推荐
- New Year Table(几何)
New Year Table Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Sub ...
- 通过winForm控制webForm的上传控件file的值
文件上传是日常开发中经常遇到的,文件上传用的最多的当然是上传控件file了,一个form表单,其中有一点就是form表单的enctype属性设置为multipart/form-data,呵呵,这个在所 ...
- 初识_IOS-简易计算器-问题总结
作为一个新手,只好拿所有开发者都写的不想写又没有太大难度的计算器来下手咯.比较细一点,耐心哟. 我们都知道,计算器首要任务就是计算,那我们就直接看成A+B=C,来进行分析了.对A,B,C三个对象进行分 ...
- iOS面试题集
现在寒假时间在家里面无法敲代码了,但是自己总要找些事情来做,回头想想马上就要开始就业了,所以不免要参加面试,于是便开始了面试题集的浏览和探索,今天下午我看了一部分的面试题感觉还是挺实用的,所以以后还是 ...
- [HeadFirst-HTMLCSS学习笔记][第八章扩大你的词汇量]
字体 font-family,可指定多个候选 body{ font-family:Verdana,Geneva,Arial,sans-serif; } font-size 字体大小 body{ fon ...
- Oracle/Mysql/SqlServer函数区别
mysql日期和时间格式转换 Linux scp 使用详解 Oracle/Mysql/SqlServer函数区别 2011-07-01 12:34:36| 分类: Mysql技术 | 标签:mys ...
- UIImageView 一些属性设置
1.contentMode属性 这个属性是用来设置图片的显示方式,如居中.居右,是否缩放等,有以下几个常量可供设定: UIViewContentModeScaleToFill UIViewConten ...
- C#参数传递、引用类型、值类型等的理解
本博客不属于技术贴,主要是记录一些自己对不懂得地方的理解和学习的记录,请带着批判的眼光阅读~ 值类型存储在栈上,引用类型存储在堆上.栈是由高到低存储的,遵循先进后出的原则,是内存提前分配好的区域,内存 ...
- 网络编程之TCP
知识补充:源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字.其用于标识客户端请求的服务器和服务. TCP编程的实现步骤:服务器端:1.通过ServletSocket创建绑定到指定客户端 ...
- Android 6.0 闪光灯的使用
Android6.0 已经抛弃了Camer 相关的API,改用新的API接口CamerManager,下面给出使用的简单实例 package com.inper.duqiang.slashlight; ...