您的位置:首页 > 移动开发 > Android开发

实现基于Android的英文词典

2010-08-15 19:58 489 查看
[b][b][b][b][b][b][b]本文为原创,如需转载,请注明作者和出处,谢谢!
[/b]
[/b]
[/b]
[/b]
[/b]
[/b]
[/b]

英文词典是手机中经常使用的应用。因此,在本文将结合
Android
来讨论如何实现一个
Android
版的英文词典。实现英文词典的方法很多。在本文使用了
SQLite
数据库来保存英文单词信息。系统通过
SQLite
数据库中保存的单词信息来查找到与指定英文对应的中文信息。当然,实现这样一个英文词典需要解决一系列技术问题。例如,如何将保存英文单词信息的数据库文件随程序(
apk
文件)一起发布;发布后如何打开数据库;如何在输入前几个字母后,在
AutoCompleteTextView
组件提示列表中显示以所输入字符串开头的所有单词。在本章将逐渐给出这些问题的详细答案。

实现电子词典要解决的技术问题及初步的解答

在这里将给出实现电子词典需要解决的主要技术问题,并给出这些技术问题的初步答案或提示。关于详细的答案和代码请读者参阅本文后面的内容。

主要技术问题及解答如下:

1. 如何将SQLite数据库(dictionary.db文件)与apk文件一起发布?

解答:可以将dictionary.db文件复制到Eclipse Android工程中的res/raw目录中,如图1所示。所有在res/raw目录中的文件不会被压缩,这样可以直接提取该目录中的文件。



图1


dictionary.db
文件复制到
res/raw
目录中

2.
如何将打开
res/raw
目录中的数据库文件?

解答:在Android
中不能直接打开
res/raw
目录中的数据库文件,而需要在程序第一次启动时将该文件复制到手机内存或
SD
卡的某个目录中,然后再打开该数据库文件。复制的基本方法是使用
getResources().openRawResource
方法获得
res/raw
目录中资源的
InputStream
对象,然后将该
InputStream
对象中的数据写入其他的目录中相应文件中。在Android
SDK
中可以使用
SQLiteDatabase.openOrCreateDatabase
方法来打开任意目录中的
SQLite
数据库文件。

3.

如果在
AutoCompleteTextView
组件中输入两个及以上字母时显示以所输入字符串开头的所有单词列表?

解答:
AutoCompleteTextView
所使用的
Adapter
是一个自定义的
Adapter
类,类的结构如下:

public

class
DictionaryAdapter
extends
CursorAdapter

{





}

要注意的是,不能将整个数据库中的单词都查出,然后生成一个
Adapter
对象再使用
setAdapter
方法来设置
AutoCompleteTextView
组件的
Adapter
对象。
AutoCompleteTextView
组件不会为我们筛选以某个字符串开头的单词。这些工作需要开发人员通过编码来实现。

基本思路是在
AutoCompleteTextView
类的
afterTextChanged
事件中监视
AutoCompleteTextView
组件中字符的输入情况,每当输入一个字符时就生成一个
Adapter
对象,然后将新生成的
Adapter
对象与
AutoCompleteTextView
关联。显示以输入字符串开头的单词列表的效果如图
2
所示。



图2

显示以输入字符串开头的单词列表

复制并打开保存英文单词的数据库文件

在本文实现的英文词典中使用openDatabase方法来打开数据库文件(该文件在SD卡的dictionary目录中,因此,要想运行本文实现的英文
词典,需要在手机或模拟器中需要安装SD卡)。如果该文件不存在,系统会自动创建/sdcard/dictionary目录,并将res/raw目录中的
dictionary.db文件复制到/sdcard/dictionary目录中。openDatabase方法的实现代码如下:

private
SQLiteDatabase openDatabase()

{

try

{

//
获得dictionary.db文件的绝对路径

String databaseFilename
=
DATABASE_PATH
+

"
/
"

+
DATABASE_FILENAME;

File dir
=

new
File(DATABASE_PATH);

//
如果/sdcard/dictionary目录中存在,创建这个目录

if
(
!
dir.exists())

dir.mkdir();

//
如果在/sdcard/dictionary目录中不存在

//
dictionary.db文件,则从res/raw目录中复制这个文件到

//
SD卡的目录(/sdcard/dictionary)

if
(
!
(
new
File(databaseFilename)).exists())

{

//
获得封装dictionary.db文件的InputStream对象

InputStream is
=
getResources().openRawResource(R.raw.dictionary);

FileOutputStream fos
=

new
FileOutputStream(databaseFilename);

byte
[] buffer
=

new

byte
[
8192
];

int
count
=

0
;

//
开始复制dictionary.db文件

while
((count
=
is.read(buffer))
>

0
)

{

fos.write(buffer,
0
, count);

}

fos.close();

is.close();

}

//
打开/sdcard/dictionary目录中的dictionary.db文件

SQLiteDatabase database
=
SQLiteDatabase.openOrCreateDatabase(

databaseFilename,
null
);

return
database;

}

catch
(Exception e)

{

}

return

null
;

}


openDatabase
方法中使用了几个常量,这些常量是在程序的主类(
Main
)中定义的,代码如下:

public

class
Main
extends
Activity
implements
OnClickListener, TextWatcher

{

private

final
String DATABASE_PATH
=
android.os.Environment

.getExternalStorageDirectory().getAbsolutePath()

+

"
/dictionary
"
;

private

final
String DATABASE_FILENAME
=

"
dictionary.db
"
;





}

查询单词

英文词典的核心就是查找英文单词的中文意思。在查找中文意思之前,首先需要使用openDatabase方法在Main类的onCreate方法中打开SQLite数据库,代码如下:

database = openDatabase();

其中database是在Main类中定义的SQLiteDatabase类型变量。

然后在查找按钮的单击事件中添加如下的代码来查找英文单词,并显示中文意思。

public

void
onClick(View view)

{

String sql
=

"
select chinese from t_words where english=?
"
;

Cursor cursor
=
database.rawQuery(sql,
new
String[]

{ actvWord.getText().toString() });

String result
=

"
未找到该单词.
"
;

//
如果查找单词,显示其中文信息

if
(cursor.getCount()
>

0
)

{

//
必须使用moveToFirst方法将记录指针移动到第1条记录的位置

cursor.moveToFirst();

result
=
cursor.getString(cursor.getColumnIndex(
"
chinese
"
));

}

//
显示查询结果对话框

new
AlertDialog.Builder(
this
).setTitle(
"
查询结果
"
).setMessage(result)

.setPositiveButton(
"
关闭
"
,
null
).show();

}

讲到这里我们应该了解一个
dictionary.db
中的
t_words
表的结果,该表只有两个字段:
english

chinese
。分别表示单词的英文和中文描述。如果要获得单词的中文描述,只需要查找
chinese
字段即可。如
onClick
方法中的代码所示。

查询单词的效果如图
3
所示。




3

查询英文单词

如果显示以输入字符串开头的单词列表

虽然到目前为止,我们的英文词典已经可以正常工作了,但为了方便读者使用,在本节将添加单词输入的自动提示功能。也就是说,如果读者在
AutoCompleteTextView组件中输入单词的前几个字母,该组件就会自动列出数据库中所有以该字符串开头的单词。效果如图2所示。拥有这样
的功能就可以使用户在只知道单词的前几个字母时也可以查找到相应的单词。

由于AutoCompleteTextView组件使用了自定义的Adapter类,下面先给出这个自定义的Adapter类的完整代码。

public

class
DictionaryAdapter
extends
CursorAdapter

{

private
LayoutInflater layoutInflater;

@Override

public
CharSequence convertToString(Cursor cursor)

{

return
cursor
==

null

?

""
: cursor.getString(cursor

.getColumnIndex(
"
_id
"
));

}

//
用于将_id字段(也就是english字段)的值设置TextView组件的文本

//
view参数表示用于显示列表项的TextView组件

private

void
setView(View view, Cursor cursor)

{

TextView tvWordItem
=
(TextView) view;

tvWordItem.setText(cursor.getString(cursor.getColumnIndex(
"
_id
"
)));

}

@Override

public

void
bindView(View view, Context context, Cursor cursor)

{

setView(view, cursor);

}

@Override

public
View newView(Context context, Cursor cursor, ViewGroup parent)

{

View view
=
layoutInflater.inflate(R.layout.word_list_item,
null
);

setView(view, cursor);

return
view;

}

public
DictionaryAdapter(Context context, Cursor c,
boolean
autoRequery)

{

super
(context, c, autoRequery);

//
通过系统服务获得LayoutInflater对象

layoutInflater
=
(LayoutInflater) context

.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

}

在编写
DictionaryAdapter
类时应注意如下
3
点:

1.
为了将
Cursor
对象与
AutoCompleteTextView
组件绑定,
DictionaryAdapter
类必须从
CursorAdapter
类继承。

2.

由于
CursorAdapter
类中的
convertToString
方法直接返回了
Cursor
对象的地址,因此,在
DictionaryAdapter
类中必须覆盖
convertToString
方法,以返回当前选中的单词。
CursorAdapter
类中的
convertToString
方法的源代码。

public
CharSequence convertToString(Cursor cursor)

{

//
如果cursor不为null,返回Cursor对象的地址(cursor.toString())

return
cursor
==

null

?

""
: cursor.toString();

}

覆盖后的
convertToToString
方法的源代码如下:

public
CharSequence convertToString(Cursor cursor)

{

return
cursor
==

null

?

""
: cursor.getString(cursor

.getColumnIndex(
"
_id
"
));

}

在这里要注意一下,当选中
AutoCompleteTextView
组件中单词列表中某一个单词后,系统会用
convertToString
方法的返回值来设置
AutoCompleteTextView
组件中的文本。因此,必须使用
Cursor

getString
来获得相应的字段值。

3.

由于将
Cursor
对象与
Adapter
绑定时必须要有一个叫“
_id
”的字段,因此,在本例中将
english
字段名映射成了“
_id
”字段。

为了监视
AutoCompleteTextView
组件中的文本输入情况,需要实现
android.text.TextWatcher
接口。在该接口中只需要实现
afterTextChanged
方法即可,代码如下:

public

void
afterTextChanged(Editable s)

{

//
必须将english字段的别名设为_id

Cursor cursor
=
database.rawQuery(

"
select english as _id from t_words where english like ?
"
,

new
String[]{ s.toString()
+

"
%
"
});

DictionaryAdapter dictionaryAdapter
=

new
DictionaryAdapter(
this
,cursor,
true
);

//
actvWord是在Main类中定义的AutoCompleteTextView类型的变量

actvWord.setAdapter(dictionaryAdapter);

}

从上面的代码中可以看到,在查询
SQL
语句中的
english
字段名的别名是“
_id
”。

4.


DictionaryAdapter
类中需要使用
bindView

newView
方法设置每一个列表项。
bindView
方法负责设置已经存在的列表项,也就是该列表项已经生成了相应的组件对象。而
newView
方法负责设置新的列表项,在该方法中需要创建一个
View
对象来显示当前的列表项。在本例中使用
word_list_item.xml
布局文件来显示每一个列表项,代码如下:

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

<
TextView
xmlns:android
="http://schemas.android.com/apk/res/android"

android:id
="@+id/tvWordItem"

android:layout_width
="fill_parent"

android:layout_height
="wrap_content"

android:textAppearance
="?android:attr/textAppearanceLarge"

android:gravity
="center_vertical"

android:paddingLeft
="6dip"

android:textColor
="#000"

android:minHeight
="?android:attr/listPreferredItemHeight"

/>

本文介绍了实现基于
Android
的英文词典的实现方法。实现英文词典主要需要解决
3
个问题:如何将保存英文单词的
SQLite
数据库文件随同
apk
文件一起发布;如何打开
SD
卡中的数据库文件;如何在
AutoCompleteTextView
组件显示以输入字符串开头的英文单词列表。在最后仍然要提一句的是在编写自定义
DictionaryAdapter
类时一定要覆盖
contertToString
方法,以便在用户选项某一个列表项时在
AutoCompleteTextView
组件中显示选中的单词,而不是
Cursor
对象地址。



《Android/OPhone开发完全讲义》(本书版权已输出到台湾)


样章和目录下载

互动网

当当网

卓越亚马逊

《人人都玩开心网:Ext JS+Android+SSH整合开发Web与移动SNS》


样章下载

互动网

乐博Android手机客户端(新浪微博)

发布
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: