小弟我的Android案例—电子词典

我的Android案例—电子词典

2015年的Android案例之旅

案例七:电子词典

知识点:

1.自动完成文本框(AutoCompleteTextView)

AutoCompleteTextView是从EditText派生出来的,当用户输入一定字符之后,AutoCompleteTextView会显示一个下拉菜单,供用户选择,当用户选择某个菜单之后,内容会被填充到该文本中。

使用AutoCompleteTextView需要设置一个Adapter,该Adapter封装了预设的提示文本

2.SQLiteDataBase数据库

3.Adapter适配器

涉及文件:

res->layout->activity_main.xml 布局文件

res->layout->word_list_item.xml 布局文件

res->raw-> dictionary.db 词典数据库

res->values->strings 资源文件之字符串资源

res->values->color 资源文件之颜色资源

res->AndroidManifest.xml 系统清单文件 主要添加SD卡相关权限

src->package->MainActivity.java java文件

activity_main.xml
<!-- 线性布局 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#ff808080">
    <!-- 相对布局
    	用于设置搜索框和搜索按钮 -->
    <RelativeLayout android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <!-- 定义自动完成文本框,供用户输入单词 -->
        <AutoCompleteTextView 
            android:id="@+id/word"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:ems="20"
            android:layout_toLeftOf="@+id/searchWord"/>
        <!-- 搜索按钮,供用户点击查询单词 -->
        <Button 
            android:id="@+id/searchWord"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_alignParentRight="true"
            android:text="@string/search"/>
    </RelativeLayout>
    <!-- 查询结果 -->
    <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/result"/>
     <!-- 用户显示查询的结果 -->
    <TextView 
        android:id="@+id/show"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:textColor="@color/blue"/>
</LinearLayout>
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:gravity="center_vertical"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:paddingLeft="6dip"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textColor="@color/gray" />
MainActivity.java
package com.example.mydicitonary;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v4.widget.CursorAdapter;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
	//定义Log标签
	private static final String TAG = "DICITONARY";
	//声明控件对象
	private Button search;
	private TextView show;
	private AutoCompleteTextView actv;
	
	//用到SQLiteDateBase
	//定义数据库的存放路径
	private static final String DATEBASE_PATH = android.os.Environment
			.getExternalStorageDirectory().getAbsolutePath()
			+ "/dictionary";
	//定义数据库的名字
	private static final String DATEBASE_NAME = "dictionary.db";
	private SQLiteDatabase database;
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Log.i(TAG, "DICITONARY is onCreate");
		
		//获取布局中的控件
		init();
		//打开数据库
		database = openDateBase();
		
		//监听事件处理
		listener();
	}


	/**
	 * @oaram 初始化控件
	 */
	private void init(){
		search = (Button)this.findViewById(R.id.searchWord);
		show = (TextView)this.findViewById(R.id.show);
		actv = (AutoCompleteTextView)this.findViewById(R.id.word);
	}
	
	/**
	 * @param 处理监听事件
	 */
	private void listener(){
		//按钮点击事件
		search.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				String result = "未查到该单词信息";
				//查询指定的单词
				String sql = "select chinese from t_words where english=?";		
				Cursor cursor = database.rawQuery(sql, new String[]{
						actv.getText().toString()	
				});
				if(cursor.getCount()>0){
					// 必须使用moveToFirst方法将记录指针移动到第1条记录的位置
					cursor.moveToFirst();
					result = cursor.getString(cursor.getColumnIndex("chinese")).replace("&", "&");
				}
				//将结果显示到TextView中
				show.setText(actv.getText().toString() +"\n"+result);
			}
		});
		
		//文本变动事件
		actv.addTextChangedListener(new TextWatcher() {
			
			@Override
			public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
					int arg3) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void afterTextChanged(Editable s) {
				Cursor cursor = database.rawQuery(
						"select english as _id from t_words where english like ?",
						new String[]
						{ s.toString() + "%" });
				//新建新的Adapter
				DictionaryAdapter dictionaryAdapter = new DictionaryAdapter(MainActivity.this,
						cursor, true);
				//绑定适配器
				actv.setAdapter(dictionaryAdapter);
				
			}
		});
	}
	
	//自定义Adapter类
	public class DictionaryAdapter extends CursorAdapter{
		//对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;
		//对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。
		private LayoutInflater layoutInflater;

		public DictionaryAdapter(Context context, Cursor c, boolean autoRequery)
		{
			super(context, c, autoRequery);
			layoutInflater = (LayoutInflater) context
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}
		
		@Override
		public CharSequence convertToString(Cursor cursor)
		{
			return cursor == null ? "" : cursor.getString(cursor
					.getColumnIndex("_id"));
		}

		//将单词信息显示到列表中
		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 arg2) {
			View view = layoutInflater.inflate(R.layout.word_list_item, null);
			setView(view, cursor);
			return view;
		}
		
	}
	
	/**
	 * @param	返回一个SQLiteDatabase对象
	 * @return
	 */
	private SQLiteDatabase openDateBase(){
		try {
			// 获得dictionary.db文件的绝对路径
			String databaseFileName = DATEBASE_PATH + "/" + DATEBASE_NAME;
			File dir = new File(DATEBASE_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[9128];
				int count = 0;
				// 开始复制dictionary.db文件
				while((count = is.read(buffer))!=-1){
					fos.write(buffer, 0, count);
				}
				//关闭文件流
				is.close();
				fos.close();
			}
			// 打开/sdcard/dictionary目录中的dictionary.db文件
			SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(
					databaseFileName, null);
			return database;
		} catch (Exception e) {
			// TODO: handle exception
		}
		return null;
	}

}