今天工作中又碰到个小问题,项目需要用到像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. JS 数组扩展函数--求起始项到终止项和

    Array.prototype.sum= function(l,r){ l=l==undefined ? 0 : l; r=r==undefined ? this.length - 1 : r; va ...

  2. java实现点名,并记录被点次数

    java实现点名,并记录被点次数 import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStrea ...

  3. ACdream 1083 有向无环图dp

    题目链接:点击打开链接 人民城管爱人民 Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 128000/64000 KB (Java/Othe ...

  4. 机器学习实战笔记5(logistic回归)

    1:简单概念描写叙述 如果如今有一些数据点,我们用一条直线对这些点进行拟合(改线称为最佳拟合直线),这个拟合过程就称为回归.训练分类器就是为了寻找最佳拟合參数,使用的是最优化算法. 基于sigmoid ...

  5. java编程中的Java.Lang.Math类

    1. Math.PI  :表示的是圆周率常量: 2.Math.E    :表示的是普通常量(e): 3.abs()方法: 表示取绝对值 eg1: int x = Math.abs(50L);     ...

  6. IoC容器Autofac之实例引入(一)

    先不必尝试理解IOC,先来看段代码. 一.一个没有使用IoC的例子 public class MPGMovieLister { public Movie[] GetMPG() { var finder ...

  7. javascript运动功能-分享到

    <script> //窗体载入,为div控件绑定事件 window.onload = function () { var div1 = document.getElementById('d ...

  8. nginx搭建flv、mp4流媒体服务

    1.安装pcre-8.33.tar.bz2 #tar -xvf 1.pcre-8.33.tar.bz2 #cd pcre-8.33/ #./configure #make && mak ...

  9. 第一章 Qt入门

    1.1Qt 窗口部件 widget,用户界面的一个可视化元素,任意窗口部件都可以作为窗口.可以通过简单的HTML修改丰富样式 1.2建立连接 Qt的窗口部件通过发射信号(signal)来表明一个用户动 ...

  10. jquery之stop()的用法

    // 为了看效果,随意写的动画 $('#animater').animate({ 'right':-800 }, 3000).animate({'font-size':'16px'},'normal' ...