Kotlin开发安卓APP笔记实战-写个简易记事本(逻辑)

元旦前事情不少,拖到现在才写,有点尴尬。写了代码才知道前一篇写的笔记有些不正确,在这一篇笔记慢慢指出来,也不更新前一篇笔记了。学习就是这样一个发现错误并改正错误的过程。
先看最终效果图
这里写图片描述
这里写图片描述
由于工作关系,RecyclerView没有画分割线,如果需要的话可以参考郭神的Android RecyclerView 使用完全解析 体验艺术般的控件
用到的返回和保存按钮图标在图标查询网下载

创建一个DbHelper类连接数据库并初始化数据库结构

package cn.bestmk.noteimport android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper/*** Created by 醉猫 on 2017/12/26.*/

class DBHelper(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {override fun onCreate(sqLiteDatabase: SQLiteDatabase) {// create table if not exists note(ID INT PRIMARY KEY NOT NULL,createtime TIMESTAMP NOT NULL,chagetime TIMESTAMP,title CHAR(255) NOT NULL,content TEXT NOT NULL);val sql = "create table if not exists $TABLE_NAME(ID INTEGER PRIMARY KEY AUTOINCREMENT,createtime TIMESTAMP NOT NULL,chagetime TIMESTAMP,title CHAR(255) NOT NULL,content TEXT NOT NULL);"sqLiteDatabase.execSQL(sql)}override fun onUpgrade(sqLiteDatabase: SQLiteDatabase, oldVersion: Int, newVersion: Int) {val sql = "DROP TABLE IF EXISTS " + TABLE_NAMEsqLiteDatabase.execSQL(sql)onCreate(sqLiteDatabase)}//声明静态变量companion object {private val DB_VERSION = 1private val DB_NAME = "note.db"private val TABLE_NAME = "note"}
}

从代码中看出这里的sql语句和上一篇笔记(ID INT PRIMARY KEY NOT NULL)并不一致,这里是ID INTEGER PRIMARY KEY AUTOINCREMENT,前面的语句是设置ID为主键并且不能为空,后面是ID为主键,并且自动增长,越是细节的地方越容易出错。

创建一个NoteBean保存笔记数据,可以理解为kotlin的Javabean

package cn.bestmk.note/*** Created by 醉猫 on 2017/12/29.*/class NoteBean {var id: Int = 0var createTime: Long = 0var chageTime: Long = 0var title: String? = nullvar content: String? = null
}

创建一个NoteManager管理笔记(增删改查)

package cn.bestmk.noteimport android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.util.Log/*** Created by 醉猫 on 2017/12/27.*/
class NoteManager(contxt: Context){val db:SQLiteDatabaseinit {db= DBHelper(contxt).writableDatabase}/*** 添加一条笔记*/fun addNote(title:String,content:String){var nowtime=System.currentTimeMillis()var sql="insert into note (createtime, chagetime, title,content) values ($nowtime,$nowtime,'$title','$content')"db.execSQL(sql)}/*** 删除一条笔记*/fun deleteNote(id:Int){var sql="delete from note where ID=$id"db.execSQL(sql)}/*** 修改一条笔记*/fun chageNote(id:Int,title: String,content: String){var nowtime=System.currentTimeMillis()var sql="update note set title='$title',content='$content',chagetime='$nowtime' where ID=$id"db.execSQL(sql)}/*** 查询笔记*/fun queryNote(id: Int):NoteBean{val bean=NoteBean()var sql="select * from note where ID=$id"var cursor=db.rawQuery(sql,null) //执行查询语句if (cursor.moveToNext()){bean.id=cursor.getInt(0) //获取idbean.createTime=cursor.getLong(1) //获取创建时间bean.chageTime=cursor.getLong(2)//获取上次修改时间bean.title=cursor.getString(3)//获取标题bean.content=cursor.getString(4)//获取内容}return bean}/*** 查询所有笔记*/fun queryNotes():ArrayList{val list: ArrayList = arrayListOf()//创建集合var sql="select * from note" //构建查询语句var cursor=db.rawQuery(sql,null) //执行查询语句while (cursor.moveToNext()){ //设置循环语句val bean=NoteBean()bean.id=cursor.getInt(0) //获取idbean.createTime=cursor.getLong(1) //获取创建时间bean.chageTime=cursor.getLong(2)//获取上次修改时间bean.title=cursor.getString(3)//获取标题bean.content=cursor.getString(4)//获取内容list.add(bean) //添加一条笔记到集合}return list}
}

注释写得比较详细,就不再多说

为RecyclerView创建一个适配器NoteAdapter.kt

package cn.bestmk.noteimport android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.support.v7.widget.RecyclerView
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import cn.bestmk.note.NoteAdapter.ViewHolderimport org.w3c.dom.Text
import java.text.SimpleDateFormat
import java.util.*/*** Created by 醉猫 on 2017/12/29.*/class NoteAdapter(var context:Context,var mData: ArrayList?) : RecyclerView.Adapter.ViewHolder>() {fun updateData(data: ArrayList) {this.mData = datanotifyDataSetChanged()}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {// 实例化展示的viewval v = LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false)// 实例化viewholderreturn ViewHolder(v)}override fun onBindViewHolder(holder: ViewHolder, position: Int) {var sdFormat= SimpleDateFormat("yyyy-MM-dd HH:mm:ss")//时间转换器// 绑定数据holder.tv_title.setText(mData!![position].title)holder.tv_createtime.setText("创建时间:"+sdFormat.format(Date(mData!![position].createTime)))//显示转换后的创建时间holder.tv_chagetime.setText("修改时间:"+sdFormat.format(Date(mData!![position].chageTime)))//显示转换后的创建时间holder.itemView.setOnClickListener { view ->val intent=Intent(context,EditActivity::class.java)intent.putExtra("ID", mData!![position].id) //向EditActivity传递IDcontext.startActivity(intent)}holder.itemView.setOnLongClickListener(object :View.OnLongClickListener{override fun onLongClick(p0: View?): Boolean {AlertDialog.Builder(context).setTitle("骚气的提示") .setMessage("是否要删除本条笔记").setPositiveButton("是",object :DialogInterface.OnClickListener{override fun onClick(p0: DialogInterface?, p1: Int) {NoteManager(context).deleteNote(position)//删除笔记mData!!.removeAt(position)//更新集合数据updateData(mData!!)//刷新页面数据Toast.makeText(context,"删除成功",Toast.LENGTH_LONG).show()}}).setNegativeButton("取消",null).show()return false}})}override fun getItemCount(): Int {return if (mData == null) 0 else mData!!.size}class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {internal var tv_title: TextViewinternal var tv_createtime: TextViewinternal var tv_chagetime: TextViewinit {tv_title = itemView.findViewById(R.id.tv_title)tv_createtime = itemView.findViewById(R.id.tv_createtime)tv_chagetime = itemView.findViewById(R.id.tv_chagetime)}}
}

MainActivity.kt

package cn.bestmk.noteimport android.content.Intent
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.widget.AdapterViewimport kotlinx.android.synthetic.main.activity_main.*class MainActivity : AppCompatActivity() {lateinit var nm: NoteManager //声明笔记管理器override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)setSupportActionBar(toolbar)nm = NoteManager(this)//初始化笔记管理器rv.layoutManager = LinearLayoutManager(this) as RecyclerView.LayoutManager?//设置布局管理器//右下悬浮按钮事件fab.setOnClickListener { view ->var intent = Intent(this@MainActivity, EditActivity::class.java)startActivity(intent)}}//在onStart中设置适配器,每次显示MainActivity都会更新一次数据override fun onStart() {rv.adapter = NoteAdapter(this, nm.queryNotes())//设置适配器super.onStart()}
}

EditActivity.kt

package cn.bestmk.noteimport android.app.AlertDialog
import android.content.DialogInterface
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.KeyEvent
import android.view.Menu
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_edit.*class EditActivity : AppCompatActivity() {lateinit var nm: NoteManagervar ID: Int = -1 //IDvar ischage = falseoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_edit)setSupportActionBar(toolbar)//为当前的Activity设置标题栏nm = NoteManager(this)//获取笔记管理器实例title = ""ID = intent.getIntExtra("ID", -1)//获取ID,设置默认值为-1,也就是没有传递参数会传-1if (ID >= 0) {//如果id大于或等于0,就说明用户是点击item进入EditActivity,是修改或查看笔记,否则是新增笔记var bean = nm.queryNote(ID)//查询这条ID的内容ettitle.setText(bean.title)//显示标题etcontent.setText(bean.content)//显示内容}//为save按钮绑定事件toolbar.setOnMenuItemClickListener {if (ettitle.text.length < 0) {//判断标题是否为空Toast.makeText(this@EditActivity, "标题不可为空", Toast.LENGTH_LONG).show()return@setOnMenuItemClickListener false}if (etcontent.text.length < 0) {//判断内容是否为空Toast.makeText(this@EditActivity, "内容不可为空", Toast.LENGTH_LONG).show()return@setOnMenuItemClickListener false}save()finish()//关闭当前页面false}back.setOnClickListener {back()}//监听标题改变事件ettitle.addTextChangedListener(object : TextWatcher {override fun afterTextChanged(p0: Editable?) {}override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {ischage = true //将笔记改变状态设置成true}})//监听内容改变事件etcontent.addTextChangedListener(object : TextWatcher {override fun afterTextChanged(p0: Editable?) {}override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {ischage = true //将笔记改变状态设置成true}})}//保存笔记函数fun save(){if (ID >= 0) {//修改nm.chageNote(ID, ettitle.text.toString(), etcontent.text.toString())//修改这条笔记Toast.makeText(this@EditActivity, "修改成功", Toast.LENGTH_LONG)} else {//新增nm.addNote(ettitle.text.toString(), etcontent.text.toString())//数据库新增一条笔记Toast.makeText(this@EditActivity, "保存成功", Toast.LENGTH_LONG).show()}}//返回函数fun back(){//如果笔记被修改就弹出窗口提示用户笔记被修改,询问用户是否要保存/修改笔记if (ischage){AlertDialog.Builder(this).setTitle("骚气的提示").setMessage("您的笔记尚未保存,是否保存?").setPositiveButton("保存",object :DialogInterface.OnClickListener{override fun onClick(p0: DialogInterface?, p1: Int) {save()finish()}}).setNegativeButton("不保存",object :DialogInterface.OnClickListener{override fun onClick(p0: DialogInterface?, p1: Int) {finish()}}).setNeutralButton("取消",null).show()}else{finish()}}// 为toolbar创建Menuoverride fun onCreateOptionsMenu(menu: Menu?): Boolean {getMenuInflater().inflate(R.menu.menu, menu);return true;}//拦截返回键override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {if (keyCode==KeyEvent.KEYCODE_BACK){back()return true}return super.onKeyDown(keyCode, event)}
}

xml相对比前一篇笔记有一些小的调整,就不贴出来了
源码下载地址我会放在猫客技术论坛同名贴子下面,需要的可以下载下来看看


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部