一款类备忘录形式的记事本:写诗APP。
首先看一下目录结构如下:
演示效果如图如下:
做这个APP的目的完全是为了练手,目前也已经在线上跑着,最近也没时间优化,可是在这个过程中,我发现,实现的效果还不错。所以就接着做了。下面进行分步讲解:
源码地址:
链接:http://pan.baidu.com/s/1mipzdm4 密码:49d1
- 1、首先用到一定要用到Android Studio,当然了,做这个小案例,你不需要导入任何的包,你只需要知道,Android Studio导包方式与ADT不同就好了。
- 2、Android用到的是自己的数据库,叫做SQLite,总结下来,简单,好用,高效。
- 3、当然了,在做这个项目之前,你先要知道自己在做什么,那就是数据库的增删改查,写诗嘛!顾名思义,你要有Title,有Content,id主要是为了在做删除和修改时有区分,在这里一定要注意一下。所以你要写一个实体类在vo目录下:“Poem”类中的代码如下:
package com.example.mypoem.vo;
/**
* Created by Dujiang0311 on 2017/1/9.
*/
public class Poem {
private int id;
private String title;
private String content;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
- 4、实体类写好了,就是数据库的工具类的书写了,在这里你要完成建表,以及新增数据列的操作,“SQLIiteHelper”具体实现代码如下:
package com.example.mypoem.sqlite;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by Dujiang0311 on 2017/2/9.
*/
public class SQLiteHelper extends SQLiteOpenHelper {
/*SQLiteHelper的四个参数,上下文,数据库名字,null,版本号(任意数字)*/
public SQLiteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
/*上面那个太过复杂,所以需要重载一个简单的方法:通过构造方法,完成数据库的创建*/
public SQLiteHelper(Context context){
super(context,"mydb",null,1);
}
//当sqliteOpenHelper中新添加了execSQL语句的时候一定要注意,将之前已经运行的MyWealth进行卸载
/*通过OnCreate方法,实现数据表的创建*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table poem (id integer primary key autoincrement,title varchar2(20),content varchar2(50))");
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
- 5、接下来数据的操作类了,也就是所谓的dao层,里面包含了对于数据库的增删改查。“FileDao”代码如下:
package com.example.mypoem.dao;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.example.mypoem.sqlite.SQLiteHelper;
import com.example.mypoem.vo.Poem;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Dujiang0311 on 2017/2/9.
*/
public class FileDao {
private SQLiteHelper sqLiteHelper;
private SQLiteDatabase db;
public FileDao(Context context) {
sqLiteHelper = new SQLiteHelper(context);
}
//新增我的诗篇删除功能
public int poemDelete(Integer id) {
db = sqLiteHelper.getWritableDatabase();
return db.delete("poem", "id = ?", new String[]{String.valueOf(id)});
}
//新增我的诗篇修改功能
public int poemUpdate(int id, String title, String content) {
db = sqLiteHelper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("id",id);
cv.put("title", title);
cv.put("content", content);
return db.update("poem", cv, "id = ?", new String[]{String.valueOf(id)});
}
//新增我的诗篇查询功能
public List<Poem> myPoems() {
List<Poem> list = new ArrayList<Poem>();
db = sqLiteHelper.getReadableDatabase();
Cursor cursor = db.query("poem", new String[]{"id","title", "content"}, null, null, null, null, null);
while (cursor.moveToNext()) {
Poem poem = new Poem();
poem.setId(cursor.getInt(0));
poem.setTitle(cursor.getString(1));
poem.setContent(cursor.getString(2));
list.add(poem);
}
return list;
}
//新增我的诗篇新增功能
public Long addPoem(Poem poem){
/*由于当前需要实现的是添加功能,所以我们需要调用getWritableDatabase()*/
db = sqLiteHelper.getWritableDatabase();
/*创建ContentValues对象*/
ContentValues cv = new ContentValues();
cv.put("title", poem.getTitle());
cv.put("content",poem.getContent());
return db.insert("poem",null,cv);
}
}
- 6、当然,有的人代码潦草,随便把它写在该用的地方,也是没问题的,不过小项目还好,大项目还是规矩点的好。
- 7、接下来就是UI的实现了,MainActivity主要是个载体,用来向AddPoemActivity和MyPoemActivity用Intent跳转的。其中MainActivity中代码如下:
package com.example.mypoem;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private ImageView iv_add_poem;
private ImageView iv_select_poem;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_add_poem = (ImageView) findViewById(R.id.iv_add_poem);
iv_add_poem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intentIn = new Intent(MainActivity.this,AddPoemActivity.class);
startActivity(intentIn);
}
});
iv_select_poem = (ImageView) findViewById(R.id.iv_select_poem);
iv_select_poem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intentMyPoem = new Intent(MainActivity.this,MyPoemActivity.class);
startActivity(intentMyPoem);
}
});
}
}
- 8、下面是诗篇的新增功能,通过调用FileDao中的addPoem的方法实现数据的保存。AddPoemActivity代码如下:
package com.example.mypoem;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.mypoem.dao.FileDao;
import com.example.mypoem.vo.Poem;
public class AddPoemActivity extends AppCompatActivity {
private EditText et_title, et_content;
private Poem poem;
private Button btn_save, btn_cacel;
private FileDao fileDao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_poem);
fileDao = new FileDao(this);
//获取控件
et_title = (EditText) findViewById(R.id.et_title);
et_content = (EditText) findViewById(R.id.et_content);
btn_save = (Button) findViewById(R.id.btn_save);
btn_cacel = (Button) findViewById(R.id.btn_cancel);
btn_save.setOnClickListener(new OnClick());
btn_cacel.setOnClickListener(new OnClick());
}
private class OnClick implements View.OnClickListener {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_save:
Poem poem = new Poem();
poem.setTitle(et_title.getText().toString().trim());
poem.setContent(et_content.getText().toString().trim());
if (fileDao.addPoem(poem) < 0) {
Toast.makeText(AddPoemActivity.this, "没有成功添加...", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(AddPoemActivity.this, "已经成功添加...", Toast.LENGTH_LONG).show();
Intent intent = new Intent(AddPoemActivity.this, MainActivity.class);
startActivity(intent);
}
break;
case R.id.btn_cancel:
finish();
break;
}
}
}
}
- 9、诗篇的查询功能的实现,在这里核心操作同样是调用封装好的方法myPoem() ,在这里为了显示多条数据,需要用到适配器SimpleAdapter,这里我没有封装,因为只在着一个地方用到了,不至于封装。但是在这里强调一下,适配器最好单独写一个类。目前笔者现在遇到的,ListView和GridView都需要适配器。,MyPoemActivity中的代码如下:
package com.example.mypoem;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import com.example.mypoem.dao.FileDao;
import com.example.mypoem.vo.Poem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MyPoemActivity extends AppCompatActivity {
private ListView lv_my_poem;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_poem);
lv_my_poem = (ListView) findViewById(R.id.lv_my_poem);
FileDao dao = new FileDao(this);
List<Poem> list0 = dao.myPoems();
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
final SimpleAdapter adapter ;
for (Poem poem :list0){
Map<String, Object> map = new HashMap<String, Object>();
map.put("id",poem.getId());
map.put("title",poem.getTitle());
map.put("content",poem.getContent());
list.add(map);
}
adapter = new SimpleAdapter(this,list,R.layout.activity_my_poem_lv,
new String[]{"id","title","content"},
new int[]{R.id.tv_my_poem_lv_id,R.id.tv_my_poem_lv_title,R.id.tv_my_poem_lv_content});
lv_my_poem.setAdapter(adapter);
lv_my_poem.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id1) {
Map<String,Object> map = (Map<String, Object>) adapter.getItem(position);
Integer id = Integer.valueOf(map.get("id").toString());
String title = map.get("title").toString();
String content = map.get("content").toString();
Intent intent = new Intent(MyPoemActivity.this,ManageMyPoemActivity.class);
intent.putExtra("id",id);
intent.putExtra("title",title);
intent.putExtra("content",content);
startActivity(intent);
}
});
}
}
- 10、修改和删除,笔者写到了一个Activity,都是调用封装好的方法操作。但是注意一点,删除时按照id删除,如果是按照标题或内容删除,很容易把有着同样标题诗篇删除,这也是我在后期调试的时候发现的,所以按照id删除,不会删错。修改那里,在MyPoemActivity和ManageMyPoemActivity之间,需要用到Intent传递一个Key和Value。ManageMyPoemActivity的代码如下:
package com.example.mypoem;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.mypoem.dao.FileDao;
public class ManageMyPoemActivity extends AppCompatActivity {
//声明控件
private EditText et_manage_title,et_manage_content,et_manage_id;
private Button btn_delete, btn_update, btn_cancel;
private FileDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_my_poem);
//获取控件
et_manage_title = (EditText) findViewById(R.id.et_manage_title);
et_manage_content = (EditText) findViewById(R.id.et_manage_content);
et_manage_id = (EditText) findViewById(R.id.et_manage_id);
dao = new FileDao(this);
btn_cancel = (Button) findViewById(R.id.btn_manage_cancel);
btn_delete = (Button) findViewById(R.id.btn_manage_delete);
btn_update = (Button) findViewById(R.id.btn_manage_update);
//接收从前面传递过来的值
//接收上面传递过来的值
Intent intent = getIntent();
et_manage_id.setId(intent.getIntExtra("id",1));
et_manage_title.setText(intent.getStringExtra("title"));
et_manage_content.setText(intent.getStringExtra("content"));
//点击“取消”按钮
btn_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
btn_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//创建一个对话框
AlertDialog.Builder builder = new AlertDialog.Builder(ManageMyPoemActivity.this);
builder.setTitle("删除Poem");
builder.setMessage("你确定要删除你的灵感吗?");
builder.setPositiveButton("删除", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (dao.poemDelete(Integer.valueOf(et_manage_id.getId())) > 0) {
Toast.makeText(ManageMyPoemActivity.this, "删除成功!!!", Toast.LENGTH_SHORT).show();
Intent intent2 = new Intent(ManageMyPoemActivity.this, MainActivity.class);
startActivity(intent2);
} else {
Toast.makeText(ManageMyPoemActivity.this, "删除失败!!!", Toast.LENGTH_SHORT).show();
}
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.create().show();
}
});
btn_update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//第三步、注意数据顺序不能错位
//String time, String type, String address, String other, Double money
if (dao.poemUpdate(et_manage_id.getId(),
et_manage_title.getText().toString(),
et_manage_content.getText().toString())> 0) {
Toast.makeText(ManageMyPoemActivity.this, "修改成功!!!", Toast.LENGTH_SHORT).show();
Intent intent1 = new Intent(ManageMyPoemActivity.this, MainActivity.class);
startActivity(intent1);
} else {
Toast.makeText(ManageMyPoemActivity.this, "修改失败", Toast.LENGTH_SHORT).show();
}
}
});
}
}
- 11、闪屏页面的话,最大的特色就是倒计时功能,实现代码如下:
package com.example.mypoem;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.TextView;
public class SplashActivity extends AppCompatActivity {
//倒计时控件声明
private TextView textView ;
private int count = 5 ;
private Animation animation ;
// private Button btnGoLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
textView = (TextView) findViewById(R.id.tv_adv);
//先声明Handler,再书写下面的延迟。
handler.sendEmptyMessageDelayed(0,1000) ;
animation= AnimationUtils.loadAnimation(this,R.anim.animation_text);
new Handler().sendEmptyMessageDelayed(0,1000);
//5秒钟自动进入登录界面
/*new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent();
intent.setClass(FirstActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
}, 3000);*/
/* this.btnGoLogin = (Button) findViewById(R.id.btn_go_login);
this.btnGoLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
// 设置跳转参数
intent.setClass(SplashActivity.this, MainActivity.class);
// 进行跳转
startActivity(intent);
// 销毁当前Activity
finish();
}
});*/
/* @Override
public void onClick(View v) {
// String msg = "你好呀";
// 跳转到主界面
// 实例化意图
Intent intent = new Intent();
// 设置跳转参数
intent.setClass(FirstActivity.this, LoginActivity.class);
// 放置传递的数据
// intent.putExtra("message",msg);
// 进行跳转
startActivity(intent);
// 销毁当前Activity
finish();
}
});*/
}
private int getCount(){
count-- ;
if (count == 0){
Intent intent = new Intent();
intent.setClass(this, MainActivity.class);
startActivity(intent);
finish();
}
return count;
}
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg){
if (msg.what == 0){
textView.setText(getCount()+"");
handler.sendEmptyMessageDelayed(0,1000) ;
animation.reset();
textView.startAnimation(animation);
}
}
};
}
- 12、布局文件不太难,大家就在源码里面看好了,指得注意的是圆形按键的实现,是调用了btn_circle.xml文件实现,在drawable目录下。
- 13、大家如果想看APP的具体实现效果,可以去下载,apk地址如下:http://shouji.baidu.com/software/10937287.html