Android开发技巧之像QQ一样输入文字和表情图像
程序员文章站
2023-12-01 08:22:04
edittext和textview一样,也可以进行图文混排。所不同的是,textview只用于显示图文混排效果,而edittext不仅可显示,也可混合输入文字和图像,让我们...
edittext和textview一样,也可以进行图文混排。所不同的是,textview只用于显示图文混排效果,而edittext不仅可显示,也可混合输入文字和图像,让我们先回顾一下图5.2所示的qq聊天输入框,在输入框中可以同时输入文字和表情图像。实际上,这种效果在android sdk中只需要几行代码就可以实现。为了使读者更有学习的冲动,先来欣赏一下即将实现的效果,如图5.16所示。
图5.16 在edittext控件中输入文字和图像
为了实现这个程序,首先来准备一些要用到的素材,也就是要在edittext控件中输入的图像文件。本例准备了9个png图像文件(face1.png至face9.png),都放在了res\drawable目录中。
接下来在屏幕上放一个只能显示3行(可输入多行)的edittext和一个button,布局文件的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<edittext android:id="@+id/edittext" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:lines="3" android:gravity="left|top"/>
<button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="随机插入表情"
android:onclick="onclick_randomface" android:layout_margintop="10dp" />
</linearlayout>
上面代码的<edittext>标签中将android:gravity属性值设为left|top。以使输入的文本从左上角开始显示,如果不设置该属性,则输入的文本会从左侧中心位置开始显示(由于设置了android:line=”3”,因此,edittext可同时显示三行的内容,所以会存在这个问题,如果只显示一行,则不存在这个问题)。
<button>标签的android:onclick属性值指定了单击事件方法(onclick_randomface),在该方法中随机获得了face1.png至face9.png中任意一个图像资源的id。最常用的方法是将这9个图像资源id放到数组中,然后随机产生一个数组索引来获取相应的图像资源id。但本例未采用这种方法,而是采用了直接通过反射技术从r.drawable类中获得图像资源id的方法。这种方法的好处是一但图像资源非常多时,可以不需要在数组中挨个定义就可以获得任意的图像资源id。
在5.2.2节使用了<img>标签来插入图像,虽然在edittext控件中插入图像也可采用这种方法。但本例使用了另外一种更简单的方法,就是使用android.text.style.imagespan类来直接插入图像。下面来看看具体的实现代码。
public void onclick_randomface(view view)
{
// 随机产生1至9的整数
int randomid = 1 + new random().nextint(9);
try
{
// 根据随机产生的1至9的整数从r.drawable类中获得相应资源id(静态变量)的field对象
field field = r.drawable.class.getdeclaredfield("face" + randomid);
// 获得资源id的值,也就是静态变量的值
int resourceid = integer.parseint(field.get(null).tostring());
// 根据资源id获得资源图像的bitmap对象
bitmap bitmap = bitmapfactory.decoderesource(getresources(), resourceid);
// 根据bitmap对象创建imagespan对象
imagespan imagespan = new imagespan(this, bitmap);
// 创建一个spannablestring对象,以便插入用imagespan对象封装的图像
spannablestring spannablestring = new spannablestring("face");
// 用imagespan对象替换face
spannablestring.setspan(imagespan, 0, 4, spannable.span_exclusive_exclusive);
// 将随机获得的图像追加到edittext控件的最后
edittext.append(spannablestring);
}
catch (exception e)
{
}
}
编写上面代码需要注意如下几点:
1. 由于r.drawable中的资源id都是public的静态变量,因此,可直接使用field.get方法获得这些变量的值。如果是private或protected的变量,需要field.setaccessible(true)设置变量值的访问权限才可以读写这些变量。
2. 使用field.get方法获得变量值时,如果是静态变量。field.get方法的参数值设为null即可。如果不是静态变量,需要为field.get方法指定一个变量所在类的对象作为参数值。
3. 由于edittext类不能直接插入span对象,因此,需要先使用spannablestring对象来封装span对象(如本例中的imagespan对象),再将spannablestring对象插入到edittext控件中。
图5.16 在edittext控件中输入文字和图像
为了实现这个程序,首先来准备一些要用到的素材,也就是要在edittext控件中输入的图像文件。本例准备了9个png图像文件(face1.png至face9.png),都放在了res\drawable目录中。
接下来在屏幕上放一个只能显示3行(可输入多行)的edittext和一个button,布局文件的代码如下:
复制代码 代码如下:
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<edittext android:id="@+id/edittext" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:lines="3" android:gravity="left|top"/>
<button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="随机插入表情"
android:onclick="onclick_randomface" android:layout_margintop="10dp" />
</linearlayout>
上面代码的<edittext>标签中将android:gravity属性值设为left|top。以使输入的文本从左上角开始显示,如果不设置该属性,则输入的文本会从左侧中心位置开始显示(由于设置了android:line=”3”,因此,edittext可同时显示三行的内容,所以会存在这个问题,如果只显示一行,则不存在这个问题)。
<button>标签的android:onclick属性值指定了单击事件方法(onclick_randomface),在该方法中随机获得了face1.png至face9.png中任意一个图像资源的id。最常用的方法是将这9个图像资源id放到数组中,然后随机产生一个数组索引来获取相应的图像资源id。但本例未采用这种方法,而是采用了直接通过反射技术从r.drawable类中获得图像资源id的方法。这种方法的好处是一但图像资源非常多时,可以不需要在数组中挨个定义就可以获得任意的图像资源id。
在5.2.2节使用了<img>标签来插入图像,虽然在edittext控件中插入图像也可采用这种方法。但本例使用了另外一种更简单的方法,就是使用android.text.style.imagespan类来直接插入图像。下面来看看具体的实现代码。
复制代码 代码如下:
public void onclick_randomface(view view)
{
// 随机产生1至9的整数
int randomid = 1 + new random().nextint(9);
try
{
// 根据随机产生的1至9的整数从r.drawable类中获得相应资源id(静态变量)的field对象
field field = r.drawable.class.getdeclaredfield("face" + randomid);
// 获得资源id的值,也就是静态变量的值
int resourceid = integer.parseint(field.get(null).tostring());
// 根据资源id获得资源图像的bitmap对象
bitmap bitmap = bitmapfactory.decoderesource(getresources(), resourceid);
// 根据bitmap对象创建imagespan对象
imagespan imagespan = new imagespan(this, bitmap);
// 创建一个spannablestring对象,以便插入用imagespan对象封装的图像
spannablestring spannablestring = new spannablestring("face");
// 用imagespan对象替换face
spannablestring.setspan(imagespan, 0, 4, spannable.span_exclusive_exclusive);
// 将随机获得的图像追加到edittext控件的最后
edittext.append(spannablestring);
}
catch (exception e)
{
}
}
编写上面代码需要注意如下几点:
1. 由于r.drawable中的资源id都是public的静态变量,因此,可直接使用field.get方法获得这些变量的值。如果是private或protected的变量,需要field.setaccessible(true)设置变量值的访问权限才可以读写这些变量。
2. 使用field.get方法获得变量值时,如果是静态变量。field.get方法的参数值设为null即可。如果不是静态变量,需要为field.get方法指定一个变量所在类的对象作为参数值。
3. 由于edittext类不能直接插入span对象,因此,需要先使用spannablestring对象来封装span对象(如本例中的imagespan对象),再将spannablestring对象插入到edittext控件中。