开发者社区> geekori> 正文

实现基于Android的英文电子词典

简介: 本文为原创,如需转载,请注明作者和出处,谢谢!   英文词典是手机中经常使用的应用。因此,在本文将结合Android来讨论如何实现一个Android版的英文词典。
+关注继续查看

本文为原创,如需转载,请注明作者和出处,谢谢!

  英文词典是手机中经常使用的应用。因此,在本文将结合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表的结果,该表只有两个字段:englishchinese。分别表示单词的英文和中文描述。如果要获得单词的中文描述,只需要查找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组件中的文本。因此,必须使用CursorgetString来获得相应的字段值。

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类中需要使用bindViewnewView方法设置每一个列表项。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手机客户端(新浪微博)发布

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
13564 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
32662 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
14468 0
使用NAT网关轻松为单台云服务器设置多个公网IP
在应用中,有时会遇到用户询问如何使单台云服务器具备多个公网IP的问题。 具体如何操作呢,有了NAT网关这个也不是难题。
34422 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
8794 0
实现基于Android的英文电子词典
本文为原创,如需转载,请注明作者和出处,谢谢!   英文词典是手机中经常使用的应用。因此,在本文将结合Android来讨论如何实现一个Android版的英文词典。
1102 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
11669 0
使用SSH远程登录阿里云ECS服务器
远程连接服务器以及配置环境
12212 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
19437 0
+关注
geekori
欧瑞科技创始人&amp;CEO,东北大学计算机专业硕士,拥有超过20年软件开分经验。欧瑞学院金牌讲师、51CTO学院金牌讲师、CSDN学院特约讲师、畅销书作者,企业内训讲师。曾出版过超过30本IT畅销书,涉猎移动开发、跨平台开发、机器学习、区块链、大数据、编译器等领域。
419
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载