目录工程如下:
具体实现以及写的过程中遇到的问题
第一步:建立数据库。
加载数据数据库到项目中来,在res目录下建立一个raw文件夹,
DBOpenHelper.java
package cn.deu.bztc.happyidiom.db;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import cn.deu.bztc.happyidiom.activity.R;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
public class DBOpenHelper {
private final int BuFFWER_SIZE=400000;//缓冲区大小
public static final String DB_NAME="idioms.db";//保存的数据库文件名
public static final String PACKAGE_Name="cn.deu.bztc.happyidiom.activity";
//应用的包名
public static final String DB_PATH="/data"
+Environment.getDataDirectory().getAbsolutePath()+"/"
+PACKAGE_Name+"/databases";//在手机里存放数据库的位置
private Context context;
public DBOpenHelper(Context context) {
super();
this.context = context;
}
public SQLiteDatabase openDatabase(){
try{
File myDataPath=new File(DB_PATH);
if(!myDataPath.exists()){
myDataPath.mkdirs(); //如果没有这个目录则创建
}
String dbfile=myDataPath+"/"+DB_NAME;
if(!(new File(dbfile).exists())){
//判断数据库文件是否存在,若不存在则执行导入,否则直接打开数据库
InputStream is=context.getResources().openRawResource(R.raw.idioms);
FileOutputStream fos=new FileOutputStream(dbfile);
byte[] buffer=new byte[BuFFWER_SIZE];
int count=0;
while((count=is.read(buffer))>0){
fos.write(buffer, 0, count);
}
fos.close();
is.close();
}
SQLiteDatabase db=SQLiteDatabase.openOrCreateDatabase(dbfile, null);
return db;
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}
}
上面的代码实现功能主要是使用输入输出流将idioms.db复制到手机中默认存放 数据库的位置
下面我们来测试一下是否成功
在AndroidManifest.xml中建立单元测试环境
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.deu.bztc.happyidiom.activity"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/logo"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
<span style="color:#ff0000;"> <uses-library android:name="android.test.runner" /></span>
<activity
android:name="cn.deu.bztc.happyidiom.activity.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="cn.deu.bztc.happyidiom.activity.StudyAnimalActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name="cn.deu.bztc.happyidiom.util.DialogUtil"
android:label="@string/app_name" >
</activity>
<activity
android:name="cn.deu.bztc.happyidiom.activity.StudyActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name="com.tangsci.android.example.ttsdemo.TtsDemoActivity"
android:label="@string/app_name" >
</activity>
</application>
<span style="color:#ff0000;"><instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="cn.deu.bztc.happyidiom.activity" >
</instrumentation></span>
</manifest>
下面我们来测试一下是否成功:
在test包下建立DBOpenHelpTest.java
package cn.deu.bztc.happyidiom.test;
import java.util.List;
import cn.deu.bztc.happyidiom.dao.AnimalDao;
import cn.deu.bztc.happyidiom.db.DBOpenHelper;
import cn.deu.bztc.happyidiom.entity.Animal;
import android.test.AndroidTestCase;
public class DBOpenHelpTest extends AndroidTestCase {
public void testDBCOpy(){
DBOpenHelper dbopenHelper=new DBOpenHelper(getContext());
dbopenHelper.openDatabase();
}
public void testGetAllAnimals(){
AnimalDao animalDao=AnimalDao.getInstance(getContext());
List<Animal> animals=animalDao.getAllAnimals();
System.out.println(animals.size());
for(Animal animal:animals){
System.out.println(animal.getName());
}
}
}
然后你会发现在raw目录下多个数据库
cn.deu.bztc.happyidiom.entity建立实体类
Animal.java
package cn.deu.bztc.happyidiom.entity;
public class Animal {
private int id;
private String name;//成语名称
private String pronounce;//成语发音
private String explain;//成语解释
private String antonym;//反义词
private String homoionym;//同义词
private String derivation;//源自
private String examples;//例子
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPronounce() {
return pronounce;
}
public void setPronounce(String pronounce) {
this.pronounce = pronounce;
}
public String getExplain() {
return explain;
}
public void setExplain(String explain) {
this.explain = explain;
}
public String getAntonym() {
return antonym;
}
public void setAntonym(String antonym) {
this.antonym = antonym;
}
public String getHomoionym() {
return homoionym;
}
public void setHomoionym(String homoionym) {
this.homoionym = homoionym;
}
public String getDerivation() {
return derivation;
}
public void setDerivation(String derivation) {
this.derivation = derivation;
}
public String getExamples() {
return examples;
}
public void setExamples(String examples) {
this.examples = examples;
}
}
然后在数据库管理层 (Dao 层)建立操作类AnimalDao.java
package cn.deu.bztc.happyidiom.dao;
import java.util.ArrayList;
import java.util.List;
import cn.deu.bztc.happyidiom.db.DBOpenHelper;
import cn.deu.bztc.happyidiom.entity.Animal;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class AnimalDao {
private static AnimalDao animalDao;
private static SQLiteDatabase db;
/**
* 将构造方法私有化
*/
public AnimalDao(Context context) {
DBOpenHelper dbHelper=new DBOpenHelper(context);
db=dbHelper.openDatabase();
}
/**
* 获取AnimalDao实例
*/
public synchronized static AnimalDao getInstance(Context context){
if(animalDao==null){
animalDao=new AnimalDao(context);
}
return animalDao;
}
/**
* 从数据库读取所有的动物类成语
*/
public static List<Animal> getAllAnimals(){
List<Animal> list=new ArrayList<Animal>();
Cursor cursor=db.query("animal", null, null, null, null,null,null);
if(cursor.moveToFirst()){
do{
Animal animal=new Animal();
animal.setId(cursor.getInt(cursor.getColumnIndex("_id")));
animal.setName(cursor.getString(cursor.getColumnIndex("name")));
animal.setPronounce(cursor.getString(cursor.getColumnIndex("pronounce")));
animal.setAntonym(cursor.getString(cursor.getColumnIndex("antonym")));
animal.setHomoionym(cursor.getString(cursor.getColumnIndex("homoionym")));
animal.setDerivation(cursor.getString(cursor.getColumnIndex("derivation")));
animal.setExamples(cursor.getString(cursor.getColumnIndex("examples")));
list.add(animal);
}while(cursor.moveToNext());
}
return list;
}
}
下面进行单元测试
在test测试类下加入
public void testGetAllAnimals(){
AnimalDao animalDao=AnimalDao.getInstance(getContext());
List<Animal> animals=animalDao.getAllAnimals();
System.out.println(animals.size());
for(Animal animal:animals){
System.out.println(animal.getName());
}
测试如下
测试成功后,实现功能
UI界面
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="@drawable/bg_animal" >
<TabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<LinearLayout
android:id="@+id/tab2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="@+id/tab3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
</FrameLayout>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TabWidget>
</LinearLayout>
</TabHost>
</RelativeLayout>
一. TabHost介绍
TabHost组件可以在界面中存放多个选项卡, 很多软件都使用了改组件进行设计;
1. TabHost常用组件
TabWidget : 该组件就是TabHost标签页中上部 或者 下部的按钮, 可以点击按钮切换选项卡;
TabSpec : 代表了选项卡界面, 添加一个TabSpec即可添加到TabHost中;
-- 创建选项卡 : newTabSpec(String tag), 创建一个选项卡;
-- 添加选项卡 : addTab(tabSpec);
TabHost的使用请看 http://blog.csdn.net/harvic880925/article/details/17120325/
然后在res的values目录的string.xml文件中定义
<string-array name="category">
<item>动物类</item>
<item>自然类</item>
<item>人物类</item>
<item>季节类</item>
<item>数字类</item>
<item>寓言类</item>
<item>其他类</item>
</string-array>
接下来cn.deu.bztc.happyidiom.activity中建立MainActivity.java
package cn.deu.bztc.happyidiom.activity;
import android.os.Bundle;
import android.app.Activity;
import android.app.TabActivity;
import android.content.Intent;
import android.view.Menu;
import android.view.Window;
import android.widget.TabHost;
public class MainActivity extends TabActivity {
private TabHost tabHost;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//取消标题栏
setContentView(R.layout.activity_main);
tabHost=getTabHost();
addTab("study", R.string.title_study, R.drawable.study,StudyActivity.class);
addTab("search", R.string.title_search, R.drawable.search, StudyActivity.class);
addTab("study", R.string.title_game, R.drawable.game, StudyActivity.class);
addTab("save", R.string.title_save, R.drawable.save, StudyActivity.class);
addTab("help", R.string.title_help, R.drawable.search, StudyActivity.class);
}
private void addTab(String tag,int title_introduction,int title_icon,Class ActivityClass){
tabHost.addTab(tabHost.newTabSpec(tag)
.setIndicator(getString(title_introduction),
getResources().getDrawable(title_icon)).setContent(new Intent(this,ActivityClass)));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
在这个类里调用TabHost组件, 然后调用了抽取出来的自定义的方法addTob()添加了五个选项卡,方法的四个参数分别为每个选项卡的tag,指示器上显示的标题。,指示器上显示的图片,选项卡对应的内容。
注意取消标题,一定位于setContCiew()方法之前
下面我就不一一介绍了,我会把源码地址分享给大家。
总结一下中间出现的错误吧
1.如果大家在非黑色背景下使用ListView控件时,Android默认可能在滚动ListView时这个列表控件的背景突然变成黑色。这样可能导致程序的黑色的背景和主程序的主题既不协调
我一开始是在AndroidManifest.xml中使用
android:theme="@android:style/Theme.NoTitleBar"
之后仔细查了查意思是:背景主题的没有标题栏的样式,默认如果没有设置的话,显示黑背景