Android MyNote笔记本——架构简介与搜索时间戳介绍

MyNote

根据Google官方的Notepad源码使用Jetpack进行重构改造

架构简介

引入Jetpack中的ViewModel架构将用户界面上的数据从Controller(Activity)分离到ViewModel中,并引入LiveData架构对数据进行实时观察。使得Controller层只需关注自身的业务逻辑。让数据的操作与通知。

同时引入Jetpack库中Room持久性库在 SQLite 的基础上提供了一个抽象层,获享更强健的数据库访问机制。并且通过Jetpack库中Navigation控制fragment切换代替Activity间Intent显隐式调用

Android MyNote笔记本——架构简介与搜索时间戳介绍_第1张图片

架构目录
Android MyNote笔记本——架构简介与搜索时间戳介绍_第2张图片

扩展功能实现

1.时间戳展示

界面展示
Android MyNote笔记本——架构简介与搜索时间戳介绍_第3张图片

在数据库实体类Note中引入复杂数据类型Date字段。如果你想追求时区的精确控制等,这里推荐你使用OffsetDateTime来作为时间的类型

@ColumnInfo(name = "last_update_time")
private Date lastUpdateTime;

Room不支持开箱即用,Room 提供了在基元类型和盒装类型之间进行转换的功能,但不允许实体之间进行对象引用。此时需要引入类型转换器。

/**
 * 类型转换类,需要在database中使用@TypeConverters({Converters.class})生效
 * @author 98578
 * @create 2020-05-29 16:49
 */
public class Converters {
    @TypeConverter
    public static Date fromTimestamp(Long value) {
        return value == null ? null : new Date(value);
    }

    @TypeConverter
    public static Long dateToTimestamp(Date date) {
        return date == null ? null : date.getTime();
    }
}

接着,将 @TypeConverters 注释添加到 NoteDatabase 类中,以便 Room 可以使用您为该 NoteDatabase 中的每个实体和 DAO 定义的转换器:

/**
 * 数据库管理,采用单例模式
 * @author 98578
 * @create 2020-05-29 11:25
 */
@Database(entities = {Note.class},version = 1,exportSchema = false)
@TypeConverters({Converters.class})
public abstract class NoteDatabase extends RoomDatabase {

    private static NoteDatabase INSTANCE;

    public synchronized static NoteDatabase getINSTANCE(Context context) {
        if (INSTANCE==null) {
            INSTANCE = Room.databaseBuilder(context.getApplicationContext(),NoteDatabase.class,"note_datebase")
                    .build();
        }
        return INSTANCE;
    }

    /**
     * 在@Database中 多个entity则写多个Dao
     */
    public abstract NoteDao getNoteDao();
}

通过使用这些转换器,您就可以在其他查询中使用自定义类型,就像使用基元类型一样,在数据库Dao中代码段所示:

/**
 * 数据库操作的接口
 * @author 98578
 * @create 2020-05-29 11:25
 */
@Dao
public interface NoteDao {
    @Query("select * from note order by last_update_time desc")
    LiveData<List<Note>> queryAllNotes();

}

2.搜索

界面展示

  • 搜索前
Android MyNote笔记本——架构简介与搜索时间戳介绍_第4张图片
  • 搜索时
Android MyNote笔记本——架构简介与搜索时间戳介绍_第5张图片

首先引入menu组件的SearchView,注意你要将组件单独在菜单栏中显示需要为SearchView添加app:showAsAction="always"字段,具体引入如下

<item
        android:id="@+id/app_bar_search"
        android:icon="@drawable/ic_search_black_24dp"
        android:title="Search"
        app:actionViewClass="android.widget.SearchView"
        app:showAsAction="always" />

而后需要在fragment中重写onCreateOptionsMenu对显式菜单项进行显示与监听,对于SearchView的封装可以进行提交搜索或实时搜索,你可以分别实现监听SearchView.OnQueryTextListener监听中的onQueryTextSubmitonQueryTextChange。此处实现实时的模糊搜索,代码如下:

/**
     * 初始化菜单栏,并实现显式菜单项功能show
     */
    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.main_menu, menu);

        //搜索
        SearchView searchView = (SearchView) menu.findItem(R.id.app_bar_search).getActionView();
        //控制搜索框长度
        int maxWidth = searchView.getMaxWidth();
        searchView.setMaxWidth((int) (0.5 * maxWidth));
        //设置搜索框的实时监听
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                //去除多余前后空格
                String pattern = newText.trim();
                noteLive = noteViewModel.queryNotesWithPattern(pattern);
                /*
                  注意:重新赋予LiveData后最好先移除之前的观察。
                  大坑:观察的移除和注入都必须是getViewLifecycleOwner获取的LifecycleOwner。其对应fragment的生命周期
                 */
                noteLive.removeObservers(getViewLifecycleOwner());
                //对LiveData重新进行观察,注意Owner的生命周期,需要注入fragment的owner
                noteLive.observe(getViewLifecycleOwner(), notes -> {
                    //备份列表
                    allNotes = notes;
                    //将观察的数据注入RecycleAdapt中
                    myAdapt.submitList(notes);
                });
                //修改为返回true后事件不会再向下传递,默认false会继续传递
                return true;
            }
        });
    }

你可能感兴趣的:(Android开发)