Android+Sqlite 实现古诗阅读应用(二)
传送门:Android+Sqlite 实现古诗阅读应用(一)
Hi,又回来了,最近接到很多热情洋溢的小伙伴们的来信,吼开心哈,我会继续努力的=-=!
上回的东西我们做到了有个textview能随机选择诗来进行显示,这也是我做这个东西的初衷,我想找我到底有哪些古诗没有读过,更想感受一下风吹哪页看哪页的闲适(扯远了=-=!),所以功能现在差不多算是结束了,
不过一个古诗应用这么丑可不行,还有就是,我找到了我要的诗我也得能收藏啊,要是下次忘了可怎么办啊,所以这里面还有一些知识点,我们能从接下来的功能中学到:
1.再做一个启动界面:
打开数据库,随着数据库的增大会有一点卡顿,我们加个界面来过渡缓解一下:
package com.lfk.poem;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation; /**
* Created by Administrator on 2015/4/11.
*/
public class Opening extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final View view = View.inflate(this, R.layout.activity_opening, null);
setContentView(view);
//渐变展示启动屏
AlphaAnimation start = new AlphaAnimation(0.3f,1.0f);
start.setDuration();
view.startAnimation(start);
start.setAnimationListener(new Animation.AnimationListener()
{
@Override
public void onAnimationEnd(Animation arg0) {
Log.e("linc", "---start!");
try{
Intent intent = new Intent();
intent.setClass(Opening.this,MainActivity.class);
Opening.this.startActivity(intent);
Opening.this.finish();
}
catch(Exception e)
{
e.printStackTrace();
}
}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationStart(Animation animation) {}
}); }
}
这是做过的样子:

2.修改Actionbar为透明的叠加模式:
这个我在之前的博客里已经写过了,可以参考一下即时通讯的第五篇:http://www.cnblogs.com/lfk-dsk/p/4419418.html3.数据库的导入:
上次为了测试我们只导入了5首古诗作为测试,这回用正则表达式调整了格式,导入了唐诗三百首。

将txt做成了这种格式,然后倒入数据库管理软件。

数据库里的格式就是这样的了,然后替换数据库就好了,想要现成的可找我要。
4.背景和刷新:
自然不用说添加自己喜欢的古风背景就好。
刷新我不用Button了,改用google的下拉刷新,我在这个博文里写过:http://www.cnblogs.com/lfk-dsk/p/4433319.html
每次刷新一下就会重新找一首诗。
5.主活动的修改
package com.lfk.poem; import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream; public class MainActivity extends Activity {
private final int BUFFER_SIZE = 400000;
public static final String DB_NAME = "poem_all.db"; //保存的数据库文件名
public static final String DB_USER_NAME = "poem_user.db";
public static final String PACKAGE_NAME = "com.lfk.poem";// 应用的包名
public static final String DB_PATH = "/data"
+ Environment.getDataDirectory().getAbsolutePath() +"/"
+ PACKAGE_NAME+ "/databases"; // 在手机里存放数据库的位置
private SwipeRefreshLayout swipeLayout;
private RelativeLayout main_layout;
private TextView textView;
private static int ID = 0;
private String NAME;
private String POEM;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Typeface typeface = Typeface.createFromAsset(getAssets(),"fonts/font_ksj.ttf");
textView = (TextView)findViewById(R.id.text_view);
textView.setTypeface(typeface); main_layout = (RelativeLayout)findViewById(R.id.main_layout);
ChangeBackground();
FindaPoem();
swipeLayout = (SwipeRefreshLayout) this.findViewById(R.id.swipe_refresh);
swipeLayout.setColorScheme(R.color.haah);
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {//延迟跳转=-=
public void run() {
swipeLayout.setRefreshing(true);
FindaPoem();
swipeLayout.setRefreshing(false);
}
}, 500);
}
});
}
private void FindaPoem() {
int ll = (int) (1 + Math.random() * (59170));
ID = ll;
SQLiteDatabase database = openDatabase();
Cursor cursor = database.rawQuery("Select * From poem Where _id = " + ll, null);
cursor.moveToFirst();
String poem = cursor.getString(1)+"\n"+"\n"+cursor.getString(2)+"\n"+"\n"+cursor.getString(13);
NAME = cursor.getString(2)+": "+cursor.getString(1);
POEM = cursor.getString(13);
Log.e(poem, "================");
textView.setText(poem);
cursor.close();
database.close();
}
private void ChangeBackground(){
int ln = (int) (1 + Math.random() * (5));
switch (ln){
case 1:
main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.detail_bg));
break;
case 2:
main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_1));
break;
case 3:
main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_2));
break;
case 4:
main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_3));
break;
case 5:
main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_4));
break;
}
}
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;
is = this.getResources().openRawResource(R.raw.poem_all); // 欲导入的数据库
FileOutputStream fos = new FileOutputStream(dbfile);
byte[] buffer = new byte[BUFFER_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);
Log.e("=======================","get it ======================");
return db;
} catch (FileNotFoundException e) {
Log.e("Database", "File not found");
e.printStackTrace();
} catch (IOException e) {
Log.e("Database", "IO exception");
e.printStackTrace();
}
return null;
}
void AddaPoemToCollect(){
File myDataPath = new File(DB_PATH);
String dbfile = myDataPath+"/"+DB_USER_NAME;
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
//ContentValues contentValues = new ContentValues();
db.execSQL("UPDATE poem SET ticai = 1 WHERE _id ="+ID);
//db.insert("book", null, contentValues);
db.close();
Toast.makeText(getApplicationContext(),
"Collect succeed",
Toast.LENGTH_SHORT).show();
//ID++;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch(id){
case R.id.collect:
Intent intent = new Intent(this,Collect.class);
startActivity(intent);
break;
case R.id.like:
AddaPoemToCollect();
break;
} return super.onOptionsItemSelected(item);
}
}
这是修改过的主活动。
1.首先更换了字体放在assets文件夹内,在res里面,没有的请新建。
Typeface typeface = Typeface.createFromAsset(getAssets(),"fonts/font_ksj.ttf");
textView = (TextView)findViewById(R.id.text_view);
textView.setTypeface(typeface);
获取了字体资源,注册了一个textview,把字体设置为textview。

这是修改过的效果,纤细的字体很适合我们的古诗!
2.
private void ChangeBackground(){
int ln = (int) (1 + Math.random() * (5));
switch (ln){
case 1:
main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.detail_bg));
break;
case 2:
main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_1));
break;
case 3:
main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_2));
break;
case 4:
main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_3));
break;
case 5:
main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_4));
break;
}
}
添加了一个修改背景的函数,每次进入会随机选择背景,这样我们每次进入就有可能看到不一样的背景了。
3.
private void FindaPoem() {
int ll = (int) (1 + Math.random() * (59170));
ID = ll;
SQLiteDatabase database = openDatabase();
Cursor cursor = database.rawQuery("Select * From poem Where _id = " + ll, null);
cursor.moveToFirst();
String poem = cursor.getString(1)+"\n"+"\n"+cursor.getString(2)+"\n"+"\n"+cursor.getString(13);
NAME = cursor.getString(2)+": "+cursor.getString(1);
POEM = cursor.getString(13);
Log.e(poem, "================");
textView.setText(poem);
cursor.close();
database.close();
}
从数据库里随即一个数(我数据库里有59170首诗,=-=!)然后打开数据库,找到ID为此项的诗,然后获取诗的内容,getString的号码要按照你自己的数据库需要选择不同的栏位,
比如0位就是ID的栏位,我这里面作者古诗名和古诗内容是分开存放的,而且加入了不少我要用的数据,所以栏位增加到了13个之多,自己做的话只需要三个栏位就好,一个id,一个古诗内容,
一个收藏标记位(用0和1来标记)
所以我对dbhelper的数据库生成类进行了一些修改:
package com.lfk.poem; import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast; /**
* Created by Administrator on 2015/5/8.
*/
public class DBhelper extends SQLiteOpenHelper {
private static final String CREAT_DB = "create table book ("
+ "id integer primary key autoincrement,"
+ "collect int,"
+ "poem text)";
private Context mcontext; public DBhelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mcontext = context;
} @Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREAT_DB);
Toast.makeText(mcontext,"succeed collect!",Toast.LENGTH_SHORT).show();
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
这样生成的数据库就能成功的应用收藏功能了,上一步所说的修改数据库也就能实现了。
6.收藏功能的实现:
我在写这篇博文之前曾经写过两次关于收藏的内容,第一次的方法比较蠢,我又开了一个用户的数据库,然后把要收藏的东西复制进用户数据库中,不过这种方法比较麻烦,
首先是开两个数据库增加了系统的无谓开销,增加了对系统资源的消耗,而且在传入新的数据库中,id会发生变化,写入和传值会非常的不便利,所以我放弃了那种方法,改用
在数据库设置标志栏位的方法来解决问题。
package com.lfk.poem; import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast; import java.io.File; public class Collect extends Activity {
private DBhelper dBhelper;
private ListView listView;
public static ArrayAdapter<String> mArrayAdapter;
public static final String DB_NAME = "poem_all.db"; //保存的数据库文件名
public static final String PACKAGE_NAME = "com.lfk.poem";// 应用的包名
public static final String DB_PATH = "/data"
+ Environment.getDataDirectory().getAbsolutePath() +"/"
+ PACKAGE_NAME+ "/databases"; // 在手机里存放数据库的位置
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_collect);
String[] data = new String[0];
//dBhelper = new DBhelper(this,"poem_all.db",null,1);
listView = (ListView)findViewById(R.id.list_view);
mArrayAdapter = new ArrayAdapter<String>(this,R.layout.list_item);
listView.setAdapter(mArrayAdapter);
FindyourCollect();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
System.out.println(arg2);
String temp = (String)((TextView)arg1).getText();
Intent intent = new Intent();
intent.putExtra("title",temp);
System.out.println(arg2);
intent.setClass(Collect.this, Collect_item.class);
startActivity(intent);
Toast.makeText(getApplicationContext(),
"Opening " + arg2,
Toast.LENGTH_SHORT).show();
mArrayAdapter.notifyDataSetChanged();
}
});
} // @Override
// public boolean onCreateOptionsMenu(Menu menu) {
// // Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.menu_collect, menu);
// return true;
// }
//
// @Override
// public boolean onOptionsItemSelected(MenuItem item) {
// // Handle action bar item clicks here. The action bar will
// // automatically handle clicks on the Home/Up button, so long
// // as you specify a parent activity in AndroidManifest.xml.
// int id = item.getItemId();
//
// //noinspection SimplifiableIfStatement
// if (id == R.id.action_settings) {
// return true;
// }
//
// return super.onOptionsItemSelected(item);
// }
void FindyourCollect(){
File myDataPath = new File(DB_PATH);
String dbfile = myDataPath+"/"+DB_NAME;
SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
Cursor cursor = database.rawQuery("Select * From poem where ticai = 1", null);
Log.e("===================", "================");
if(cursor.moveToFirst()) {
Log.e("===================", "================");
do {
String title = cursor.getString(cursor.getColumnIndex("mingcheng"));
mArrayAdapter.add(title);
Log.e(title, "================");
}while (cursor.moveToNext());
}
cursor.close();
database.close();
}
@Override
protected void onRestart(){
super.onRestart();
mArrayAdapter.clear();
FindyourCollect();
mArrayAdapter.notifyDataSetChanged();
}
}
这是Collect的活动的代码,代码中用了一个系统自带的简易的listview(主要是也不需要太多的功能),进入之后运行FindyourCollect()方法用Select * From poem where ticai = 1语法,
寻找标志位,然后把所有找到的东西加入listview中去,然后设置item的响应打开。
package com.lfk.poem; import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast; public class Collect_item extends Activity {
private DBhelper dBhelper;
private String ID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_collect_item);
Intent intent = getIntent();
String title = intent.getStringExtra("title");
//System.out.println(id+"=================");
TextView textView = (TextView)findViewById(R.id.poem_item);
Typeface typeface = Typeface.createFromAsset(getAssets(),"fonts/font_ksj.ttf");
textView.setTypeface(typeface);
dBhelper = new DBhelper(this,"poem_all.db",null,1);
SQLiteDatabase database = dBhelper.getWritableDatabase();
Cursor cursor = database.rawQuery("Select * From poem where mingcheng="+"\""+title+"\"", null);
cursor.moveToFirst();
ID = cursor.getString(cursor.getColumnIndex("_id"));
String poem = cursor.getString(1)+"\n"+"\n"+cursor.getString(2)+"\n"+"\n"+cursor.getString(13);
textView.setText(poem);
Log.e("===================", "================");
cursor.close();
database.close();
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_collect_item, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId(); if(id == R.id.dislike_collect){
SQLiteDatabase db = dBhelper.getWritableDatabase();
db.execSQL("UPDATE poem SET ticai = 0 WHERE _id ="+ID);
db.close();
Toast.makeText(getApplicationContext(),
"Collect Delete",
Toast.LENGTH_SHORT).show();
} return super.onOptionsItemSelected(item);
} }
打开后的方法比较简单和主活动基本一样,接受传入的题目,然后根据题目找到我们需要的诗,设置字体然后textview中显示出来。
然后就是加入收藏了,为了方便,我把加入收藏写进了meau中以方便使用:
void AddaPoemToCollect(){
//File myDataPath = new File(DB_PATH);
//String dbfile = myDataPath+"/"+DB_USER_NAME;
SQLiteDatabase db = openDatabase();
//ContentValues contentValues = new ContentValues();
db.execSQL("UPDATE poem SET ticai = 1 WHERE _id ="+ID);
//db.insert("book", null, contentValues);
db.close();
Toast.makeText(getApplicationContext(),
"Collect succeed",
Toast.LENGTH_SHORT).show();
//ID++;
}
void deleteAPoemFromCollect(){
SQLiteDatabase db = openDatabase();
db.execSQL("UPDATE poem SET ticai = 0 WHERE _id ="+ID);
db.close();
Toast.makeText(getApplicationContext(),
"Collect Delete",
Toast.LENGTH_SHORT).show();
}
这个就是加入收藏和删除收藏的方法所在了,我在主活动和收藏的内容活动中都为meau添加了这个方法,并且设置了一个全局变量ID用于删除和加入收藏的时候寻址。
到此为止我们初期的功能就都开发完了,放出新的界面,图片还是暂时借用了别人的成例,我已经找UI帮我做更好看的界面了:




好了这一篇就说这么多吧,应该还会有一些新的有意思的功能要尝试,所以应该还会有后续吧!
么么哒,喜欢就点赞吧!!!
Android+Sqlite 实现古诗阅读应用(二)的更多相关文章
- Android+Sqlite 实现古诗阅读应用(三)
往期传送门: Android+Sqlite 实现古诗阅读应用(一) Android+Sqlite 实现古诗阅读应用(二) 加入截图分享的功能. 很多应用都有分享的功能,我也想在我的古诗App里加入这个 ...
- Android+Sqlite 实现古诗阅读应用(一)
不说网络app,很多本地的app都有一些随机的内容推送,比如随机推送一些小知识,古诗,名言名画什么的,界面制作的好看一点就能看起来特别的文艺范, 最近就是看了这样的一些应用,就想自己实现一下,这种方法 ...
- 《阿里巴巴Android编码规范》阅读纪要(二)
版权声明:本文出自汪磊的博客,转载请务必注明出处. 本篇继续上一篇<阿里巴巴Android编码规范>阅读纪要(一) ,还是建议各位同学有时间完整阅读一下<阿里巴巴Android编码规 ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- Android SQLite总结(一) (转)
Android SQLite总结(一) 郑海波 2012-08-21 转载请声明:http://blog.csdn.net/nuptboyzhb/article/details/7891887 前言 ...
- Android SQLite 数据库详细介绍
Android SQLite 数据库详细介绍 我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用 ...
- Android SQLite 数据库 增删改查操作
Android SQLite 数据库 增删改查操作 转载▼ 一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NU ...
- Android系统--输入系统(十二)Dispatch线程_总体框架
Android系统--输入系统(十二)Dispatch线程_总体框架 1. Dispatch线程框架 我们知道Dispatch线程是分发之意,那么便可以引入两个问题:1. 发什么;2. 发给谁.这两个 ...
- 再读Android sqlite
再读Android sqlite Android原生支持sqlite数据库操作,sqlite时轻量级关系型数据库,支持标准sql语句.Android对sqlite进行良好的接口封装来避免sql注入等安 ...
随机推荐
- WPF如何实现一个漂亮的页签导航UI
最近看到一个比较漂亮的UI主界面,该UI是用左边的页签进行导航,比较有特色,就想着尝试用WPF来实现一下.经过一番尝试,基本上将UI设计图的效果用WPF程序进行了实现.下面介绍一下主要的思路: 1 U ...
- 基于 jQuery 实现垂直滑动的手风琴效果
今天我们要与大家分享一个漂亮而灵活的垂直 jQuery 手风琴效果.其主要思想是扩大手风琴片上的点击和显示更多的信息.其他内容片段将变得不那么透明.当使用一个导航箭头导航下一个片段,新的片会从顶部或底 ...
- jQ函数after、append、appendTo的区别
1.after函数定义和用法:after() 方法在被选元素后插入指定的内容.参考:http://keleyi.com/a/bjac/cfyxd60g.htm 语法:$(selector).after ...
- CSS3里的display
默认值:inline 适用于:所有元素 继承性:无 动画性:否 none: 隐藏对象.与visibility属性的hidden值不同,其不为被隐藏的对象保留其物理空间 inline: 指定对象为内联元 ...
- 谈谈JavaScript类型检测
javascript内置的类型检测机制并非完全可靠.比如typeof操作符,并不能准确的判断数据是哪个类型,比如:数组和对象就不能通过typeof来区分. typeof [] ==="o ...
- xmpp整理笔记:环境的快速配置(附安装包)
现在虽然环信的xmpp框架很火,但是也有一些弊端.环信的框架部分代码不开源,而且收费模式不科学,用户量一直低于免费线则好,一旦超过,收费极高. xmpp感觉还是从xmppFramework框架学起比较 ...
- 将Android系统源码导入ecplise
Android系统源码中带有个IDE的配置文件,目录为:development/ide/ 如果要用eclipse导入查看系统源码,则将development/ide/eclipse/.classpat ...
- swift 2.2 语法 (下)
前言: 1.此文中的语法会根据Swift的升级变动而更新. 2.如果需要请移步 -> swift2.2 语法(上).swift 2.2语法(中) 类的析构函数 swift会自动释放不需要的实例来 ...
- iOS 被拒问题及原因 - IDFA问题
IDFA问题 iOS APP上线被拒绝的问题解决(AdSupport),百度统计,友盟统计,讯飞语音等 苹果反馈信息如下: .... To process your delivery, the f ...
- 你真的了解UIApplication吗?
一:首先查看一下关于UIApplication的定义 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIApplication : UIResponder //获得单例 ...