你的位置:首页 > 操作系统

[操作系统]Android+Sqlite 实现古诗阅读应用(二)


  传送门:Android+Sqlite 实现古诗阅读应用(一):http://www.cnblogs.com/lfk-dsk/p/4492974.html

  Hi,又回来了,最近接到很多热情洋溢的小伙伴们的来信,吼开心哈,我会继续努力的=-=!

  上回的东西我们做到了有个textview能随机选择诗来进行显示,这也是我做这个东西的初衷,我想找我到底有哪些古诗没有读过,更想感受一下风吹哪页看哪页的闲适(扯远了=-=!),所以功能现在差不多算是结束了,

不过一个古诗应用这么丑可不行,还有就是,我找到了我要的诗我也得能收藏啊,要是下次忘了可怎么办啊,所以这里面还有一些知识点,我们能从接下来的功能中学到:

1.再做一个启动界面:

  打开数据库,随着数据库的增大会有一点卡顿,我们加个界面来过渡缓解一下:

 1 package com.lfk.poem; 2 import android.app.Activity; 3 import android.content.Intent; 4 import android.os.Bundle; 5 import android.util.Log; 6 import android.view.View; 7 import android.view.animation.AlphaAnimation; 8 import android.view.animation.Animation; 9 10 /**11  * Created by Administrator on 2015/4/11.12 */13 public class Opening extends Activity {14   @Override15   public void onCreate(Bundle savedInstanceState) {16     super.onCreate(savedInstanceState);17     final View view = View.inflate(this, R.layout.activity_opening, null);18     setContentView(view);19     //渐变展示启动屏20     AlphaAnimation start = new AlphaAnimation(0.3f,1.0f);21     start.setDuration(2000);22     view.startAnimation(start);23     start.setAnimationListener(new Animation.AnimationListener()24     {25       @Override26       public void onAnimationEnd(Animation arg0) {27         Log.e("linc", "---start!");28         try{29           Intent intent = new Intent();30           intent.setClass(Opening.this,MainActivity.class);31           Opening.this.startActivity(intent);32           Opening.this.finish();33         }34         catch(Exception e)35         {36           e.printStackTrace();37         }38       }39       @Override40       public void onAnimationRepeat(Animation animation) {}41       @Override42       public void onAnimationStart(Animation animation) {}43     });44 45 46   }47 }

 

这是做过的样子:

    

2.修改Actionbar为透明的叠加模式:

  这个我在之前的博客里已经写过了,可以参考一下即时通讯的第五篇:http://www.cnblogs.com/lfk-dsk/p/4419418.html

3.数据库的导入:

  上次为了测试我们只导入了5首古诗作为测试,这回用正则表达式调整了格式,导入了唐诗三百首。

  

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

  

数据库里的格式就是这样的了,然后替换数据库就好了,想要现成的可找我要。

4.背景和刷新:

  自然不用说添加自己喜欢的古风背景就好。

  刷新我不用Button了,改用google的下拉刷新,我在这个博文里写过:http://www.cnblogs.com/lfk-dsk/p/4433319.html

  每次刷新一下就会重新找一首诗。

5.主活动的修改

 1 package com.lfk.poem; 2  3 import android.app.Activity; 4 import android.content.Intent; 5 import android.database.Cursor; 6 import android.database.sqlite.SQLiteDatabase; 7 import android.graphics.Typeface; 8 import android.os.Bundle; 9 import android.os.Environment; 10 import android.os.Handler; 11 import android.support.v4.widget.SwipeRefreshLayout; 12 import android.util.Log; 13 import android.view.Menu; 14 import android.view.MenuInflater; 15 import android.view.MenuItem; 16 import android.widget.RelativeLayout; 17 import android.widget.TextView; 18 import android.widget.Toast; 19  20 import java.io.File; 21 import java.io.FileNotFoundException; 22 import java.io.FileOutputStream; 23 import java.io.IOException; 24 import java.io.InputStream; 25  26  27 public class MainActivity extends Activity { 28   private final int BUFFER_SIZE = 400000; 29   public static final String DB_NAME = "poem_all.db"; //保存的数据库文件名 30   public static final String DB_USER_NAME = "poem_user.db"; 31   public static final String PACKAGE_NAME = "com.lfk.poem";// 应用的包名 32   public static final String DB_PATH = "/data" 33       + Environment.getDataDirectory().getAbsolutePath() +"/" 34       + PACKAGE_NAME+ "/databases"; // 在手机里存放数据库的位置 35   private SwipeRefreshLayout swipeLayout; 36   private RelativeLayout main_layout; 37   private TextView textView; 38   private static int ID = 0; 39   private String NAME; 40   private String POEM; 41   @Override 42   protected void onCreate(Bundle savedInstanceState) { 43     super.onCreate(savedInstanceState); 44     setContentView(R.layout.activity_main); 45  46     Typeface typeface = Typeface.createFromAsset(getAssets(),"fonts/font_ksj.ttf"); 47     textView = (TextView)findViewById(R.id.text_view); 48     textView.setTypeface(typeface); 49  50     main_layout = (RelativeLayout)findViewById(R.id.main_layout); 51     ChangeBackground(); 52     FindaPoem(); 53     swipeLayout = (SwipeRefreshLayout) this.findViewById(R.id.swipe_refresh); 54     swipeLayout.setColorScheme(R.color.haah); 55     swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 56       @Override 57       public void onRefresh() { 58         new Handler().postDelayed(new Runnable() {//延迟跳转=-= 59           public void run() { 60             swipeLayout.setRefreshing(true); 61             FindaPoem(); 62             swipeLayout.setRefreshing(false); 63           } 64         }, 500); 65       } 66     }); 67   } 68   private void FindaPoem() { 69     int ll = (int) (1 + Math.random() * (59170)); 70     ID = ll; 71     SQLiteDatabase database = openDatabase(); 72     Cursor cursor = database.rawQuery("Select * From poem Where _id = " + ll, null); 73     cursor.moveToFirst(); 74     String poem = cursor.getString(1)+"\n"+"\n"+cursor.getString(2)+"\n"+"\n"+cursor.getString(13); 75     NAME = cursor.getString(2)+": "+cursor.getString(1); 76     POEM = cursor.getString(13); 77     Log.e(poem, "================"); 78     textView.setText(poem); 79     cursor.close(); 80     database.close(); 81   } 82   private void ChangeBackground(){ 83     int ln = (int) (1 + Math.random() * (5)); 84     switch (ln){ 85       case 1: 86         main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.detail_bg)); 87         break; 88       case 2: 89         main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_1)); 90         break; 91       case 3: 92         main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_2)); 93         break; 94       case 4: 95         main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_3)); 96         break; 97       case 5: 98         main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_4)); 99         break;100     }101   }102   public SQLiteDatabase openDatabase() {103     try {104       File myDataPath = new File(DB_PATH);105       if (!myDataPath.exists())106       {107         myDataPath.mkdirs();// 如果没有这个目录,则创建108       }109       String dbfile = myDataPath+"/"+DB_NAME;110       if (!(new File(dbfile).exists())) {// 判断数据库文件是否存在,若不存在则执行导入,否则直接打开数据库111         InputStream is;112         is = this.getResources().openRawResource(R.raw.poem_all); // 欲导入的数据库113         FileOutputStream fos = new FileOutputStream(dbfile);114         byte[] buffer = new byte[BUFFER_SIZE];115         int count = 0 ;116         while ((count = is.read(buffer)) > 0) {117             fos.write(buffer, 0, count);118         }119         fos.close();120         is.close();121       }122       SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);123       Log.e("=======================","get it ======================");124       return db;125     } catch (FileNotFoundException e) {126       Log.e("Database", "File not found");127       e.printStackTrace();128     } catch (IOException e) {129       Log.e("Database", "IO exception");130       e.printStackTrace();131     }132     return null;133   }134   void AddaPoemToCollect(){135     File myDataPath = new File(DB_PATH);136     String dbfile = myDataPath+"/"+DB_USER_NAME;137     SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);138     //ContentValues contentValues = new ContentValues();139     db.execSQL("UPDATE poem SET ticai = 1 WHERE _id ="+ID);140     //db.insert("book", null, contentValues);141     db.close();142     Toast.makeText(getApplicationContext(),143         "Collect succeed",144         Toast.LENGTH_SHORT).show();145     //ID++;146   }147   @Override148   public boolean onCreateOptionsMenu(Menu menu) {149     // Inflate the menu; this adds items to the action bar if it is present.150     MenuInflater inflater = getMenuInflater();151     inflater.inflate(R.menu.menu_main, menu);152     return super.onCreateOptionsMenu(menu);153   }154 155   @Override156   public boolean onOptionsItemSelected(MenuItem item) {157     // Handle action bar item clicks here. The action bar will158     // automatically handle clicks on the Home/Up button, so long159     // as you specify a parent activity in AndroidManifest.160     int id = item.getItemId();161     switch(id){162       case R.id.collect:163         Intent intent = new Intent(this,Collect.class);164         startActivity(intent);165         break;166       case R.id.like:167         AddaPoemToCollect();168         break;169     }170 171     return super.onOptionsItemSelected(item);172   }173 }

View Code

 

  这是修改过的主活动。

  1.首先更换了字体放在assets文件夹内,在res里面,没有的请新建。

1 Typeface typeface = Typeface.createFromAsset(getAssets(),"fonts/font_ksj.ttf");2     textView = (TextView)findViewById(R.id.text_view);3     textView.setTypeface(typeface);

 

获取了字体资源,注册了一个textview,把字体设置为textview。

    

这是修改过的效果,纤细的字体很适合我们的古诗!

  2.

 1   private void ChangeBackground(){ 2     int ln = (int) (1 + Math.random() * (5)); 3     switch (ln){ 4       case 1: 5         main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.detail_bg)); 6         break; 7       case 2: 8         main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_1)); 9         break;10       case 3:11         main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_2));12         break;13       case 4:14         main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_3));15         break;16       case 5:17         main_layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.navigation_4));18         break;19     }20   }

 

  添加了一个修改背景的函数,每次进入会随机选择背景,这样我们每次进入就有可能看到不一样的背景了。

  3.

 1   private void FindaPoem() { 2     int ll = (int) (1 + Math.random() * (59170)); 3     ID = ll; 4     SQLiteDatabase database = openDatabase(); 5     Cursor cursor = database.rawQuery("Select * From poem Where _id = " + ll, null); 6     cursor.moveToFirst(); 7     String poem = cursor.getString(1)+"\n"+"\n"+cursor.getString(2)+"\n"+"\n"+cursor.getString(13); 8     NAME = cursor.getString(2)+": "+cursor.getString(1); 9     POEM = cursor.getString(13);10     Log.e(poem, "================");11     textView.setText(poem);12     cursor.close();13     database.close();14   }

 

  从数据库里随即一个数(我数据库里有59170首诗,=-=!)然后打开数据库,找到ID为此项的诗,然后获取诗的内容,getString的号码要按照你自己的数据库需要选择不同的栏位,

比如0位就是ID的栏位,我这里面作者古诗名和古诗内容是分开存放的,而且加入了不少我要用的数据,所以栏位增加到了13个之多,自己做的话只需要三个栏位就好,一个id,一个古诗内容,

一个收藏标记位(用0和1来标记)

  所以我对dbhelper的数据库生成类进行了一些修改:

 1 package com.lfk.poem; 2  3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteOpenHelper; 6 import android.widget.Toast; 7  8 /** 9  * Created by Administrator on 2015/5/8.10 */11 public class DBhelper extends SQLiteOpenHelper {12   private static final String CREAT_DB = "create table book ("13       + "id integer primary key autoincrement,"14       + "collect int,"15       + "poem text)";16   private Context mcontext;17 18   public DBhelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {19     super(context, name, factory, version);20     mcontext = context;21   }22 23   @Override24   public void onCreate(SQLiteDatabase db) {25     db.execSQL(CREAT_DB);26     Toast.makeText(mcontext,"succeed collect!",Toast.LENGTH_SHORT).show();27   }28 29   @Override30   public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {31   }32 }

 

  这样生成的数据库就能成功的应用收藏功能了,上一步所说的修改数据库也就能实现了。

6.收藏功能的实现:

  我在写这篇博文之前曾经写过两次关于收藏的内容,第一次的方法比较蠢,我又开了一个用户的数据库,然后把要收藏的东西复制进用户数据库中,不过这种方法比较麻烦,

首先是开两个数据库增加了系统的无谓开销,增加了对系统资源的消耗,而且在传入新的数据库中,id会发生变化,写入和传值会非常的不便利,所以我放弃了那种方法,改用

在数据库设置标志栏位的方法来解决问题。

  

 1 package com.lfk.poem; 2  3 import android.app.Activity; 4 import android.content.Intent; 5 import android.database.Cursor; 6 import android.database.sqlite.SQLiteDatabase; 7 import android.os.Bundle; 8 import android.os.Environment; 9 import android.util.Log; 10 import android.view.View; 11 import android.widget.AdapterView; 12 import android.widget.ArrayAdapter; 13 import android.widget.ListView; 14 import android.widget.TextView; 15 import android.widget.Toast; 16  17 import java.io.File; 18  19  20 public class Collect extends Activity { 21   private DBhelper dBhelper; 22   private ListView listView; 23   public static ArrayAdapter<String> mArrayAdapter; 24   public static final String DB_NAME = "poem_all.db"; //保存的数据库文件名 25   public static final String PACKAGE_NAME = "com.lfk.poem";// 应用的包名 26   public static final String DB_PATH = "/data" 27       + Environment.getDataDirectory().getAbsolutePath() +"/" 28       + PACKAGE_NAME+ "/databases"; // 在手机里存放数据库的位置 29   @Override 30   protected void onCreate(Bundle savedInstanceState) { 31     super.onCreate(savedInstanceState); 32     setContentView(R.layout.activity_collect); 33     String[] data = new String[0]; 34     //dBhelper = new DBhelper(this,"poem_all.db",null,1); 35     listView = (ListView)findViewById(R.id.list_view); 36     mArrayAdapter = new ArrayAdapter<String>(this,R.layout.list_item); 37     listView.setAdapter(mArrayAdapter); 38     FindyourCollect(); 39     listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 40       @Override 41       public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 42                   long arg3) { 43         System.out.println(arg2); 44         String temp = (String)((TextView)arg1).getText(); 45         Intent intent = new Intent(); 46         intent.putExtra("title",temp); 47         System.out.println(arg2); 48         intent.setClass(Collect.this, Collect_item.class); 49         startActivity(intent); 50         Toast.makeText(getApplicationContext(), 51             "Opening " + arg2, 52             Toast.LENGTH_SHORT).show(); 53         mArrayAdapter.notifyDataSetChanged(); 54       } 55     }); 56   } 57  58  59 //  @Override 60 //  public boolean onCreateOptionsMenu(Menu menu) { 61 //    // Inflate the menu; this adds items to the action bar if it is present. 62 //    getMenuInflater().inflate(R.menu.menu_collect, menu); 63 //    return true; 64 //  } 65 // 66 //  @Override 67 //  public boolean onOptionsItemSelected(MenuItem item) { 68 //    // Handle action bar item clicks here. The action bar will 69 //    // automatically handle clicks on the Home/Up button, so long 70 //    // as you specify a parent activity in AndroidManifest. 71 //    int id = item.getItemId(); 72 // 73 //    //noinspection SimplifiableIfStatement 74 //    if (id == R.id.action_settings) { 75 //      return true; 76 //    } 77 // 78 //    return super.onOptionsItemSelected(item); 79 //  } 80   void FindyourCollect(){ 81     File myDataPath = new File(DB_PATH); 82     String dbfile = myDataPath+"/"+DB_NAME; 83     SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(dbfile, null); 84     Cursor cursor = database.rawQuery("Select * From poem where ticai = 1", null); 85     Log.e("===================", "================"); 86     if(cursor.moveToFirst()) { 87       Log.e("===================", "================"); 88       do { 89         String title = cursor.getString(cursor.getColumnIndex("mingcheng")); 90         mArrayAdapter.add(title); 91         Log.e(title, "================"); 92       }while (cursor.moveToNext()); 93     } 94     cursor.close(); 95     database.close(); 96   } 97   @Override 98   protected void onRestart(){ 99     super.onRestart();100     mArrayAdapter.clear();101     FindyourCollect();102     mArrayAdapter.notifyDataSetChanged();103   }104 }

 

这是Collect的活动的代码,代码中用了一个系统自带的简易的listview(主要是也不需要太多的功能),进入之后运行FindyourCollect()方法用Select * From poem where ticai = 1语法,

寻找标志位,然后把所有找到的东西加入listview中去,然后设置item的响应打开。

 1 package com.lfk.poem; 2  3 import android.app.Activity; 4 import android.content.Intent; 5 import android.database.Cursor; 6 import android.database.sqlite.SQLiteDatabase; 7 import android.graphics.Typeface; 8 import android.os.Bundle; 9 import android.util.Log;10 import android.view.Menu;11 import android.view.MenuItem;12 import android.widget.TextView;13 import android.widget.Toast;14 15 16 public class Collect_item extends Activity {17   private DBhelper dBhelper;18   private String ID;19   @Override20   protected void onCreate(Bundle savedInstanceState) {21     super.onCreate(savedInstanceState);22     setContentView(R.layout.activity_collect_item);23     Intent intent = getIntent();24     String title = intent.getStringExtra("title");25     //System.out.println(id+"=================");26     TextView textView = (TextView)findViewById(R.id.poem_item);27     Typeface typeface = Typeface.createFromAsset(getAssets(),"fonts/font_ksj.ttf");28     textView.setTypeface(typeface);29     dBhelper = new DBhelper(this,"poem_all.db",null,1);30     SQLiteDatabase database = dBhelper.getWritableDatabase();31     Cursor cursor = database.rawQuery("Select * From poem where mingcheng="+"\""+title+"\"", null);32     cursor.moveToFirst();33     ID = cursor.getString(cursor.getColumnIndex("_id"));34     String poem = cursor.getString(1)+"\n"+"\n"+cursor.getString(2)+"\n"+"\n"+cursor.getString(13);35     textView.setText(poem);36     Log.e("===================", "================");37     cursor.close();38     database.close();39   }40 41   @Override42   public boolean onCreateOptionsMenu(Menu menu) {43     // Inflate the menu; this adds items to the action bar if it is present.44     getMenuInflater().inflate(R.menu.menu_collect_item, menu);45     return true;46   }47 48   @Override49   public boolean onOptionsItemSelected(MenuItem item) {50     // Handle action bar item clicks here. The action bar will51     // automatically handle clicks on the Home/Up button, so long52     // as you specify a parent activity in AndroidManifest.53     int id = item.getItemId();54 55     if(id == R.id.dislike_collect){56       SQLiteDatabase db = dBhelper.getWritableDatabase();57       db.execSQL("UPDATE poem SET ticai = 0 WHERE _id ="+ID);58       db.close();59       Toast.makeText(getApplicationContext(),60           "Collect Delete",61           Toast.LENGTH_SHORT).show();62     }63 64     return super.onOptionsItemSelected(item);65   }66 67 }

 

打开后的方法比较简单和主活动基本一样,接受传入的题目,然后根据题目找到我们需要的诗,设置字体然后textview中显示出来。

然后就是加入收藏了,为了方便,我把加入收藏写进了meau中以方便使用:

 1 void AddaPoemToCollect(){ 2     //File myDataPath = new File(DB_PATH); 3     //String dbfile = myDataPath+"/"+DB_USER_NAME; 4     SQLiteDatabase db = openDatabase(); 5     //ContentValues contentValues = new ContentValues(); 6     db.execSQL("UPDATE poem SET ticai = 1 WHERE _id ="+ID); 7     //db.insert("book", null, contentValues); 8     db.close(); 9     Toast.makeText(getApplicationContext(),10         "Collect succeed",11         Toast.LENGTH_SHORT).show();12     //ID++;13   }14   void deleteAPoemFromCollect(){15     SQLiteDatabase db = openDatabase();16 17     db.execSQL("UPDATE poem SET ticai = 0 WHERE _id ="+ID);18 19     db.close();20 21     Toast.makeText(getApplicationContext(),22         "Collect Delete",23         Toast.LENGTH_SHORT).show();24   }

 

这个就是加入收藏和删除收藏的方法所在了,我在主活动和收藏的内容活动中都为meau添加了这个方法,并且设置了一个全局变量ID用于删除和加入收藏的时候寻址。

到此为止我们初期的功能就都开发完了,放出新的界面,图片还是暂时借用了别人的成例,我已经找UI帮我做更好看的界面了:

            

            

            

            

好了这一篇就说这么多吧,应该还会有一些新的有意思的功能要尝试,所以应该还会有后续吧!

么么哒,喜欢就点赞吧!!!