我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=19puc3fpv9pnr
前言
本文的内容主要是解析日记 APP 的制作流程,以及代码的具体实现,若有什么不足之处,还请提出建议,附上这个 APP 的 Github 地址 WatermelonDiaryNew 欢迎大家 star 和 fork.
本文的主要内容
- 日记的展示
- 悬浮菜单的实现
- 日记增删改的实现
先来一波日记的展示吧,虽然内容比较简单,但还是设计的非常用心的,因此这款 APP 还是非常简洁和优雅的
一、日记的展示
1、伪日记的处理
可以看到刚开始进入主页面,显示的是 今天,你什么都没写下...
这个伪日记,其实只要是某一天没有写日记的话,界面最上面显示的就是这个,当我们写了日记之后,这个伪日记便会消失,讲道理一开始实现这个还真花了我不少心思,本来的思路是将这个伪日记作为 RecyclerView 的第一个Item,如果当天有写日记了,就将它隐藏起来,等到了第二天再重新显示,但是感觉实现起来会很麻烦,后来想了想只要将这个伪日记,直接写在主页面的布局中,到时候如果检索到数据库里面,有某篇日记的日期跟当天的日期一致的话,就将伪日记从布局中 remove 掉就行了
if (cursor.moveToFirst()) {
do {
String date = cursor.getString(cursor.getColumnIndex("date"));
// 这是我自己写的一个获取当天日期的一个方法
String dateSystem = GetDate.getDate().toString();
if (date.equals(dateSystem)) {
mMainLlMain.removeView(mItemFirst);
break;
}
} while (cursor.moveToNext());
}
2、使用 RecyclerView 展示日记
因为我是打算以事件线的形式来展示我们所写的日记,因此使用 RecyclerView 也算是比较合适的了。这里附上一篇将 RecyclerView 讲的很不错的博客 RecyclerView 使用详解(一)
要想使用 RecyclerView来实现我们想要实现的效果,先让我们建立一个item_rv_diary
作为 RecyclerView 的子布局
布局还是比较简单的,比较难实现的应该是左边的那条竖线,其实,一开始并没有什么思路,因为
shape 中的 line 只能画横线,而画不了竖线,最后在 Google 的帮助下,终于找到了实现这个竖线的思路,我是这样处理的,定义一个 layer-list 设置在 TextView 中,将 TextView 的右边框进行描绘
-
-
写好子布局之后,再让我们来实现 RecyclerView 的 Adapter,首先定义了一个 DiaryViewHolder 继承自 RecyclerView.ViewHolder,传入一个保存日记信息的 List,然后通过 onCreateViewHolder
来创建布局,通过 onBindViewHolder
将数据绑定到对应的 Item 上面,这里我使用了 EventBus 通过点击编辑按钮打开修改日记的界面, EventBus 是一款针对Android优化的发布/订阅事件总线,使用也是非常简单的,可以当作一个轻量级的BroadCastReceiver 来使用,有兴趣可以看看这篇文章 EventBus 使用详解(一)——初步使用 EventBus
public class DiaryAdapter extends RecyclerView.Adapter {
private Context mContext;
private LayoutInflater mLayoutInflater;
private List mDiaryBeanList;
public DiaryAdapter(Context context, List mDiaryBeanList){
mContext = context;
this.mLayoutInflater = LayoutInflater.from(context);
this.mDiaryBeanList = mDiaryBeanList;
}
@Override
public DiaryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new DiaryViewHolder(mLayoutInflater.inflate(R.layout.item_rv_diary, parent, false));
}
@Override
public void onBindViewHolder(final DiaryViewHolder holder, final int position) {
String dateSystem = GetDate.getDate().toString();
/**
* 如果该日记是当天写的,则将日期左边的圆圈设置成橙色的
*/
if(mDiaryBeanList.get(position).getDate().equals(dateSystem)){
holder.mIvCircle.setImageResource(R.drawable.circle_orange);
}
holder.mTvDate.setText(mDiaryBeanList.get(position).getDate());
holder.mTvTitle.setText(mDiaryBeanList.get(position).getTitle());
holder.mTvContent.setText(mContext.getString(R.string.spaces) + mDiaryBeanList.get(position).getContent());
holder.mIvEdit.setVisibility(View.INVISIBLE);
/**
* 当点击日记的内容时候,则显示出编辑按钮
*/
holder.mLl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (holder.mIvEdit.getVisibility() == View.INVISIBLE) {
holder.mIvEdit.setVisibility(View.VISIBLE);
}else {
holder.mIvEdit.setVisibility(View.INVISIBLE);
}
}
});
/**
* 使用 EventBus 来打开修改日记的界面,事件接收函数载 MainActivity 中
*/
holder.mIvEdit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new StartUpdateDiaryEvent(position));
}
});
}
@Override
public int getItemCount() {
return mDiaryBeanList.size();
}
static class DiaryViewHolder extends RecyclerView.ViewHolder{
TextView mTvDate;
TextView mTvTitle;
TextView mTvContent;
ImageView mIvEdit;
LinearLayout mLlTitle;
LinearLayout mLl;
ImageView mIvCircle;
LinearLayout mLlControl;
RelativeLayout mRlEdit;
DiaryViewHolder(View view){
super(view);
mIvCircle = (ImageView) view.findViewById(R.id.main_iv_circle);
mTvDate = (TextView) view.findViewById(R.id.main_tv_date);
mTvTitle = (TextView) view.findViewById(R.id.main_tv_title);
mTvContent = (TextView) view.findViewById(R.id.main_tv_content);
mIvEdit = (ImageView) view.findViewById(R.id.main_iv_edit);
mLlTitle = (LinearLayout) view.findViewById(R.id.main_ll_title);
mLl = (LinearLayout) view.findViewById(R.id.item_ll);
mLlControl = (LinearLayout) view.findViewById(R.id.item_ll_control);
mRlEdit = (RelativeLayout) view.findViewById(R.id.item_rl_edit);
}
}
}
最后在 MainActivity 中将 RecyclerView 进行处理就行了
mMainRvShowDiary.setLayoutManager(new LinearLayoutManager(this));
mMainRvShowDiary.setAdapter(new DiaryAdapter(this, mDiaryBeanList));
二、悬浮菜单的实现
悬浮菜单看起来逼格还是挺高的, 而且观赏性也算是比较高,我是从 Github 找的一个库,来实现这个悬浮菜单的,不得不说,搞这个悬浮菜单真的花了我不少时间, 有些库要么不能调节菜单的大小,要么不能调节菜单图案,找了好久才找到这个让我比较满意的库FloatingActionButton
虽然逼格挺高的,但使用起来却是相当的方便,先在build.grade中添加
dependencies {
compile 'cc.trity.floatingactionbutton:library:1.0.0'
}
然后在布局中设置我们想要的颜色和图案,最后在 Activity 中进行悬浮按钮点击事件的处理就行了
三、日记增删改的实现
日记的信息,我是使用 Android 自带的 SQLite 数据库进行保存的,做法也是比较简单的,这里附上一篇讲解 SQLite 的博客 Android中SQLite应用详解,先建立一个 DiaryDatabaseHelper 作为我们进行数据库操作的帮助类,因为日记的内容比较简单, 因此,我只建了一张表
public class DiaryDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_DIARY = "create table Diary("
+ "id integer primary key autoincrement, "
+ "date text, "
+ "title text, "
+ "content text)";
private Context mContext;
public DiaryDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version){
super(context, name, factory, version);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_DIARY);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists Diary");
onCreate(db);
}
}
1、日记的添加
获取添加日记界面中日记的日期、标题以及具体的内容,然后将这些信息添加到数据库中
String date = GetDate.getDate().toString();
String title = mAddDiaryEtTitle.getText().toString() + "";
String content = mAddDiaryEtContent.getText().toString() + "";
if (!title.equals("") || !content.equals("")) {
SQLiteDatabase db = mHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("date", date);
values.put("title", title);
values.put("content", content);
db.insert("Diary", null, values);
values.clear();
2、日记的删除
在这里我为了防止日记被误删,就做了一个对话框,当点击删除按钮的时候,便会跳出这个对话框询问用户是否真的要删除该日记
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("确定要删除该日记吗?").setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String title = mUpdateDiaryEtTitle.getText().toString();
SQLiteDatabase dbDelete = mHelper.getWritableDatabase();
dbDelete.delete("Diary", "title = ?", new String[]{title});
MainActivity.startActivity(UpdateDiaryActivity.this);
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
}).show();
3、日记的修改
SQLiteDatabase dbUpdate = mHelper.getWritableDatabase();
ContentValues valuesUpdate = new ContentValues();
String title = mUpdateDiaryEtTitle.getText().toString();
String content = mUpdateDiaryEtContent.getText().toString();
valuesUpdate.put("title", title);
valuesUpdate.put("content", content);
dbUpdate.update("Diary", valuesUpdate, "title = ?", new String[]{title});
dbUpdate.update("Diary", valuesUpdate, "content = ?", new String[]{content});
以上便是我写这个 APP 的具体实现思路,以及踩过的一些坑,记录下来,给大家看看,最后附上这个 APP 的 Github 地址 WatermelonDiaryNew 欢迎大家 star 和 fork,如果有什么想法或者建议,非常欢迎大家来讨论
猜你喜欢
- 手把手教你从零开始做一个好看的 APP
- Android 能让你少走弯路的干货整理
- Android 撸起袖子,自己封装 DialogFragment