今天工作中又碰到个小问题,项目需要用到像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>
下面是效果图:
分享到:
相关推荐
自定义带标题边框的Layout,像Java-swing的JPanel效果,本例继承LinearLayout,继承其他Layout是一样的过程。
为GridView添加边框效果,供大家参考,具体内容如下 1.自定义GridView的item样式: grid_item.xml文件 <?xml version=1.0 encoding=utf-8?> <LinearLayout xmlns:android=...
com .bytoaster.widget.LetterCircleView android : layout_width = " 50dp " android : layout_height = " 50dp " android : text = " M " android : textColor = " @color/white " android : textSize = " 25...
适用于Android的圆形,可自定义的UI元素。 您可以将圆角大小,边框大小,边框颜色设置为任何weidget。 用法 在xml中简单使用 < com .linfaxin.roundedui.RoundedFrameLayout android : layout_marginTop = " ...
可自定义样式、功能全面的分段控件。项目地址:https://github.com/klongmitre/android-segmented-control-view效果图:如何使用xml中直接创建 android:id="@ id/androidSegmentedControlView" android:layout...
可自定义控件的颜色、边框长度、动画时间。项目地址:https://github.com/dodocat/CircularProgress 效果图:如何使用 android:layout_width="100dp" android:layout_height="100dp" android:layout_margin...
应用启动页自定义跳转计时器View Demo: CircleTextProgressbar.java: package com.demo.startpageskiptimerdemo.widget; import android.content.Context; import android.content.res.ColorStateList; import ...
外层一个LinearLayout,里面一个自定义的控件DragScaleView,为了能够更清楚的看到控件的变化过程,就给控件加了一个灰色带虚线的边框bg_dashgap。 layout文件 <?xml version=1.0 encoding=utf-8?> <...
如“材质图标”和Google应用中所述,获取2dp星形边框背景。 跨平台正确自定义着色。 当layout_width设置为match_parent ,能够正确呈现,如在Google Play商店中一样。 当layout_height设置为16dp,36dp和48dp...
这个自定义ImageView控件实现了图片的圆角、圆形、边框等功能,同时具有按下改变颜色的效果,通过属性设置可以自定义按下的颜色, 以及颜色的透明度;还克定义边框的颜色##Demo截图: ##使用方法使用方法很简单,...
View的布局显示方式有下面几种:线性布局(Linear Layout)、相对布局(Relative Layout)、表格布局(Table Layout)、网格视图(Grid View)、标签布局(Tab Layout)、列表视图(List View)、绝对布局...
android:layout_gravity="bottom|center_horizontal" android:layout_marginBottom="10dp" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="20dp" android:...
可以支持各个方向设置渐变色可以支持设置带边框的按钮,可以设置边框的颜色和宽度可以支持设置按钮是否可以点击可以设置带图标的按钮,支持自定义按钮大小,和自动缩放,图标支持设置在文字上下左右四个方向,支持...
但是Google提供的布局属性有限,某些功能的实现我们必须使用代码,或者自定义控件的方式例如我们经常使用背景来表示和设置背景,那是不是可以使用layout_radius来表示和设置圆角呢? 使用示例需要在项目build.gradle...
每个对话框类型也支持自定义边框圆角、背景透明度、字体大小与色值初衷是掌握知识点,此库不一定适合你的产品整体风格,当然能够适合你的项目最好不过,有建议和不足之处欢迎骚扰知识点全代码创建shape、selector、...