編輯:關於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表的結果,該表只有兩個字段: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軟件編程有所幫助。
直接上效果圖: 實現步驟: 1.主界面activity_main.xml很簡單,一個按鈕 2.彈出層樣式actionsheet.xml
1.從結構上分析jsp+servlet圖解原理:在基於mvc設計模式下的最原始的jsp+Servlet框架,在某種程度上是不能夠達到mvc最直觀的體現。當客戶端發送請求到
項目下載地址:https://github.com/Aiushtha/android-PictureSelector最早使用android調用系統拍照然後遇到很多空指針等
日志可以在幫我們開發中調試程序,下面看看Android自帶日志的作用先聲明一個字符串 private static final String TAG = &qu