Android UI设计系列之自定义TextView属性实现带下划线的文本框(4)

作者:llew2011 时间:2022-08-11 11:03:29 

在Android开发过程中,如果Android系统自带的属性不能满足我们日常开发的需求,那么就需要我们给系统控件添加额外的属性了。假如有个需求是实现带下划线的文本显示(下划线),如果不使用自定义属性的话实现起来也不太难(起码我认为的实现方式是有许多种的),今天就讲解一下如何使用自定义属性来实现上述带下划线的文本框吧。还好Android中自定义属性不是很复杂,也可以归纳为三步走吧。

老规矩,还是先贴出工程目录吧:

Android UI设计系列之自定义TextView属性实现带下划线的文本框(4)

一、添加属性文件

在values文件夹中新建attrs.xml文件,在文件中新建属性文件,代码如下:


<?xml version="1.0" encoding="utf-8"?>
<resources>

<!-- 自定义属性开始 -->
<declare-styleable name="BorderTextView">
<attr name="layout_borders" format="boolean"></attr>
<attr name="layout_borderLeft" format="boolean"></attr>
<attr name="layout_borderTop" format="boolean"></attr>
<attr name="layout_borderRight" format="boolean"></attr>
<attr name="layout_borderBottom" format="boolean"></attr>
</declare-styleable>
<!-- 自定义属性结束 -->

</resources>

其中需要说明的是,自定义属性文件的根节点页是<resources>,在根节点内创建你所需要的属性值,自定义属性的节点是以<declare-styleable>开始的,它表示的是个属性集可以包含众多属性,其中name="BorderTextView"是属性集名。接着在<declare-styleable>中定义我们需要的以<attr>为节点的属性,attr表示属性的意思name表示当前属性的名称,format表示的是属性值的类型,例如我们当前定义的属性类型为boolean类型,也就是说当前定义的属性取值只能为boolean类型的,format可以表示的的类型有好多种,最常见的如:string,boolean,integer,dimension,reference等这,里就不再详细讲解了,如果谁有疑问,可以自己动手问问度娘,她知道的比我多,呵呵

二、使用自定义属性

在attrs.xml文件中定义好了属性,就可以在布局文件中使用了,接下来看看在布局文件中如何使用自定义属 * ,代码如下:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:greendroid="http://schemas.android.com/apk/res/com.llew.e"
android:orientation="vertical"
android:layout_width="fill_parent"
android:background="#ffffff"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dip"
android:text="@string/hello"
android:textColor="#000000" />

<com.llew.e.view.wedgit.BorderTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="左侧带有边框"
android:layout_margin="10dip"
greendroid:layout_borderLeft="true"
android:textSize="20sp"
android:textColor="#aabbcc">
</com.llew.e.view.wedgit.BorderTextView>

<com.llew.e.view.wedgit.BorderTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="顶部带有边框"
android:layout_margin="10dip"
greendroid:layout_borderTop="true"
android:textSize="20sp"
android:textColor="#bbccaa">
</com.llew.e.view.wedgit.BorderTextView>

<com.llew.e.view.wedgit.BorderTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="右侧带有边框"
android:layout_margin="10dip"
greendroid:layout_borderRight="true"
android:textSize="20sp"
android:textColor="#ccaabb">
</com.llew.e.view.wedgit.BorderTextView>

<com.llew.e.view.wedgit.BorderTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="底部带有边框"
android:layout_margin="10dip"
greendroid:layout_borderBottom="true"
android:textSize="20sp"
android:textColor="#abcabc">
</com.llew.e.view.wedgit.BorderTextView>

<com.llew.e.view.wedgit.BorderTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="四周带有边框"
android:layout_margin="10dip"
greendroid:layout_borders="true"
android:textSize="20sp"
android:textColor="#cbacba">
</com.llew.e.view.wedgit.BorderTextView>
</LinearLayout>

使用自定义控件也很简单就是包名+自定义控件名,为了使用我们自定义的属性,必须在布局文件的根节点中加上xmlns:greendroid="http://schemas.android.com/apk/res/com.llew.e"这句话,其中xmlns:greendroid表示的是命名空间名称,greendroid只是个名字是我们使用自定义属性的前缀,可以随便取值(只要不是android就行了),com.llew.e是在manifest中的package的对应值,使用自定义属性就想代码中的那样:greendroid:layout_borderLeft="true",(*^__^*) 嘻嘻&hellip;&hellip;,是不是可简单?

三、根据自定义属性值做相应操作

完成自定义属性文件之后,我们就来为控件添加自定义的属性了,自定义控件我认为最简单的实现就是使用继承,在继承的基础上进行扩充来实现我们所要的功能,所以为了实现带边框的文本组件,我就直接继承了TextView组件,在它的基础上进行扩充了,代码如下:


public class BorderTextView extends TextView {

/**
* 四周是否带有边框【true:四周带有边框】【false:四周不带边框】
*/
boolean borders = false;
/**
* 左边是否带有边框【true:左侧带有边框】【false:左侧不带边框】
*/
boolean borderLeft = false;
/**
* 顶部是否带有边框【true:顶部带有边框】【false:底部不带边框】
*/
boolean borderTop = false;
/**
* 右侧是否带有边框【true:右侧带有边框】【false:右侧不带边框】
*/
boolean borderRight = false;
/**
* 底部是否带有边框【true:底部带有边框】【false:底部不带边框】
*/
boolean borderBottom = false;
/**
* 边框颜色
*/
String textColor = "#ff000000";

public BorderTextView(Context context) {
this(context, null);
}

public BorderTextView(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.textViewStyle);
}

public BorderTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// 获取自定义属性集
TypedArray typedArray = context.obtainStyledAttributes(attrs,
 R.styleable.BorderTextView);
// 是否设置全部边框,默认为false
borders = typedArray.getBoolean(
 R.styleable.BorderTextView_layout_borders, false);
// 是否设置左侧边框,默认为false
borderLeft = typedArray.getBoolean(
 R.styleable.BorderTextView_layout_borderLeft, false);
// 是否设置顶部边框,默认为false
borderTop = typedArray.getBoolean(
 R.styleable.BorderTextView_layout_borderTop, false);
// 是否设置右侧边框,默认为false
borderRight = typedArray.getBoolean(
 R.styleable.BorderTextView_layout_borderRight, false);
// 是否设置底部边框,默认为false
borderBottom = typedArray.getBoolean(
 R.styleable.BorderTextView_layout_borderBottom, false);
// 获取文本颜色值,用来画边框的,便于和文本颜色匹配
textColor = attrs.getAttributeValue(
 "http://schemas.android.com/apk/res/android", "textColor");
typedArray.recycle();
}

@Override
public void draw(Canvas canvas) {
super.draw(canvas);
// 创建画笔
Paint paint = new Paint();
// 获取该画笔颜色
int color = paint.getColor();
// 设置画笔颜色
paint.setColor(Color.parseColor(textColor));
// 如果borders为true,表示左上右下都有边框
if (borders) {
 canvas.drawLine(0, 0, 0, this.getHeight() - 1, paint);
 canvas.drawLine(0, 0, this.getWidth() - 1, 0, paint);
 canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1,
  this.getHeight() - 1, paint);
 canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1,
  this.getHeight() - 1, paint);
} else {
 if (borderLeft) {
 // 画左边框线
 canvas.drawLine(0, 0, 0, this.getHeight() - 1, paint);
 }
 if (borderTop) {
 // 画顶部边框线
 canvas.drawLine(0, 0, this.getWidth() - 1, 0, paint);
 }
 if (borderRight) {
 // 画右侧边框线
 canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1,
  this.getHeight() - 1, paint);
 }
 if (borderBottom) {
 // 画底部边框线
 canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1,
  this.getHeight() - 1, paint);
 }
}
// 设置画笔颜色归位
paint.setColor(color);
}
}

其实给BorderTextView添加边框也是很简单,原理就是其draw方法中绘画出边框罢,我们都知道每一个View控件在屏幕上显示出来大致可以归纳为三大步骤,首先调用View控件的onMesure方法,其次调用View控件的onLayout方法,再次调用View控件的onDraw方法,所以我们只需要在draw方法中绘制出边框就行了,绘制边框的步骤很简单,代码注释也很详细,就不再详细讲解了

最后运行一下程序来看一下效果图吧,呵呵

Android UI设计系列之自定义TextView属性实现带下划线的文本框(4)

标签:Android,TextView,文本框
0
投稿

猜你喜欢

  • Spring MVC中自定义拦截器的实例讲解

    2023-12-19 05:09:04
  • Android通讯录开发之删除功能的实现方法

    2021-07-06 10:43:53
  • 详解JAVA中的OPTIONAL

    2022-08-22 17:09:04
  • java 线程创建多线程详解

    2021-08-06 22:02:22
  • C#请求http向网页发送接收数据的方法

    2022-05-28 15:39:20
  • window下安装和配置maven环境

    2021-06-13 14:32:16
  • Java编程在ICPC快速IO实现源码

    2021-10-18 01:41:54
  • Java中session存储Users对象实现记住密码

    2021-06-27 10:46:59
  • Java基础之Thymeleaf的简单使用

    2023-08-24 19:00:22
  • 详解Spring依赖注入的三种方式使用及优缺点

    2023-06-09 18:29:00
  • Android 逆向学习详解及实例

    2022-12-26 08:51:50
  • IDEA插件之彩虹括号Rainbow Brackets使用介绍

    2022-03-14 09:09:51
  • Springboot项目快速实现过滤器功能

    2023-08-11 18:30:02
  • OpenCV Java实现人脸识别和裁剪功能

    2022-08-21 01:47:23
  • Android 三级NestedScroll嵌套滚动实践

    2022-11-12 07:45:21
  • C#获取文件夹所占空间大小的功能

    2022-12-02 10:54:15
  • SpringCloud Eureka服务治理之服务注册服务发现

    2021-12-27 15:07:16
  • Android中如何指定SnackBar在屏幕的位置及小问题解决

    2023-08-07 07:56:19
  • mybatis源码解读-Java中executor包的语句处理功能

    2023-09-03 06:34:16
  • Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解

    2023-01-31 14:08:39
  • asp之家 软件编程 m.aspxhome.com