一.功能需求及技术可行性分析
在开始编码之前,需要先对程序进行需求分析,思考项目应该具备哪些功能
1.成语分类学习:用户可根据自己喜欢的分类(动物类,人物类,季节类,自然类,数字类,寓言类,其他类)来进行选择性学习。
2.成语查询:用户可联网来获取网络释义。
分析完功能需求后,接下来进行技术可行性分析,考虑字库来源问题,以及如何获得每个成语的读音,解释,近义词,反义词等信息。
数据提供如下:https://www.juhe.cn/docs/api/id/157
在线成语如下:http://cy.5156edu.com/
二.主要实现的功能
基础功能:文档中示范的基础功能全部完成
1.使用TabHost进行标签显示主页
2.使用listview显示学习列表
3.显示本地数据库中的成语学习资料
扩展功能:
1.添加滑动欢迎页面(扩展功能)
2.添加网络释义(扩展功能)
三.主要功能实现代码解析
1.建立数据库文件,加载数据库到项目中,在res目录下建立一个raw文件夹,
新建DBOpenHelper实现将数据库文件从raw目录拷贝到手机里存放数据库的位置
public class DBOpenHelper {
private final int BuFFWER_SIZE=400000;//缓冲区大小
public static final String DB_NAME="idioms.db";//保存的数据库文件名
public static final StringPACKAGE_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())){
//判断数据库文件是否存在,若不存在则执行导入,否则直接打开数据库
InputStreamis=context.getResources().openRawResource(R.raw.idioms);
FileOutputStream fos=newFileOutputStream(dbfile);
byte[] buffer=newbyte[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;
}
}
2.org.gerrysu.happyidiom.entity建立实体类
3.在org.gerrysu.happyidiom.Dao下建立操作类AnimalDao,完成对数据库的创建。
4.可进行单元测试测试数据库是否导入成功
5.编写activity_main.xml
,定义TabHost
6.建立MainActivity,使用TabHost组件,在这个onCreate方法中,通过调用getTabHost()方法来获取整个TabHost组件
public class MainActivity extendsTabActivity{
privateTabHost tabHost;
protectedvoid 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("study",R.string.title_search,R.drawable.search,StudyActivity.class); addTab("study",R.string.title_game,R.drawable.game,StudyActivity.class);
addTab("study",R.string.title_save,R.drawable.save,StudyActivity.class);
addTab("study",R.string.title_help,R.drawable.help,StudyActivity.class);
}
privatevoid addTab(String tag, int title_introduction,int title_icon, ClassActivityClass) {
//TODO Auto-generated method stub
tabHost.addTab(tabHost.newTabSpec(tag)
.setIndicator(getString(title_introduction),
getResources().getDrawable(title_icon))
.setContent(newIntent(this,ActivityClass)));}
7.在AndroidManifest下注册MainActivity,此时可运行程序查看效果
8.对LisyView进行定制,显示学习列表
修改Values下的strings,定义列表的文字内容,新建Category实体类,用来封装列表中的文字和图片。新建activity_study.xml,定义一个ListView控件,然后为ListView自定义一个布局文件category_item.xml。
9.新建CategoryAdapter创建自定义适配器,继承自ArrayAdapter
通过getItem()方法得到当前项的Category的实例,然后使用LayoutInflater来为这个子项加载传入的布局。
public class CategoryAdapter extendsArrayAdapter<Category>{
privateint resourceId;
publicCategoryAdapter(Context context, int resource,List<Category>objects) {
super(context,resource,objects);
resourceId = resource;
//TODO Auto-generated constructor stub
}
publicView getView(int position,View convertView,ViewGroup parent){
Categorycategory = getItem(position);//获取当前项的Category实例
Viewview;
ViewHolderviewHolder;
if(convertView== null){
view= LayoutInflater.from(getContext()).inflate(resourceId, null);
viewHolder= new ViewHolder();
viewHolder.categoryImage= (ImageView)view.findViewById(R.id.category_image);
viewHolder.categoryName= (TextView)view.findViewById(R.id.category_name);
view.setTag(viewHolder);//将ViewHolder存储在View中
}else{
view= convertView;
viewHolder= (ViewHolder)view.getTag();//重新拾取ViewHolder
}
viewHolder.categoryImage.setImageResource(category.getImageId());
viewHolder.categoryName.setText(category.getName());
returnview;
}
classViewHolder{
ImageViewcategoryImage;
TextViewcategoryName;
}
}
10.下面新建study活动
添加一个initCategories方法,用于初始化所有类别的数据
使用setOnItemClickListener()方法来为ListView注册监听器,当用户点击就会回调onItemClick()方法,在这个方法中可以通过position参数判断出用户点击的是哪一子项,然后获取到相应的类别,并通过Toast将类别的名字显示出来。
/* 定制ListView页面
*/
public class StudyActivity extendsActivity{
privateList<Category> categoryList;
privateString[] category_names;
privateint[] category_images;
protectedvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_study);
initCategories();//初始化类别
CategoryAdapteradapter =new CategoryAdapter(this, R.layout.category_item, categoryList);
ListViewlistView = (ListView)findViewById(R.id.ivCategories);
listView.setAdapter(adapter);
listView.setOnItemClickListener(newOnItemClickListener() {
@Override
publicvoid onItemClick(AdapterView<?> adapterView, View view, int posotion,
longid) {
switch(posotion) {
case0:
Intentintent = new
Intent(StudyActivity.this,StudyAnimalActivity.class);
startActivity(intent);
break;
default:
break;
}
}
});
}
privatevoid initCategories() {
//TODO Auto-generated method stub
categoryList= new ArrayList<Category>();
Resourcesresoures = getResources();
category_names= resoures.getStringArray(R.array.category);
category_images=new int[]{R.drawable.category_animal,
R.drawable.category_nature,R.drawable.category_human,
R.drawable.category_season,R.drawable.category_number,
R.drawable.category_fable,R.drawable.category_other};
for(int i=0; i<category_names.length;i++){
categoryList.add(new Category(category_names[i],category_images[i]));
}
}
}
11.去掉点击出现的橙色的背景色,在activity_study.xml中添加代码:android:listSelevtor=”#00000000”
12.增加界面淡入淡出的动画效果。在res目录下新建anim目录, 新建anim_listview.xml设置动画效果,再在study_activity.xml中引用
<?xml version="1.0"encoding="utf-8"?>
<alphaxmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromAlpha="0.0"
android:toAlpha="1.0"></alpha>
13.将学习界面与之前建立的主界面连起来,再通过intent将选项卡和studyactivity关联起来。
private void addTab(String tag, inttitle_introduction,int title_icon, Class ActivityClass) {
//TODO Auto-generated method stub
tabHost.addTab(tabHost.newTabSpec(tag)
.setIndicator(getString(title_introduction),
getResources().getDrawable(title_icon))
.setContent(newIntent(this,ActivityClass)));
}
14.显示所有动物类成语的列表
在layout下新建activity_animal.xml,主要添加一个ListView控件,然后为ListView的子项指定自定义布局animal_item.xml
15.新建AnimalAdater 并将泛型指向Animal类,实现过程与CategoryAdapter类似。
16显示每条成语的详情信息,新建dialog_info.xml,修改StudyAnimalActivity,增加点击事件处理
17,修改图标名字,打包完成。
四.扩展功能
1.增加滑动欢迎界面
新建AndyViewPagerActivity,使用ViewPager控件实现
2.扩展功能,网络释义
新建activity_search.xml,定义一个WebView,然后新建SearchActivity
public void searchWord(View view) {
Stringword = etWord.getText().toString();
if(TextUtils.isEmpty(word)) {
Toast.makeText(this,"查询内容不能为空!", Toast.LENGTH_LONG).show();
}else {
finalString strUrl =
"http://dict.baidu.com/s?wd="+word+"&ptype=idiom";
wvResult.loadUrl(strUrl);
}
}
五.参考文献
1. Android综合项目乐学成语
2.Android移动开发项目式教程
六附上源代码
链接:https://pan.baidu.com/s/1qZzyojU 密码:mhhh