接前面一篇http://blog.csdn.net/molu_chase/article/details/53954557
前面只是实现了查询的功能,但是查完之后,不会留下任何信息,下面我使用数据库将查询的结果保存下来,以单词本的形式展现出来,可以实现按点击次数排序或按时间排序,双击去掉单词。(当点击某个单词条目,flag++,双击会从数据库中删除)
具体使用知识点如下:
1.SQLite中插入,更新,删除,查询的使用
2.自定义ListView
3.ListView的点击事件实现,关于双击的处理
Android 中SQLite操作见下面两篇文章
http://blog.csdn.net/jason0539/article/details/10248457
http://blog.csdn.net/codeeer/article/details/30237597/
讲解的很详细,我下面关于SQLite的使用的疑问全部在上面可以找到答案,对于增删改查最好使用SQLite语言
首先建SQLiteOpenHelper的子类,如下,这个类有两个方法,一个是onCreate,一个是onUpgrade。在onCreate()函数中执行建表语句,该函数只有在第一次建表的时候才会调用,之后不会调用;onUpgrade()函数针对的是版本号,和在new实例的时候传给构造函数的最后一个参数有关;当数据库更新的时候调用,这篇文章讲的很详细
http://blog.csdn.net/molu_chase/article/details/53966388
在数据库中建note_table表,包含word,explains,flag,phonogram字段
public class SqliteOperate extends SQLiteOpenHelper {
public SqliteOperate(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql="CREATE TABLE note_table(word VARCHAR(20) PRIMARY KEY NOT NULL,explains VARCHAR(250) ,flag int NOT NULL,phonogram VARCHAR(20))";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// String sql="ALTER TABLE note_table ADD COLUMN flag int";
// db.execSQL(sql);
}
}
dbHelper=new SqliteOperate(MainActivity.this,"note.db",null,1);
插入操作(下面的方法不推荐,最好使用数据库语句)
类似于Map的键值对,将用户查询的单词json解析后相应的存储到数据库
SQLiteDatabase db=dbHelper.getWritableDatabase();
ContentValues contentValues=new ContentValues();
contentValues.put("word",word);
contentValues.put("explains",explains);
contentValues.put("phonogram",phonogram);
contentValues.put("flag",0);
db.insert("note_table",null,contentValues);
db.close();
查询语句
将从数据库中查到的结果实例化WordInfo类对象,并添加到arrayList中,其中arrayList为adapter中的数据来源
SQLiteDatabase db=MainActivity.dbHelper.getReadableDatabase();
// Cursor cursor = db.query("note_table", null, null, null, null, "flag DESC", null);
Cursor cursor;
if(b==1) {
cursor = db.rawQuery("SELECT * FROM note_table ORDER BY flag DESC", null);
}else{
cursor = db.rawQuery("SELECT * FROM note_table", null);
}
while(cursor.moveToNext()){
String word=cursor.getString(cursor.getColumnIndex("word"));
String explains=cursor.getString(cursor.getColumnIndex("explains"));
String phonogram=cursor.getString(cursor.getColumnIndex("phonogram"));
int flag=cursor.getInt(cursor.getColumnIndex("flag"));
WordInfo wordInfo=new WordInfo(word,explains,phonogram,flag);
arrayList.add(wordInfo);
}
db.close();
下面讲讲自定义ListView
需要以下几步:子布局,
适配器中的参数类,
继承适配器重现getView方法,
主布局中添加ListView,并在Activity中加载。
子布局:
很简单,就使用了两个textView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/text_word"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textColor="@color/red"/>
<TextView
android:id="@+id/text_explains"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
参数类:
主要是映射数据表中的一条记录
public class WordInfo {
private String word;
private String explains;
private int flag;
private String phonogram;
public WordInfo(String word, String explains,String phonogram,int flag) {
this.word = word;
this.explains = explains;
this.phonogram=phonogram;
this.flag=flag;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public String getExplains() {
return explains;
}
public void setExplains(String explains) {
this.explains = explains;
}
public int getFlag() {
return flag;
}
public void setFlag(int flag) {
this.flag = flag;
}
public String getPhonogram() {
return phonogram;
}
public void setPhonogram(String phonogram) {
this.phonogram = phonogram;
}
}
继承适配器重写getView:
注意构造函数中的三个参数,泛型里面传的是子数据类
public class WordAdapter extends ArrayAdapter<WordInfo> {
private int resourceId;
//传入文本,子布局,List列表
public WordAdapter(Context context, int resource, List<WordInfo> objects) {
super(context, resource, objects);
resourceId=resource;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
WordInfo wordInfo=getItem(position);
View view= LayoutInflater.from(getContext()).inflate(resourceId, null);
TextView textView_word=(TextView)view.findViewById(R.id.text_word);
TextView textView_explains=(TextView)view.findViewById(R.id.text_explains);
textView_word.setText(Html.fromHtml(wordInfo.getWord()+" <font color='#000000'>["+wordInfo.getPhonogram()+"] "+"("+wordInfo.getFlag()+")</font>"));
textView_explains.setText(Html.fromHtml(wordInfo.getExplains()));
return view;
}
}
在主布局中加载:
arrayAdapter=new WordAdapter(NoteActivity.this,R.layout.simple_item,arrayList2);
listView=(ListView)findViewById(R.id.listview);
listView.setAdapter(arrayAdapter);
关于主布局中:我使用的是RelativeLayout,对于在listView下添加一行Button的方法,先设置Button位于父布局的底部,然后将listView设置为位于Button的上面
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.administrator.dictionary.NoteActivity">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/butt"
></ListView>
<LinearLayout
android:id="@+id/butt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
>
<Button
android:id="@+id/bt_time"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="60dp"
android:text="按时间顺序"/>
<Button
android:id="@+id/bt_click"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="60dp"
android:text="按点击次数"/>
</LinearLayout>
</RelativeLayout>
最后关于ListView点击事件的实现
对于双击事件,使用的是时间和position来判断的
其中还提到动态修改ListView的方法
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
WordInfo wi=arrayList2.get(position);
long time=System.currentTimeMillis();
if(position==prepostion&&Math.abs(time-pretime)<500){
//双击事件
SQLiteDatabase db=MainActivity.dbHelper.getWritableDatabase();
String sql="DELETE FROM note_table WHERE word=?";
db.execSQL(sql,new Object[]{wi.getWord()});
db.close();
arrayList2.remove(position);
arrayAdapter.notifyDataSetChanged();
// listView.setAdapter(arrayAdapter);
// Toast.makeText(NoteActivity.this,"双击事件"+position,Toast.LENGTH_SHORT).show();
}else{
//单击事件
SQLiteDatabase db=MainActivity.dbHelper.getWritableDatabase();
String sql="UPDATE note_table SET flag=? WHERE word=?";
int flag=wi.getFlag()+1;
wi.setFlag(flag);
String word=wi.getWord();
db.execSQL(sql, new Object[]{flag, word});
db.close();
// Toast.makeText(NoteActivity.this,"单击事件"+position,Toast.LENGTH_SHORT).show();
}
pretime=time;
prepostion=position;
}
});
源码见github地址:https://github.com/moluchase/Dictionary
参考:
adapter http://blog.csdn.net/nairuohe/article/details/6457300/
点击事件http://www.eoeandroid.com/thread-553920-1-1.html?_dsign=e843b26d