Android開發(fā)技巧之像QQ一樣輸入文字和表情圖像
更新時(shí)間:2013年01月22日 10:31:29 作者:
QQ聊天輸入框,在輸入框中可以同時(shí)輸入文字和表情圖像。實(shí)際上,這種效果在Android SDK中只需要幾行代碼就可以實(shí)現(xiàn),本文將會(huì)介紹如何實(shí)現(xiàn)像QQ一樣輸入表情圖像
EditText和TextView一樣,也可以進(jìn)行圖文混排。所不同的是,TextView只用于顯示圖文混排效果,而EditText不僅可顯示,也可混合輸入文字和圖像,讓我們先回顧一下圖5.2所示的QQ聊天輸入框,在輸入框中可以同時(shí)輸入文字和表情圖像。實(shí)際上,這種效果在Android SDK中只需要幾行代碼就可以實(shí)現(xiàn)。為了使讀者更有學(xué)習(xí)的沖動(dòng),先來欣賞一下即將實(shí)現(xiàn)的效果,如圖5.16所示。

圖5.16 在EditText控件中輸入文字和圖像
為了實(shí)現(xiàn)這個(gè)程序,首先來準(zhǔn)備一些要用到的素材,也就是要在EditText控件中輸入的圖像文件。本例準(zhǔn)備了9個(gè)png圖像文件(face1.png至face9.png),都放在了res\drawable目錄中。
接下來在屏幕上放一個(gè)只能顯示3行(可輸入多行)的EditText和一個(gè)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="隨機(jī)插入表情"
android:onClick="onClick_RandomFace" android:layout_marginTop="10dp" />
</LinearLayout>
上面代碼的<EditText>標(biāo)簽中將android:gravity屬性值設(shè)為left|top。以使輸入的文本從左上角開始顯示,如果不設(shè)置該屬性,則輸入的文本會(huì)從左側(cè)中心位置開始顯示(由于設(shè)置了android:line=”3”,因此,EditText可同時(shí)顯示三行的內(nèi)容,所以會(huì)存在這個(gè)問題,如果只顯示一行,則不存在這個(gè)問題)。
<Button>標(biāo)簽的android:onClick屬性值指定了單擊事件方法(onClick_RandomFace),在該方法中隨機(jī)獲得了face1.png至face9.png中任意一個(gè)圖像資源的ID。最常用的方法是將這9個(gè)圖像資源ID放到數(shù)組中,然后隨機(jī)產(chǎn)生一個(gè)數(shù)組索引來獲取相應(yīng)的圖像資源ID。但本例未采用這種方法,而是采用了直接通過反射技術(shù)從R.drawable類中獲得圖像資源ID的方法。這種方法的好處是一但圖像資源非常多時(shí),可以不需要在數(shù)組中挨個(gè)定義就可以獲得任意的圖像資源ID。
在5.2.2節(jié)使用了<img>標(biāo)簽來插入圖像,雖然在EditText控件中插入圖像也可采用這種方法。但本例使用了另外一種更簡(jiǎn)單的方法,就是使用android.text.style.ImageSpan類來直接插入圖像。下面來看看具體的實(shí)現(xiàn)代碼。
public void onClick_RandomFace(View view)
{
// 隨機(jī)產(chǎn)生1至9的整數(shù)
int randomId = 1 + new Random().nextInt(9);
try
{
// 根據(jù)隨機(jī)產(chǎn)生的1至9的整數(shù)從R.drawable類中獲得相應(yīng)資源ID(靜態(tài)變量)的Field對(duì)象
Field field = R.drawable.class.getDeclaredField("face" + randomId);
// 獲得資源ID的值,也就是靜態(tài)變量的值
int resourceId = Integer.parseInt(field.get(null).toString());
// 根據(jù)資源ID獲得資源圖像的Bitmap對(duì)象
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
// 根據(jù)Bitmap對(duì)象創(chuàng)建ImageSpan對(duì)象
ImageSpan imageSpan = new ImageSpan(this, bitmap);
// 創(chuàng)建一個(gè)SpannableString對(duì)象,以便插入用ImageSpan對(duì)象封裝的圖像
SpannableString spannableString = new SpannableString("face");
// 用ImageSpan對(duì)象替換face
spannableString.setSpan(imageSpan, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 將隨機(jī)獲得的圖像追加到EditText控件的最后
edittext.append(spannableString);
}
catch (Exception e)
{
}
}
編寫上面代碼需要注意如下幾點(diǎn):
1. 由于R.drawable中的資源ID都是public的靜態(tài)變量,因此,可直接使用Field.get方法獲得這些變量的值。如果是private或protected的變量,需要field.setAccessible(true)設(shè)置變量值的訪問權(quán)限才可以讀寫這些變量。
2. 使用Field.get方法獲得變量值時(shí),如果是靜態(tài)變量。Field.get方法的參數(shù)值設(shè)為null即可。如果不是靜態(tài)變量,需要為Field.get方法指定一個(gè)變量所在類的對(duì)象作為參數(shù)值。
3. 由于EditText類不能直接插入Span對(duì)象,因此,需要先使用SpannableString對(duì)象來封裝Span對(duì)象(如本例中的ImageSpan對(duì)象),再將SpannableString對(duì)象插入到EditText控件中。

圖5.16 在EditText控件中輸入文字和圖像
為了實(shí)現(xiàn)這個(gè)程序,首先來準(zhǔn)備一些要用到的素材,也就是要在EditText控件中輸入的圖像文件。本例準(zhǔn)備了9個(gè)png圖像文件(face1.png至face9.png),都放在了res\drawable目錄中。
接下來在屏幕上放一個(gè)只能顯示3行(可輸入多行)的EditText和一個(gè)Button,布局文件的代碼如下:
復(fù)制代碼 代碼如下:
<?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="隨機(jī)插入表情"
android:onClick="onClick_RandomFace" android:layout_marginTop="10dp" />
</LinearLayout>
上面代碼的<EditText>標(biāo)簽中將android:gravity屬性值設(shè)為left|top。以使輸入的文本從左上角開始顯示,如果不設(shè)置該屬性,則輸入的文本會(huì)從左側(cè)中心位置開始顯示(由于設(shè)置了android:line=”3”,因此,EditText可同時(shí)顯示三行的內(nèi)容,所以會(huì)存在這個(gè)問題,如果只顯示一行,則不存在這個(gè)問題)。
<Button>標(biāo)簽的android:onClick屬性值指定了單擊事件方法(onClick_RandomFace),在該方法中隨機(jī)獲得了face1.png至face9.png中任意一個(gè)圖像資源的ID。最常用的方法是將這9個(gè)圖像資源ID放到數(shù)組中,然后隨機(jī)產(chǎn)生一個(gè)數(shù)組索引來獲取相應(yīng)的圖像資源ID。但本例未采用這種方法,而是采用了直接通過反射技術(shù)從R.drawable類中獲得圖像資源ID的方法。這種方法的好處是一但圖像資源非常多時(shí),可以不需要在數(shù)組中挨個(gè)定義就可以獲得任意的圖像資源ID。
在5.2.2節(jié)使用了<img>標(biāo)簽來插入圖像,雖然在EditText控件中插入圖像也可采用這種方法。但本例使用了另外一種更簡(jiǎn)單的方法,就是使用android.text.style.ImageSpan類來直接插入圖像。下面來看看具體的實(shí)現(xiàn)代碼。
復(fù)制代碼 代碼如下:
public void onClick_RandomFace(View view)
{
// 隨機(jī)產(chǎn)生1至9的整數(shù)
int randomId = 1 + new Random().nextInt(9);
try
{
// 根據(jù)隨機(jī)產(chǎn)生的1至9的整數(shù)從R.drawable類中獲得相應(yīng)資源ID(靜態(tài)變量)的Field對(duì)象
Field field = R.drawable.class.getDeclaredField("face" + randomId);
// 獲得資源ID的值,也就是靜態(tài)變量的值
int resourceId = Integer.parseInt(field.get(null).toString());
// 根據(jù)資源ID獲得資源圖像的Bitmap對(duì)象
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
// 根據(jù)Bitmap對(duì)象創(chuàng)建ImageSpan對(duì)象
ImageSpan imageSpan = new ImageSpan(this, bitmap);
// 創(chuàng)建一個(gè)SpannableString對(duì)象,以便插入用ImageSpan對(duì)象封裝的圖像
SpannableString spannableString = new SpannableString("face");
// 用ImageSpan對(duì)象替換face
spannableString.setSpan(imageSpan, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 將隨機(jī)獲得的圖像追加到EditText控件的最后
edittext.append(spannableString);
}
catch (Exception e)
{
}
}
編寫上面代碼需要注意如下幾點(diǎn):
1. 由于R.drawable中的資源ID都是public的靜態(tài)變量,因此,可直接使用Field.get方法獲得這些變量的值。如果是private或protected的變量,需要field.setAccessible(true)設(shè)置變量值的訪問權(quán)限才可以讀寫這些變量。
2. 使用Field.get方法獲得變量值時(shí),如果是靜態(tài)變量。Field.get方法的參數(shù)值設(shè)為null即可。如果不是靜態(tài)變量,需要為Field.get方法指定一個(gè)變量所在類的對(duì)象作為參數(shù)值。
3. 由于EditText類不能直接插入Span對(duì)象,因此,需要先使用SpannableString對(duì)象來封裝Span對(duì)象(如本例中的ImageSpan對(duì)象),再將SpannableString對(duì)象插入到EditText控件中。
您可能感興趣的文章:
- 基于Android開發(fā)支持表情的實(shí)現(xiàn)詳解
- Android自帶emoji表情的使用方法詳解
- Android編程實(shí)現(xiàn)QQ表情的發(fā)送和接收完整實(shí)例(附源碼)
- 完整的Android表情功能處理方案
- Android編程開發(fā)實(shí)現(xiàn)TextView顯示表情圖像和文字的方法
- 詳解Android過濾emoji表情正則表達(dá)式
- android高仿微信表情輸入與鍵盤輸入代碼(詳細(xì)實(shí)現(xiàn)分析)
- Android EdText編輯框禁止輸入表情符號(hào)(使用正則表達(dá)式)
- Android輸入框添加emoje表情圖標(biāo)的實(shí)現(xiàn)代碼
- Android實(shí)現(xiàn)表情功能
相關(guān)文章
flutter 實(shí)現(xiàn)點(diǎn)擊下拉欄微信右上角彈出窗功能
這篇文章主要介紹了flutter 實(shí)現(xiàn)彈出窗點(diǎn)擊下拉欄微信右上角彈出窗功能,這段代碼使用的是PopupRoute這個(gè)路由類進(jìn)行實(shí)現(xiàn) 的,分步驟通過實(shí)例代碼講解的非常詳細(xì),需要的朋友可以參考下2021-05-05Android使用Sensor感應(yīng)器獲取用戶移動(dòng)方向(指南針原理)
這篇文章主要介紹了Android使用Sensor感應(yīng)器獲取用戶移動(dòng)方向的方法,實(shí)例分析了指南針原理極其應(yīng)用,需要的朋友可以參考下2015-12-12Android編程獲取系統(tǒng)隱藏服務(wù)實(shí)現(xiàn)鎖屏的方法
這篇文章主要介紹了Android編程獲取系統(tǒng)隱藏服務(wù)實(shí)現(xiàn)鎖屏的方法,涉及Android關(guān)于廣播,服務(wù),權(quán)限及鎖屏等操作的相關(guān)技巧,需要的朋友可以參考下2015-12-12Android中的popupwindow進(jìn)入和退出的動(dòng)畫效果
這篇文章主要介紹了Android中的popupwindow進(jìn)入和退出的動(dòng)畫,需要的朋友可以參考下2017-04-04Android數(shù)據(jù)持久化之SQLite數(shù)據(jù)庫(kù)用法分析
這篇文章主要介紹了Android數(shù)據(jù)持久化之SQLite數(shù)據(jù)庫(kù)用法,結(jié)合實(shí)例形式分析了SQLite概念、功能、相關(guān)操作類與使用技巧,需要的朋友可以參考下2017-05-05Ubuntu中為Android簡(jiǎn)單介紹硬件抽象層(HAL)
本文主要介紹在Android 的硬件抽象層,學(xué)習(xí)Android 硬件抽象層(HAL)對(duì)理解整個(gè)Android都是有非常大的作用,有興趣的小伙伴可以參考下2016-08-08詳解Android平臺(tái)上讀寫NFC標(biāo)簽
NFC,即Near Field Communication,近距離無線通訊技術(shù),是一種短距離的(通常<=4cm或更短)高頻(13.56M Hz)無線通信技術(shù),可以讓消費(fèi)者簡(jiǎn)單直觀地交換信息、訪問內(nèi)容與服務(wù)。2017-01-01