传送门: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帮我做更好看的界面了:
好了这一篇就说这么多吧,应该还会有一些新的有意思的功能要尝试,所以应该还会有后续吧!
么么哒,喜欢就点赞吧!!!