Android MVVM框架使用(十一)(功能开发)记事本(1)

@Override

public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override

public void onTextChanged(CharSequence s, int start, int before, int count) {

}

@Override

public void afterTextChanged(Editable s) {

if (s.length() > 0) {

binding.ivOk.setVisibility(View.VISIBLE);

} else {

if (binding.etTitle.getText().length() == 0 && binding.etContent.getText().length() == 0 ){

binding.ivOk.setVisibility(View.GONE);

}

}

}

});

}

/**

  • 显示键盘

*/

public void showInput() {

binding.etContent.requestFocus();

inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);

inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

}

/**

  • 隐藏键盘

*/

public void dismiss() {

if (inputMethodManager != null) {

inputMethodManager.hideSoftInputFromWindow(binding.etContent.getWindowToken(), 0);

}

}

@Override

protected void onPause() {

super.onPause();

dismiss();

}

@Override

public void onBackPressed() {

super.onBackPressed();

dismiss();

}

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.iv_ok://提交

showMsg(“提交”);

break;

}

}

}

这个页面的逻辑当前是这样的,有两个输入框,一个是标题一个是内容,当输入框有输入的时候显示一个提交按钮,当没有输入或者输入框为空的时候隐藏这个提交按钮,还有一个就是一进入当前页面,就显示内容的输入框光标,同时弹出软键盘。

这个页面也需要一个入口,也就是记事本页面点击右下角的按钮跳转过来,在activity_notebook.xml中修改浮动按钮的onClick事件。

在这里插入图片描述

这里是一个toEdit,然后在NotebookActivity中新增一个toEdit方法

/**

  • 去编辑

*/

public void toEdit(View view) {

jumpActivity(EditActivity.class);

}

当然了,我们的NotebookActivity也需要一个入口,在我的MVVM中我就在侧滑菜单中增加入口,首先增加一个路径图标,在drawable下新增一个icon_notebook.xml,代码如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<vector xmlns:android=“http://schemas.android.com/apk/res/android”

android:width=“24dp”

android:height=“24dp”

android:autoMirrored=“true”

android:tint=“#000000”

android:viewportWidth=“24.0”

android:viewportHeight=“24.0”>

<path

android:fillColor=“@android:color/white”

android:pathData=“M14.17,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V9.83c0,-0.53 -0.21,-1.04 -0.59,-1.41l-4.83,-4.83C15.21,3.21 14.7,3 14.17,3L14.17,3zM8,15h8c0.55,0 1,0.45 1,1v0c0,0.55 -0.45,1 -1,1H8c-0.55,0 -1,-0.45 -1,-1v0C7,15.45 7.45,15 8,15zM8,11h8c0.55,0 1,0.45 1,1v0c0,0.55 -0.45,1 -1,1H8c-0.55,0 -1,-0.45 -1,-1v0C7,11.45 7.45,11 8,11zM8,7h5c0.55,0 1,0.45 1,1v0c0,0.55 -0.45,1 -1,1H8C7.45,9 7,8.55 7,8v0C7,7.45 7.45,7 8,7z” />

然后在nav_menu.xml中新增代码:

<item

android:id=“@+id/item_notebook”

android:icon=“@drawable/icon_notebook”

android:title=“记事本” />

添加位置如下图所示:

在这里插入图片描述

最后在HomeActivity中修改一下菜单点击代码,如下图所示:

在这里插入图片描述

下面我们运行一下:

在这里插入图片描述

编辑页面写好了,需要写具体的功能了,这需要在数据库中一个笔记表。

三、增加笔记表


① Bean

首先在bean包下新增一个Notebook类,代码如下:

@Entity(tableName = “notebook”)

public class Notebook {

@PrimaryKey(autoGenerate = true)

private int uid;

private String title;

private String content;

public int getUid() {

return uid;

}

public void setUid(int uid) {

this.uid = uid;

}

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;

}

@Ignore

public Notebook(String title, String content) {

this.title = title;

this.content = content;

}

public Notebook() {}

}

这目前的表中我只设置了两个主要字段,标题和内容,uid自增。

② Dao

下面就是数据表的操作接口类,在dao包下新建一个NotebookDao接口,代码如下:

@Dao

public interface NotebookDao {

@Query(“SELECT * FROM notebook”)

Flowable<List> getAll();

@Update

Completable update(Notebook notebook);

@Insert(onConflict = OnConflictStrategy.REPLACE)

Completable insert(Notebook notebook);

@Delete

Completable delete(Notebook notebook);

}

这里就是增删改查,相信你已经很熟悉了,如果你是从之前的文章一路看过来的话。

③ 数据库升级迁移

打开AppDatabase首先增加表和版本升级,如下图所示:

在这里插入图片描述

下面增加刚才的Dao的实现,一行代码搞定,如下图所示:

public abstract NotebookDao notebookDao();

然后是数据库升级迁移,代码如下:

/**

  • 版本升级迁移到6 在数据库中新增一个笔记表

*/

static final Migration MIGRATION_5_6 = new Migration(5, 6) {

@Override

public void migrate(@NonNull @NotNull SupportSQLiteDatabase database) {

//创建笔记表

database.execSQL("CREATE TABLE notebook " +

"(uid INTEGER NOT NULL, " +

"title TEXT, " +

"content TEXT, " +

“PRIMARY KEY(uid))”);

}

};

最后添加迁移,如下图所示:

在这里插入图片描述

数据库搞定了,下面就是存储库了。

④ 新增存储库类

在repository包下新建一个NotebookRepository类,里面的代码如下:

public class NotebookRepository {

private static final String TAG = NotebookRepository.class.getSimpleName();

@Inject

NotebookRepository() {}

private final MutableLiveData notebookLiveData = new MutableLiveData<>();

private final MutableLiveData<List> notebooksMutableLiveData = new MutableLiveData<>();

public final MutableLiveData failed = new MutableLiveData<>();

public final List emptyList = new ArrayList<>();

/**

  • 添加笔记

*/

public void saveNotebook(Notebook notebook) {

//保存到数据库

Completable insert = BaseApplication.getDb().notebookDao().insert(notebook);

//RxJava处理Room数据存储

CustomDisposable.addDisposable(insert, () -> Log.d(TAG, “saveNotebook: 笔记数据保存成功”));

}

/**

  • 获取所有笔记

*/

public MutableLiveData<List> getNotebooks() {

Flowable<List> listFlowable = BaseApplication.getDb().notebookDao().getAll();

CustomDisposable.addDisposable(listFlowable, notebooks -> {

if (notebooks.size() > 0) {

notebooksMutableLiveData.postValue(notebooks);

} else {

notebooksMutableLiveData.postValue(emptyList);

failed.postValue(“暂无数据”);

}

});

return notebooksMutableLiveData;

}

}

这里存储里面现在是两个方法,一个用于查询,一个用于添加。然后就是新建ViewModel去操作这个存储库。

⑤ 新增ViewModel

这里其实有两个ViewModel,一个对应EditActivity,一个对应NotebookActivity,首先在viewmodels包下创建一个EditViewModel类,代码如下:

public class EditViewModel extends BaseViewModel {

private final NotebookRepository notebookRepository;

@ViewModelInject

EditViewModel(NotebookRepository notebookRepository){

this.notebookRepository = notebookRepository;

}

/**

  • 添加笔记

*/

public void addNotebook(Notebook notebook) {

failed = notebookRepository.failed;

notebookRepository.saveNotebook(notebook);

}

}

然后同样在viewmodels包下创建NotebookViewModel类,代码如下:

public class NotebookViewModel extends BaseViewModel {

private final NotebookRepository notebookRepository;

public LiveData<List> notebooks;

@ViewModelInject

NotebookViewModel(NotebookRepository notebookRepository){

this.notebookRepository = notebookRepository;

}

public void getNotebooks() {

failed = notebookRepository.failed;

notebooks = notebookRepository.getNotebooks();

}

}

⑥ 添加笔记

首先需要把EditViewModel与EditActivity进行绑定,如下图所示:

在这里插入图片描述

然后就是很简单的时候,在点击右上角按钮时,进行保存笔记,在EditActivity中修改一下代码,如下图所示:

在这里插入图片描述

这里我是保存了数据之后关掉当前页面,就会返回到之前的NotebookActivity,那么在这个页面就需要搜索当前数据库的表,然后通过列表加载出来。

四、显示笔记列表


既然是一个列表,那么自然就需要有一个item的布局,在layout下新建一个item_notebook.xml,里面的代码如下:

<?xml version="1.0" encoding="utf-8"?>

<variable

name=“notebook”

type=“com.llw.mvvm.db.bean.Notebook” />

<variable

name=“onClick”

type=“com.llw.mvvm.ui.adapter.NotebookAdapter.ClickBinding” />

<RelativeLayout

android:id=“@+id/detail”

android:foreground=“?attr/selectableItemBackground”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:layout_marginBottom=“8dp”

android:background=“@drawable/shape_bg_white_radius_12”

android:onClick=“@{() -> onClick.itemClick(notebook,detail)}”

android:padding=“12dp”>

<TextView

android:id=“@+id/tv_title”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:ellipsize=“end”

android:singleLine=“true”

android:text=“@{notebook.title}”

android:textColor=“@color/black”

android:textSize=“16sp” />

<TextView

android:id=“@+id/tv_content”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_below=“@+id/tv_title”

android:layout_marginTop=“4dp”

android:ellipsize=“end”

android:maxLines=“3”

android:text=“@{notebook.content}”

android:textSize=“14sp” />

布局很简单,就是显示标题和内容,采用databinding的方式赋值,下面创建适配器,在adapter包下新建一个NotebookAdapter类,里面的代码如下:

public class NotebookAdapter extends BaseQuickAdapter<Notebook, BaseDataBindingHolder> {

public NotebookAdapter(@Nullable List data) {

super(R.layout.item_notebook, data);

}

@Override

protected void convert(@NotNull BaseDataBindingHolder bindingHolder, Notebook notebook) {

ItemNotebookBinding binding = bindingHolder.getDataBinding();

if (binding != null) {

binding.setNotebook(notebook);

binding.setOnClick(new NotebookAdapter.ClickBinding());

binding.executePendingBindings();

}

}

public static class ClickBinding {

public void itemClick(Notebook notebook, View view) {

}

}

}

这个代码也是很简单的,就是绑定数据绑定布局,下面就是显示列表了,也很简单,回到NotebookActivity,增加三个变量并添加了一个注解,如下图所示:

在这里插入图片描述

修改代码,如下图所示:

在这里插入图片描述

首先是绑定ViewModel,然后在onResume的生命周期查询数据库中的数据,在编辑页面对数据进行修改之后会销毁掉,然后就会显示NotebookActivity,会触发onResume,再去查询一次数据。然后监听数据,有数据则加载列表,没有就显示那个空内容布局。下面来运行一下看看效果如何。

在这里插入图片描述

还是可以的吧,下面要做的就是修改笔记。

五、修改笔记


修改笔记的前提是要查询到要修改的笔记,通过id进行查询,然后完成修改,说起来是挺简单的,当然了,实现起来也很简单,我们来实现吧。首先是列表item的点击事件,点击之后传递uid到EditActivity,通过通过uid去得到Notebook。

在NotebookAdapater中增加如下图所示代码:

在这里插入图片描述

因为我们的NotebookDao中并没有通过id查询笔记的方法,因此我们在NotebookDao中新加一个,代码如下:

@Query(“SELECT * FROM notebook WHERE uid=:uid”)

Flowable findById(int uid);

然后去NotebookRepository中去对方法进行实现,这里我们需要实现两个方法,一个用于通过id查询,一个用于修改,在NotebookRepository中新增如下代码:

/**

  • 根据id获取笔记

  • @param uid id

*/

public MutableLiveData getNotebookById(int uid) {

Flowable flowable = BaseApplication.getDb().notebookDao().findById(uid);

CustomDisposable.addDisposable(flowable, notebook -> {

if (notebook != null) {

notebookLiveData.postValue(notebook);

} else {

failed.postValue(“未查询到笔记”);

}

});

return notebookLiveData;

}

/**

  • 更新笔记

  • @param notebook

*/

public void updateNotebook(Notebook notebook) {

Completable update = BaseApplication.getDb().notebookDao().update(notebook);

CustomDisposable.addDisposable(update, () -> {

Log.d(TAG, "updateNotebook: " + “更新成功”);

failed.postValue(“200”);

});

}

存储库的方法写好了,下面就是在EditViewModel中去调用了,进入EditViewModel,新增如下代码:

public LiveData notebook;

/**

  • 根据Id搜索笔记

*/

public void queryById(int uid) {

failed = notebookRepository.failed;

notebook = notebookRepository.getNotebookById(uid);

}

/**

  • 更新笔记

*/

public void updateNotebook(Notebook notebook) {

failed = notebookRepository.failed;

notebookRepository.updateNotebook(notebook);

}

这个代码就没啥好说的,见过很多类似的了,最后就是在EditActivity。

进入EditActivity中,新增两个变量:

private int uid;

private Notebook mNotebook;

首先要处理uid的问题,因为我们点击新增笔记和笔记笔记都是进入这个页面,所以要分情况处理。

在这里插入图片描述

这里我把showInput从移除掉了,根据现在的业务逻辑它不应该在onCreate中调用了,需要在initView方法中,下面我们看看怎么去修改。

在这里插入图片描述

如图所示,这里获取uid,如果为-1表示为新增,否则就是更新。是更新的话就通过查询id然后观察返回的数据变化。

这里的binding.setNotebook(mNotebook);是直接通过单向绑定对控件进行赋值,因此这里需要修改一下activity_edit.xml中的代码:

在这里插入图片描述

在这里插入图片描述

最后我们修改一下确定按钮的业务逻辑,如下图所示:

在这里插入图片描述

这个-1是用来做什么的我就不再多说了,这里修改数据之后,依然后关闭当前页面。我们的代码写完了,运行一下吧。

在这里插入图片描述

修改就完成了,下面就是删除了。

六、删除笔记


删除的方法之前就写好了,因此Dao中不需要改动了,只要在NotebookRepository中增加删除的方法即可,代码如下:

/**

  • 删除笔记

*/

public void deleteNotebook(Notebook notebook) {

Completable delete = BaseApplication.getDb().notebookDao().delete(notebook);

CustomDisposable.addDisposable(delete, () -> {

Log.d(TAG, "deleteNotebook: " + “删除成功”);

failed.postValue(“200”);

});

}

然后是EditViewModel中去调用,在EditViewModel中新增代码如下所示:

/**

  • 删除笔记

*/

public void deleteNotebook(Notebook notebook) {

notebookRepository.deleteNotebook(notebook);

failed = notebookRepository.failed;

}

下面就是在EditActivity中去调用EditViewModel中的deleteNotebook方法,在标题哪里添加一个按钮,修改activity_edit.xml,代码如下:

<ImageView

android:id=“@+id/iv_delete”

android:layout_width=“36dp”

android:layout_height=“36dp”

android:layout_gravity=“end”

android:layout_marginEnd=“16dp”

android:foreground=“?attr/selectableItemBackground”

android:padding=“2dp”

android:src=“@mipmap/ic_delete”

android:visibility=“gone” />

注意添加的位置:

在这里插入图片描述

然后是修改EditActivity中的代码,主要就是注册按钮的监听,然后是调用删除的方法。

在这里插入图片描述

删除笔记

在这里插入图片描述

运行一下:

在这里插入图片描述

OK了,本篇文章就到这里了,下一篇可能会对记事本功能进行一个优化,主要是用户体验方面,时隔近一个月,再写文章时花费的时间依然很多,久违了的感觉。今天是周五了,周末愉快啊。

七、源码


如果对你有所帮助的话,可以Fork or Star

GitHub:MVVM-Demo

CSDN: MVVMDemo_11.rar

八、开心一下


在这里插入图片描述

最后

一线互联网Android面试题含详解(初级到高级专题)

这些题目是今年群友去腾讯、百度、小米、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。并且大多数都整理了答案,熟悉这些知识点会大大增加通过前两轮技术面试的几率

如果设置门槛,很多开发者朋友会因此错过这套高级架构资料,错过提升成为架构师的可能。这就失去了我们的初衷;让更多人都能通过高效高质量的学习,提升自己的技术和格局,升职加薪。

最后送给大家一句话,望共勉,永远不要放弃自己的梦想和追求;
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
s=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Yid5a2m6ICFLVN0dWR5,size_20,color_FFFFFF,t_70,g_se,x_16)

运行一下:

在这里插入图片描述

OK了,本篇文章就到这里了,下一篇可能会对记事本功能进行一个优化,主要是用户体验方面,时隔近一个月,再写文章时花费的时间依然很多,久违了的感觉。今天是周五了,周末愉快啊。

七、源码


如果对你有所帮助的话,可以Fork or Star

GitHub:MVVM-Demo

CSDN: MVVMDemo_11.rar

八、开心一下


在这里插入图片描述

最后

一线互联网Android面试题含详解(初级到高级专题)

这些题目是今年群友去腾讯、百度、小米、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。并且大多数都整理了答案,熟悉这些知识点会大大增加通过前两轮技术面试的几率

[外链图片转存中…(img-qkLpWnRJ-1714654304228)]

如果设置门槛,很多开发者朋友会因此错过这套高级架构资料,错过提升成为架构师的可能。这就失去了我们的初衷;让更多人都能通过高效高质量的学习,提升自己的技术和格局,升职加薪。

最后送给大家一句话,望共勉,永远不要放弃自己的梦想和追求;
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 15
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android MVVM框架是一种基于DataBinding工具实现的框架,它是Android项目框架中的一种,与MVC和MVP框架相对应。MVVM框架的特点是可以在ViewModel中修改View层的展示,而无需通知View层做任何事情。 在使用MVVM框架时,需要创建一个MainActivity和对应的布局xml文件,并在MainActivity中使用DataBindingUtil.setContentView方法将布局文件与Activity进行绑定,然后创建一个ViewModel对象并传入ViewDataBinding参数,实现数据和UI的绑定。 DataBinding是一个实现数据和UI绑定的框架,它可以方便地实现MVVM开发模式。在xml中使用@{}的方式来实现数据的显示,这种方式在Java Web开发中也有类似的应用。123 #### 引用[.reference_title] - *1* *2* [Android 框架系列(二)—— MVVM框架搭建及分析](https://blog.csdn.net/StudyOfAndroid/article/details/108527052)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *3* [Android MVVM架构](https://blog.csdn.net/weixin_53431933/article/details/126372227)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值