2015.08.09
喜闻乐见的大结局终于来了!我自己一点一点写下来感觉收获很多,但是基本上我是需要什么学什么,所以掌握的不多,但是总体来说基本满足了我背单词的需要----我不想用书本去刷单词,但是市场上的背单词app又不能让我按照老师的方法10s过一个单词----于是这个app便诞生了!
这篇博客其实没什么可写的,因为我实现的功能在之前的博客里面已经有记录过了,但是随着不断的学习,不断的调整,原来贴上来的代码也在不断地改变着.所以本次打算把把代码的最终版本写上来,以后看着方便,也好和之前的进行对比.
话不多少,上代码!
1.MainActivity.java
这主要是欢迎界面,包含一个TextView(欢迎语),一个Button(用来获取今天的计划量),一个跳转按钮,还有一个背景图片
package example.mywordapp;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
/*欢迎界面*/
public class MainActivity extends Activity {
//声明一个按钮
private Button startButton=null;
private TextView welcomeText=null;
private EditText TodayPlanEditText=null;
//复写onCreate方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TodayPlanEditText=(EditText)findViewById(R.id.TodayPlan);
//捆绑监听器到按钮上
startButton=(Button)findViewById(R.id.startButton);
startButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent();
intent.setClass(MainActivity.this,MySQLiteActivity.class);
intent.putExtra("today_plan",TodayPlanEditText.getText().toString() );
MainActivity.this.startActivity(intent);
}
});
welcomeText=(TextView)findViewById(R.id.welcome);
welcomeText.setText("背单词唯一有效的手段就是过遍数");
}
}
2.MySQLiteActivity.java
包含四个按钮和一个ListView:
add添加单词库(SQLite方式)
package mywordapp.wordsqlite;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper extends SQLiteOpenHelper{
private static final String DATABASE_NAME = "vocabulary_db";
private static final int DATABASE_VERSION = 1;
public DBHelper(Context context)
{//CursorFactory 设置为默认值null
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//数据库第一次被创建时onCreate会被调用
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS word"+
"(_id INTEGER PRIMARY KEY AUTOINCREMENT,en_meaning VARCHAR,cn_meaning VARCHAR,repeating_number INTEGER)");
}
//如果DATABASE_VERSION的值被改成2,系统发现现有数据库版本不同,就会调用onUpgrade
@Override
public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)
{
db.execSQL("ALTER TABLE word ADD COLUMN other STRING");
}
}
delete:删除记忆遍数达到50的单词
queryTheCursor:用ListView显示所有单词(并没有设置大滚轮,所以翻三千个单词基本不靠谱,用处不大)
gogogo:开始记忆单词的跳转按钮(包含获取参数的方法)
onActivityResult:数据库更新
package example.mywordapp;
import java.io.InputStream;
import java.util.ArrayList;
import org.apache.http.util.EncodingUtils;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import mywordapp.wordsqlite.DBManager;
import mywordapp.wordsqlite.Word;
public class MySQLiteActivity extends Activity{
private DBManager mgr;
public String res;
//学习进度&今日学习计划
private int today_start_place;
private int today_plan;
private boolean para_need_get=true;
//获取今日计划和开始的位置
public void getTodayLearningParameters(int []WordRepeatedNumber)
{
Intent intent=getIntent();
String tmp=intent.getStringExtra("today_plan");
today_plan=Integer.parseInt(tmp);
today_start_place=0;
for(int i=0;i<3111;i++)
if(WordRepeatedNumber[i]>WordRepeatedNumber[i+1])
{
today_start_place=i+1;
break;
}
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sqlite);
//初始化DBManager
mgr=new DBManager(this);
}
//添加单词
public void add(View view) {
ArrayList<Word> words=new ArrayList<Word>();
String fileName = "GRE.txt"; //单词表名字 ,文件要放在asset文件夹下
try{
//得到资源中的asset数据流
InputStream in = getResources().getAssets().open(fileName);
//利用IO流或得一个res的String串,res里面的内容是整个单词表txt里面的内容
int length = in.available();
byte [] buffer = new byte[length];
in.read(buffer);
in.close();
res = EncodingUtils.getString(buffer, "UTF-8");
}catch(Exception e){
e.printStackTrace();
}
//利用String类里面的split方法将res这个大字符串分割成一个String数组,其中的一行就是一个单词
String []tmp=res.split("\n");
for(int i=0;i<tmp.length;i++)
{
//这是在利用我们之前设置好的唯一的一个空格进行二次切割,从而分离出来英语单词和中文释义,这样就可以加入到数据库了
String []tmp_word=tmp[i].split(" ");
//System.out.println(i+1+" "+tmp_word[0]+" "+tmp_word[1]);
Word word=new Word(tmp_word[0],tmp_word[1],0);
words.add(word);
}
mgr.add(words);
}
//删除烂熟的单词
public void delete(View view) {
Word word = new Word();
word.repeating_number = 50;
mgr.deleteAdroidWord(word);
}
//全体查询,返回的是整个单词表,然后利用SimpleAdapter和ListView绑定在一起
//注意要确保查询结果中有"_id"列
@SuppressWarnings("deprecation")
public void queryTheCursor(View view) {
Cursor c = mgr.queryTheCursor();
startManagingCursor(c); //托付给activity根据自己的生命周期去管理Cursor的生命周期
CursorWrapper cursorWrapper = new CursorWrapper(c) {
@Override
public String getString(int columnIndex) {
//在英文后加上中文
if (getColumnName(columnIndex).equals("en_meaning")) {
String cn_meaning = getString(getColumnIndex("cn_meaning"));
return super.getString(columnIndex)+" "+cn_meaning;
}
return super.getString(columnIndex);
}
};
//下面是在绑定语句----其结果是每个list显示两行:第一行是单词+释义,第二行是记忆次数.
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2,
cursorWrapper, new String[]{"en_meaning", "repeating_number"}, new int[]{android.R.id.text1, android.R.id.text2});
ListView listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
}
//开始刷单词!
//主要功能--获取单词和学习进度同时传递进度
@SuppressWarnings("deprecation")
public void gogogo(View view)
{
Cursor c=mgr.queryTheCursor();
startManagingCursor(c);
//获取单词的所有信息
int k=0;
int []_id=new int[3113];
String []English=new String[3112];
String []Chinese=new String[3113];
int []WordRepeatedNumber=new int[3113];
while(c.moveToNext())
{
_id[k]=c.getInt(c.getColumnIndex("_id"));
English[k]=c.getString(c.getColumnIndex("en_meaning"));
Chinese[k]=c.getString(c.getColumnIndex("cn_meaning"));
WordRepeatedNumber[k]=c.getInt(c.getColumnIndex("repeating_number"));
k++;
}
//获取学习进度
if(para_need_get) {
getTodayLearningParameters(WordRepeatedNumber);
para_need_get=false;
}
//参数传递
Intent intent=new Intent(MySQLiteActivity.this,MyHandlerActivity.class);
Bundle bundle=new Bundle();
bundle.putIntArray("_id", _id);
bundle.putStringArray("English", English);
bundle.putStringArray("Chinese", Chinese);
bundle.putInt("today_start_place", today_start_place);
bundle.putInt("today_plan", today_plan);
intent.putExtras(bundle);
MySQLiteActivity.this.startActivityForResult(intent, 1000);
}
//更新当前学习进度
@SuppressWarnings("deprecation")
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==1000&&resultCode==1001)
{
Cursor c=mgr.queryTheCursor();
startManagingCursor(c);
//获取更新需要的参数--开始更新的位置和待更新的单词数目
int end_update_place=data.getIntExtra("next_start_place", today_plan+today_start_place);
int start_update_place=today_start_place;
int total_time=end_update_place>=start_update_place?end_update_place-start_update_place+1:3111+end_update_place-start_update_place+1;
//更新操作,需要判断背完3000单词之后再从头背的情况
c.moveToPosition(start_update_place-1);
int update_time=1;
while(c.moveToNext()&&update_time<=total_time)
{
String tmpString=c.getString(c.getColumnIndex("en_meaning"));
int tmpNumber=c.getInt(c.getColumnIndex("repeating_number"));
mgr.updateRepeating_Number(tmpString,tmpNumber);
update_time++;
}
if(update_time<total_time)
{
c.moveToPosition(-1);
while(c.moveToNext()&&update_time<=total_time)
{
String tmpString=c.getString(c.getColumnIndex("en_meaning"));
int tmpNumber=c.getInt(c.getColumnIndex("repeating_number"));
mgr.updateRepeating_Number(tmpString,tmpNumber);
update_time++;
}
}
//更新当前学习进度,以便继续刷的时候的进度更新
today_start_place=end_update_place+1;
today_plan-=update_time-1;
}
}
}
这其中还有数据库的设置及封装文件
a.DBHelper.java----创建数据库
package mywordapp.wordsqlite;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper extends SQLiteOpenHelper{
private static final String DATABASE_NAME = "vocabulary_db";
private static final int DATABASE_VERSION = 1;
public DBHelper(Context context)
{//CursorFactory 设置为默认值null
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//数据库第一次被创建时onCreate会被调用
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS word"+
"(_id INTEGER PRIMARY KEY AUTOINCREMENT,en_meaning VARCHAR,cn_meaning VARCHAR,repeating_number INTEGER)");
}
//如果DATABASE_VERSION的值被改成2,系统发现现有数据库版本不同,就会调用onUpgrade
@Override
public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)
{
db.execSQL("ALTER TABLE word ADD COLUMN other STRING");
}
}
b.DBManager.java----数据库操作封装
package mywordapp.wordsqlite;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class DBManager {
private DBHelper helper;
private SQLiteDatabase db;
public DBManager(Context context)
{
helper=new DBHelper(context);
db=helper.getWritableDatabase();
}
/*
* 添加单词*/
public void add(List<Word> words)
{
db.beginTransaction();
try
{
for (Word word : words)
{
db.execSQL("INSERT INTO word VALUES(null,?,?,?)",new Object[]{word.en_meaning,word.cn_meaning,word.repeating_number});
}
db.setTransactionSuccessful();
}finally{
db.endTransaction();
}
}
/*更新记忆次数*/
public void updateRepeating_Number(String English,int OldRepeatingNumber)
{
ContentValues cv=new ContentValues();
int NewRepeatingNumber=OldRepeatingNumber+1;
cv.put("repeating_number",NewRepeatingNumber);
db.update("word", cv, "en_meaning=?", new String[]{English});
}
/*删除烂熟的单词*/
public void deleteAdroidWord(Word word) {
db.delete("word", "repeating_number >=?", new String[]{String.valueOf(word.repeating_number)});
}
/*查询所有单词,返回一个完整的单词表*/
public List<Word> query()
{
ArrayList<Word> words=new ArrayList<Word>();
Cursor csr=queryTheCursor();
while (csr.moveToNext()) {
Word word = new Word();
word._id=csr.getInt(csr.getColumnIndex("_id"));
word.en_meaning=csr.getString(csr.getColumnIndex("en_meaning"));
word.cn_meaning=csr.getString(csr.getColumnIndex("cn_meaning"));
word.repeating_number=csr.getInt(csr.getColumnIndex("repeating_number"));
}
return words;
}
public Cursor queryTheCursor() {
Cursor c=db.rawQuery("SELECT*FROM word", null);
return c;
}
/*关闭数据库*/
public void closeDB()
{
db.close();
}
}
c.Word.java----定义一个单词类,方便数据库录入
package mywordapp.wordsqlite;
public class Word {
public int _id;
public String en_meaning;
public String cn_meaning;
public int repeating_number;
public Word(){}
public Word(String en_meaning,String cn_meaning,int repeating_number)
{
this.en_meaning=en_meaning;
this.cn_meaning=cn_meaning;
this.repeating_number=repeating_number;
}
}
这是显示单词并定时刷新的控件
package example.mywordapp;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import example.mywordapp.R;
public class MyHandlerActivity extends Activity {
private Button btnStart;
private Button btnStop;
private Button btnBack;
private Button btnSkip;
private TextView EnText;
private TextView CnText;
private TextView CountText;
private boolean run = false;
private String []English=new String[3113];
private String []Chinese=new String[3113];
private int today_start_place;//开始背的位置
private int today_plan;//要背的单词数目
private int next_start_place;//当前进行道德位置
public int k;//当前进度
private final Handler handler = new Handler();
private final Runnable task = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
next_start_place=k;
EnText.setText("\n" + English[k]);
CnText.setText(""+Chinese[k]);
CountText.setText(""+k);
//设置跳过功能--这个单词如果认识点击按钮直接跳到下一个
btnSkip=(Button)findViewById(R.id.Button04);
btnSkip.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
handler.removeCallbacks(task);//销毁当前线程
handler.postDelayed(task, 1);//重新开始
}
});
if (run&&k<today_plan+today_start_place-1&&k<3112) {
k++;
if(k>3111) {k=0;today_plan=today_plan+today_start_place-3111;today_start_place=0;}
handler.postDelayed(this, 7777);
}
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//保持屏幕常亮
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_handler);
//接收参数,获取学习计划和开始的位置
Intent intent=getIntent();
English=intent.getStringArrayExtra("English");
Chinese=intent.getStringArrayExtra("Chinese");
today_plan=intent.getIntExtra("today_plan", 100);
today_start_place=intent.getIntExtra("today_start_place", 500);
k=today_start_place;
btnStart = (Button) findViewById(R.id.Button01);
btnStop = (Button) findViewById(R.id.Button02);
btnBack=(Button)findViewById(R.id.Button03);
EnText = (TextView) findViewById(R.id.en_text);
CnText=(TextView)findViewById(R.id.cn_text);
CountText=(TextView)findViewById(R.id.count_text);
//设置开始按钮
btnStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
run = true;
updateButton();
handler.postDelayed(task, 1);
}
});
//设置暂停按钮
btnStop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
run = false;
updateButton();
handler.post(task);
}
});
//设置返回键去向数据库控件传递参数从而更新数据库
btnBack.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
run=false;
Intent intent=new Intent();
intent.putExtra("next_start_place", next_start_place);
setResult(1001,intent);
finish();
}
});
}
private void updateButton() {
btnStart.setEnabled(!run);
btnStop.setEnabled(run);
}
}
至于布局文件就不再写出来了
来几张效果图:
虽然界面low了一点但是我感觉比较简洁,还算接受得了,你们怎么看?
最后说一下后续计划,我会在后面找一些开源控件去代替这些控件并且尽可能进行一些功能拓展,加油!
end~