今天工作中又碰到个小问题,项目需要用到像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的更多相关文章

  1. Android 自定义带刻度的seekbar

    自定义带刻度的seekbar 1.布局 <span style="font-family:SimHei;font-size:18px;"><com.imibaby ...

  2. Android -- 自定义带进度条的按钮

    1. 实现了一个带进度条的按钮,完成后显示提示信息,并设置按钮为不可再次被点击

  3. Android自定义EditText去除边框并添加下划线

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  4. Android 自定义带回调的Dialog 及EditText相关

      import android.app.Activity; import android.content.Context; import android.text.Editable; import ...

  5. android自定义圆角实线边框,圆角虚线边框,直实线,虚实线,半圆角边框

    先上图 在现实项目开发中,单纯的Button,EditText等控件远远不能满足我们项目的UI设计需求,这时候,我们就需要自己动手丰衣足食啦.接下来先给大家介绍一些属性,备注写的都非常清楚啦,我就不啰 ...

  6. Android实现自定义带文字和图片的Button

    Android实现自定义带文字和图片的Button 在Android开发中经常会需要用到带文字和图片的button,下面来讲解一下常用的实现办法. 一.用系统自带的Button实现 最简单的一种办法就 ...

  7. [转]Android UI:看看Google官方自定义带旋转动画的ImageView-----RotateImageView怎么写(附 图片淡入淡出效果)

    http://blog.csdn.net/yanzi1225627/article/details/22439119 众所周知,想要让ImageView旋转的话,可以用setRotation()让其围 ...

  8. 我的Android进阶之旅------>Android自定义View实现带数字的进度条(NumberProgressBar)

    今天在Github上面看到一个来自于 daimajia所写的关于Android自定义View实现带数字的进度条(NumberProgressBar)的精彩案例,在这里分享给大家一起来学习学习!同时感谢 ...

  9. Android自定义控件 -- 带边框的TextView

    使用xml实现边框 原来使用带边框的TextView时一般都是用XML定义来完成,在drawable目录中定义如下所示的xml文件: <?xml version="1.0" ...

随机推荐

  1. PHP连接sql server 2005环境配置

    一.Windows下PHP连接SQLServer 2005 设定:安装的Windows操作系统(Win7 或XP均可.其它系统暂未測试),在C盘下:PHP的相关文件位于c:/PHP以下,其配置文件ph ...

  2. 批量设置AssetBundleName

    using UnityEngine; using System.Collections; using UnityEditor; using System.IO; public class Change ...

  3. Why Hadoop2

    自从Hadoop2出现之后,其迅速代替了Hadoop1的地位,并丰富了Hadoop的应用场景.假设如今有公司使用Hadoop的话,往往直接採用Hadoop2了. Hadoop2能被如此广泛的使用,肯定 ...

  4. linux 常用 命令 笔记二

    wget 下载,得到网络上的内容 grep 文件搜索工具 EveryThing is a file in the linux system 安装 cowsay sudo apt-get install ...

  5. 如何安装,卸载eclipse中的ADT,或者更新ADT

    昨天手贱把Android的SDK升级了,然后搞到ADT的版本不对应,然后从网上搜了一些办法~效果还可以,重新安装了一次ADT. 卸载ADT的方法,方法如下(我的Eclipse版本为3.5): 1.选择 ...

  6. Code Complete阅读笔记(二)

    2015-03-06   328   Unusual Data Types    ——You can carry this technique to extremes,putting all the ...

  7. eclipse中多个工程编译到同一个目录下

    1.点击link source  2.选择Java(ps:Java文件目录)或者resource(ps:配置文件目录)  3.最后结果,然后使用project中的clean进行编译,就可以把两个工程编 ...

  8. Mapper映射语句高阶应用——ResultMap

    resultMap 元素是MyBatis 中最重要最强大的元素.它就是让你远离 90%的需要从结果 集中取出数据的 JDBC代码的那个东西, 而且在一些情形下允许你做一些 JDBC 不支持的事 情. ...

  9. Centos安装php提示virtual memory exhausted: Cannot allocate memory

    由于内存不够,需要在php配置的时候./configure最后添加上 --disable-fileinfo >>./configure --prefix= ...........   -- ...

  10. js倒计时 重发 效果

    <script type="text/javascript"> window.onload = function() { var wait = 60; function ...