前话:明天要交安卓程序了,前几天在自己的电脑上配置了一下安卓环境,但是项目无法编译,原因好像是jdk版本过高,有一个包无法支持,然后换成1.8的jdk也不行,昨晚折腾到凌晨一点半也没成功,今天借了同学的电脑,把之前构思的一个程序逻辑和代码思路实现了一下。
该程序要实现的只有最简单的几个功能:
1.添加一个备忘录
2.查看备忘录列表
3.点击某个备忘录查看里面的信息
4.修改某个备忘录的信息
5.删除某个备忘录
6.备忘录的信息保存到数据库中
编译环境:SDK+ADT
程序运行功能展示:
主界面:
添加备忘录:
编辑备忘录信息"hello world"并保存:
查看备忘录信息:
修改备忘录信息为“very good!”:
最后删除备忘录信息,界面为空。
由于时间原因,本程序的不完美的地方主要有以下两个:
1.在删除某个备忘录的信息后,希望能把删除的备忘录信息后面备忘录的id号进行重新排序(比如有1,2,3条备忘录信息,如果我要删除掉2第二个备忘录,希望再次打开备忘录列表时,能显示1,2),但是此程序没有实现该功能。(实际上我写了一段代码:在点击删除按钮之后,再读一遍数据库里的信息,将id号重新按照递增差值为1的顺序排好,但是失败了,原因未知。)
2.在备忘录列表里点击某个具体的备忘录信息后,也就是说由当前的activity-A跳转到下一个activity-B,假设在activity-B里执行的操作为删除,希望返回activity-A时,能够自动更新备忘录列表,将已经删除的备忘录在该列表里删除。
此功能也没有实现,并且这个问题是我耗时最多去思考的一个问题,用了几种方法,都没有达到预期的效果。
于是最后干脆在activity-B执行删除动作结束后,跳转到了主activity,也就是最初的界面。虽然麻烦了一步,不过总比我退回上一个界面后看到了我删除的备忘录信息还在强。。。
跳转到主activity的实现很简单,只需要在activity-A跳转到activity-B时,finish掉A就可以了。
源码:
一.com.example.DB 包:
1.DBHelper类:
创建数据库
package com.example.DB;import android.content.Context;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;public class DBHelper extends SQLiteOpenHelper{private static final int VERSION = 1;private static final String DBNAME = "memorandum.db";public DBHelper(Context context){super(context, DBNAME, null, VERSION);}public void onCreate(SQLiteDatabase db){// 创建数据库db.execSQL("create table memorandum_db (_id integer primary key,flag varchar(400))");// 创建便签信息表}@Overridepublic void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {// TODO Auto-generated method stub}}
2.AddMemo类:
实现的主要功能:
添加便签信息,更新便签信息,查找便签信息,删除便签信息,获取便签信息,获取便签的总记录数,获取便签最大编号。
package com.example.DB;import java.util.ArrayList;import java.util.List;import com.example.model.Tb_flag;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;public class AddMemo {private DBHelper helper;private SQLiteDatabase db;public AddMemo(Context context){helper = new DBHelper(context);db = helper.getWritableDatabase();}/** 添加便签信息* */public void add(Tb_flag tb_flag) {db.execSQL("insert into memorandum_db (_id,flag) values (?,?)", new Object[] {tb_flag.getid(), tb_flag.getFlag() });// 执行添加便签信息操作}/** 更新便签信息* */public void update(Tb_flag tb_flag) {//db = helper.getWritableDatabase();// 初始化SQLiteDatabase对象db.execSQL("update memorandum_db set flag = ? where _id = ?", new Object[] {tb_flag.getFlag(), tb_flag.getid() });// 执行修改便签信息操作}/** 查找便签信息* */public Tb_flag find(int id) {//db = helper.getWritableDatabase();// 初始化SQLiteDatabase对象Cursor cursor = db.rawQuery("select _id,flag from memorandum_db where _id = ?",new String[] { String.valueOf(id) });// 根据编号查找便签信息,并存储到Cursor类中if (cursor.moveToNext()){// 遍历查找到的便签信息// 将遍历到的便签信息存储到Tb_flag类中return new Tb_flag(cursor.getInt(cursor.getColumnIndex("_id")),cursor.getString(cursor.getColumnIndex("flag")));}cursor.close();// 关闭游标return null;// 如果没有信息,则返回null}/** 删除便签信息* */public void detele(Integer... ids) {if (ids.length > 0){// 判断是否存在要删除的idStringBuffer sb = new StringBuffer();// 创建StringBuffer对象for (int i = 0; i < ids.length; i++){// 遍历要删除的id集合sb.append('?').append(',');// 将删除条件添加到StringBuffer对象中}sb.deleteCharAt(sb.length() - 1);// 去掉最后一个“,“字符//db = helper.getWritableDatabase();// 创建SQLiteDatabase对象// 执行删除便签信息操作db.execSQL("delete from memorandum_db where _id in (" + sb + ")",(Object[]) ids);}}/*获取便签信息* */public List<Tb_flag> getScrollData(int start, int count) {List<Tb_flag> lisTb_flags = new ArrayList<Tb_flag>();// 创建集合对象//db = helper.getWritableDatabase();// 初始化SQLiteDatabase对象// 获取所有便签信息Cursor cursor = db.rawQuery("select * from memorandum_db limit ?,?",new String[] { String.valueOf(start), String.valueOf(count) });while (cursor.moveToNext()){// 遍历所有的便签信息// 将遍历到的便签信息添加到集合中lisTb_flags.add(new Tb_flag(cursor.getInt(cursor.getColumnIndex("_id")), cursor.getString(cursor.getColumnIndex("flag"))));}cursor.close();// 关闭游标return lisTb_flags;// 返回集合}/** 获取便签的总记录数* */public long getCount() {//db = helper.getWritableDatabase();// 初始化SQLiteDatabase对象Cursor cursor = db.rawQuery("select count(_id) from memorandum_db", null);// 获取便签信息的记录数if (cursor.moveToNext()){// 判断Cursor中是否有数据return cursor.getLong(0);// 返回总记录数}cursor.close();// 关闭游标return 0;// 如果没有数据,则返回0}/** 获取便签最大编号* */public int getMaxId() {//db = helper.getWritableDatabase();// 初始化SQLiteDatabase对象Cursor cursor = db.rawQuery("select max(_id) from memorandum_db", null);// 获取便签信息表中的最大编号while (cursor.moveToLast()) {// 访问Cursor中的最后一条数据return cursor.getInt(0);// 获取访问到的数据,即最大编号}cursor.close();// 关闭游标return 0;// 如果没有数据,则返回0}}
二.com.example.model 包:
Tb_flag类:用于存储便签信息实体类
package com.example.model;public class Tb_flag { // 便签信息实体类private int _id;// 存储便签编号private String flag;// 存储便签信息public Tb_flag(){// 默认构造函数super();}// 定义有参构造函数,用来初始化便签信息实体类中的各个字段public Tb_flag(int id, String flag) {super();this._id = id;// 为便签号赋值this.flag = flag;// 为便签信息赋值}public int getid(){// 设置便签编号的可读属性return _id;}public void setid(int id){// 设置便签编号的可写属性this._id = id;}public String getFlag(){// 设置便签信息的可读属性return flag;}public void setFlag(String flag){// 设置便签信息的可写属性this.flag = flag;}}
三.com.example.memorandum 包
1.MainActivity类:
package com.example.memorandum;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button1 = (Button)findViewById(R.id.button1);button1.setOnClickListener(new View.OnClickListener(){public void onClick(View v) {Intent intent = new Intent(MainActivity.this, EditMemo.class);startActivity(intent);}});Button button2 = (Button)findViewById(R.id.button2);button2.setOnClickListener(new View.OnClickListener(){public void onClick(View v) {Intent intent = new Intent(MainActivity.this, ShowInfo.class);startActivity(intent);}});}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic 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.action_settings) {return true;}return super.onOptionsItemSelected(item);}}
2.EditMemo:编辑便签信息
package com.example.memorandum;import com.example.DB.AddMemo;import com.example.model.Tb_flag;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;public class EditMemo extends Activity {EditText txt;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.editmemo);txt = (EditText)findViewById(R.id.txt);Button buttonSave = (Button)findViewById(R.id.save);buttonSave.setOnClickListener(new View.OnClickListener(){public void onClick(View v) {String str = txt.getText().toString();if(!str.isEmpty()) {AddMemo addmemo = new AddMemo(EditMemo.this);Tb_flag tb_flag = new Tb_flag(addmemo.getMaxId() + 1, str);addmemo.add(tb_flag);Toast.makeText(EditMemo.this, "便签保存成功!",Toast.LENGTH_SHORT).show();finish();} else {Toast.makeText(EditMemo.this, "请输入便签!",Toast.LENGTH_SHORT).show();}}});Button buttonCancel = (Button)findViewById(R.id.cancel);buttonCancel.setOnClickListener(new View.OnClickListener(){public void onClick(View v) {txt.setText("");}});}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic 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.action_settings) {return true;}return super.onOptionsItemSelected(item);}}
3.ShowInfo类:显示备忘录信息列表的类
package com.example.memorandum;import java.util.List;import com.example.DB.AddMemo;import com.example.model.Tb_flag;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.Window;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.ListView;import android.widget.TextView;import android.widget.AdapterView.OnItemClickListener;public class ShowInfo extends Activity {public static final String FLAG = "id";ListView lvinfo;String strType = "";protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.showinfo);lvinfo = (ListView) findViewById(R.id.lvinfo);showinfo();lvinfo.setOnItemClickListener(new OnItemClickListener(){// 为ListView添加项单击事件public void onItemClick(AdapterView<?> parent, View view,int position, long id) {String strInfo = String.valueOf(((TextView) view).getText());// 记录单击的项信息String strid = strInfo.substring(0, strInfo.indexOf('.'));// 从项信息中截取编号Intent intent = null;// 创建Intent对象intent = new Intent(ShowInfo.this, FlagManage.class);// 使用FlagManage窗口初始化Intent对象intent.putExtra(FLAG, strid);// 设置要传递的数据startActivity(intent);// 执行Intent,打开相应的Activityfinish();}});}private void showinfo() {String[] strInfos = null;ArrayAdapter<String> arrayAdapter = null;AddMemo info = new AddMemo(ShowInfo.this);// 创建AddMemo对象// 获取所有便签信息,并存储到List泛型集合中List<Tb_flag> listFlags = info.getScrollData(0,(int) info.getCount());strInfos = new String[listFlags.size()];// 设置字符串数组的长度int n = 0;// 定义一个开始标识for (Tb_flag tb_flag : listFlags) {// 遍历List泛型集合// 将便签相关信息组合成一个字符串,存储到字符串数组的相应位置strInfos[n] = tb_flag.getid() + "." + tb_flag.getFlag();if (strInfos[n].length() > 15)// 判断便签信息的长度是否大于15strInfos[n] = strInfos[n].substring(0, 15) + "……";// 将位置大于15之后的字符串用……代替n++;// 标识加1}// 使用字符串数组初始化ArrayAdapter对象arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, strInfos);lvinfo.setAdapter(arrayAdapter);// 为ListView列表设置数据源}protected void onRestart() {super.onRestart();}}
4.FlagManage类:
package com.example.memorandum;import com.example.memorandum.FlagManage;import com.example.memorandum.ShowInfo;import java.util.List;import com.example.DB.AddMemo;import com.example.model.Tb_flag;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.Toast;public class FlagManage extends Activity {EditText txtFlag;// 创建EditText对象Button btnEdit, btnDel;// 创建两个Button对象String strid;// 创建字符串,表示便签的id@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.flagmanage);// 设置布局文件txtFlag = (EditText) findViewById(R.id.txtFlagManage);// 获取便签文本框btnEdit = (Button) findViewById(R.id.btnFlagManageEdit);// 获取修改按钮btnDel = (Button) findViewById(R.id.btnFlagManageDelete);// 获取删除按钮Intent intent = getIntent();// 创建Intent对象Bundle bundle = intent.getExtras();// 获取便签idstrid = bundle.getString(ShowInfo.FLAG);// 将便签id转换为字符串final AddMemo info = new AddMemo(FlagManage.this);txtFlag.setText(info.find(Integer.parseInt(strid)).getFlag());// 根据便签id查找便签信息,并显示在文本框中btnEdit.setOnClickListener(new OnClickListener() {// 为修改按钮设置监听事件@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubTb_flag tb_flag = new Tb_flag();// 创建Tb_flag对象tb_flag.setid(Integer.parseInt(strid));// 设置便签idtb_flag.setFlag(txtFlag.getText().toString());// 设置便签值info.update(tb_flag);// 修改便签信息// 弹出信息提示Toast.makeText(FlagManage.this, "便签修改成功!",Toast.LENGTH_SHORT).show();finish();}});btnDel.setOnClickListener(new OnClickListener() {// 为删除按钮设置监听事件@Overridepublic void onClick(View arg0) {int id = Integer.parseInt(strid);info.detele(id);// 根据指定的id删除便签信息Toast.makeText(FlagManage.this, "便签删除成功!",Toast.LENGTH_SHORT).show();//下面代码想在删除一个便签之后修改后面的便签id号,但是失败了,原因待查。/*List<Tb_flag> listFlags = info.getScrollData(0,(int) info.getCount());int i = 1, tag = 0;for (Tb_flag tb_flag : listFlags) {if (tb_flag.getid() != i) {tb_flag.setid(i);info.update(tb_flag);// 修改便签信息}i++;}*/finish();}});}}
Layout:
activity_main.xml
<RelativeLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.example.memorandum.MainActivity" ><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignBaseline="@+id/button1"android:layout_alignBottom="@+id/button1"android:layout_alignParentLeft="true"android:layout_marginLeft="25dp"android:text="查看备忘录" /><ImageViewandroid:id="@+id/imageView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_above="@+id/button1"android:layout_alignLeft="@+id/button2"android:layout_marginBottom="36dp"android:src="@drawable/image" /><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignRight="@+id/imageView1"android:layout_marginBottom="39dp"android:text="添加备忘录" /></RelativeLayout>
editmemo.xml
<LinearLayout xmlns:android="/apk/res/android"android:id="@+id/itemflag"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:gravity="center_horizontal"android:text="新增便签(400字以内)"android:textSize="25sp"android:textStyle="bold" /><EditTextandroid:id="@+id/txt"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="top"android:lines="10" /><RelativeLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:padding="10dp" ><Buttonandroid:id="@+id/cancel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_marginLeft="10dp"android:text="清空" /><Buttonandroid:id="@+id/save"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toLeftOf="@id/cancel"android:text="保存" /></RelativeLayout></LinearLayout>
showinfo.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><ListView android:id="@+id/lvinfo" android:layout_width="match_parent" android:layout_height="match_parent"android:scrollbarAlwaysDrawVerticalTrack="true"></ListView></LinearLayout>
flagmanage.xml
<LinearLayout xmlns:android="/apk/res/android"android:id="@+id/flagmanage"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><LinearLayout android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_weight="3"><TextView android:layout_width="wrap_content"android:layout_gravity="center"android:gravity="center_horizontal"android:text="修改便签(400字以内)"android:textSize="25sp"android:textStyle="bold" android:layout_height="wrap_content"/></LinearLayout><LinearLayout android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_weight="1"><RelativeLayout android:layout_width="fill_parent"android:layout_height="fill_parent"android:padding="5dp"><EditText android:id="@+id/txtFlagManage"android:layout_width="350dp"android:layout_height="400dp"android:gravity="top"android:singleLine="false"/></RelativeLayout></LinearLayout><LinearLayout android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_weight="3"><RelativeLayout android:layout_width="fill_parent"android:layout_height="fill_parent"android:padding="10dp"><Buttonandroid:id="@+id/btnFlagManageDelete"android:layout_width="80dp"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_marginLeft="10dp"android:text="删除"/><Button android:id="@+id/btnFlagManageEdit"android:layout_width="80dp"android:layout_height="wrap_content"android:layout_toLeftOf="@id/btnFlagManageDelete"android:text="修改" android:maxLength="200"/></RelativeLayout></LinearLayout></LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="/apk/res/android"package="com.example.memorandum"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="19"android:targetSdkVersion="19" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name=".MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activityandroid:name=".EditMemo"android:label="编辑备忘录" ></activity><activityandroid:name=".ShowInfo"android:label="备忘录目录" ></activity><activityandroid:name=".FlagManage"android:label="修改便签"> </activity></application></manifest>
就到这吧,基本功能就这些,因为还要准备考研,也没什么时间去实现更好的功能了。
期末快乐!