android-wear os 记事本开发
- wear-OS 记事本
- sqllite+recyclerview的基本使用
- 一、创建项目
- 二、构建activity,继承wearableactivity
- 三、根布局适配
- 四、添加列表视图
- 五、跳转按钮
- 六、创建不同类别的包
- 七、创建第二个activity
- 八、完善主页布局文件,添加了一个swiperefresh
- 九、日记编写页面的搭建
- 十、常量类的创建
- 十一、实体类的创建
- 十二、数据库的操作
- 十三、编写自定义alterdialog
- 十四、列表条目布局文件的编写
- 十五、编写适配器
- 长按弹出提示框,删除条目选项
- 点击跳转到详情页面,同时传递参数,用于判断是修改还是删除
- 十六 mainactivity 主界面的编写
- 主界面编写就简单了,初始化控件,调用SQL的查询方法,返回集合,实例化适配器,给适配器传入数据,给列表条目设置适配器。 设置swiperefresh下拉刷新控件的方法,刷新时重新获取数据并展示,返回false,刷新操作完成后圈圈消化掉。
- 实现添加按钮的点击操作,点击跳转到日记详情页面
- 十七、详情页面的逻辑实现
- 该页面也好实现
- 首先初始化控件
- 接收主页面传过来的数据,也就是条目点击进行的跳转时发送的数据,如果是点击添加按钮进行跳转,则没有数据传输。如果有数据传过来,就将传过来的内容自动填充到输入框内由用户进行修改编辑
- 使用activity的生命周期,在用户滑动退出时,也就是失去焦点,不可见,销毁时调用SQL的添加方法,自动保存用户的内容。当然,在在方法内判断传过来的id是否为空,如果为空,执行添加事件,如果不为空,则根据id进行数据库的修改操作。
- 定义一个静态变量,进行字号的大小调整,完成加大字体和减小字体的逻辑功能
- 实现字体颜色切换的功能
- 十八、主界面xml文件代码
- 十九、日记详情界面xml文件代码
wear-OS 记事本
sqllite+recyclerview的基本使用
一、创建项目
新建项目,选择wear,点击默认的activity,而后点击next,起好自己的项目名称创建
二、构建activity,继承wearableactivity
等待构建、activity继承自wearableActivity,
三、根布局适配
根布局使用BoxInsetLayout,直接子布局用app:boxedEdges="all"这个属性,一般来说不会报错,报红也没事,运行没有问题。
这里的意思是适配方形的手表和圆形的手表,当手表是圆形的时候,内容将全部现实于圆心,具体图片我就不展示了。
四、添加列表视图
主界面放一个列表视图用于展示笔记条目,也就是数据库里面的内容
WearableRecyclerView,这个在wear项目中等同于android的recyclerview。
五、跳转按钮
屏幕添加一个按钮,点击进入笔记编辑页面
ps:按理说手表小,应该手势操作滑动进入,但是我这里使用gesture没有效果,emmm,应为我是昨天才开始看wear的,也没找到什么资料,暂时不会解决。睡会解决的话麻烦告知一下谢谢
六、创建不同类别的包
创建四个包,分别存放不同的类(当然不创建也可以,个人觉得这样较为清楚)
七、创建第二个activity
创建第二个activity,也就是添加日记的页面,一般来说我是直接右键系统自动生成activity,但这里要继承wear的类,我直接复制并改名,(layout文件也要复制哦),记得activity必须要在清单文件中注册
八、完善主页布局文件,添加了一个swiperefresh
完成mainactivity的xml布局,该布局中我在根布局-----》fragment-----》下添加了Swiperefreshlayout布局,用于进行数据的刷新。因为在wear下我采取生命周期的方法让适配器在发生数据变化时刷新无效,所以采用下拉刷新控件,在swiperefresh下放一个相对布局,在相对布局中放置一个wearablerecyclerview控件进行数据库内容的映射,也就是日记列表面,然后添加一个进行页面跳转的控件,这里我添加了img,让其位于父控件的右底部。
布局层次如下,img与列表控件同级
boxinsetlayout——>FrameLayout——》SwipeRefreshLayout——》RelativeLayout——》WearableRecyclerView+imageview
九、日记编写页面的搭建
注意:外部的scrollview视图添加,方面页面过大导致界面出问题,原本是通过手势检测进行一个右边的控制面板的构建,手势滑动将其显示,结果因为gesture在wear没有效果(我这边无效),就弃用了,后面也适用了drawablelayout,体验并不怎么好,也启用。所以通过滚动视图将其置于输入框的下边
十、常量类的创建
我们计划的数据库有库名,表名,还有三个字段,分别是id,内容,时间,id用于删改查,其他自然是信息了。故此我们进行常量的设定
同时设置一个获取当前系统时间的方法,并返回格式的文本
本来设置了一个吐司提示调用的方法,但是android原生态吐司在wear中太难看了,我后面没有用到,想加的可以加
该类代码如下
package com.yangpeilin.aaa.Constant;
import android.annotation.SuppressLint;
import android.content.Context;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Constant {
/**
* id
* 内容
* 时间
* 表名
* 数据库
*/
public static final String ID = "node_id";
public static final String CONTEXT = "node_context";
public static final String TIME = "node_time";
public static final String TABLENAME = "node";
public static final String DBNAME = "node.db";
// 获取当前时间并格式化
public static String getTime(){
Date date = new Date();
@SuppressLint("SimpleDateFormat") SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format = dateFormat.format(date);
return format;
}
// 吐司提示
public static void showMsg(String msg, Context context){
Toast.makeText(context,msg,Toast.LENGTH_SHORT).show();
}
}
十一、实体类的创建
我们便于数据的操作,来创建一个bean类,同时创建出她的无参构造和全参构造,并实现get/set方法,代码如下
package com.yangpeilin.aaa.Bean;
/**
* 实体类
*/
public class NodeBean {
private String id;
private String context;
private String time;
public NodeBean() {
}
public NodeBean(String id, String context, String time) {
this.id = id;
this.context = context;
this.time = time;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
十二、数据库的操作
我这里将数据库的创建以及帮助类操作方法放在了一起。
我们创建一个数据库,工厂不用,给个null,版本为1。
我们在构造方法中直接得到database帮助类,并将其抽取为全局变量
创建数据表,三个字段,id为integer类型,主键自增,其他两个设置为text类型即可,varchar 也可以。
"create table node(node_id integer primary key autoincrement,node_context text,node_time text)"
实现增删改查的方法,增需要values,改需要values id 删需要id 查需要游标、集合。我们将查询到的数据直接通过一个集合返回。这都是sqlite的基本api,这里不做细说。
- 增删改查对应
- insert delete update queryall
- 该类整体代码如下
package com.yangpeilin.aaa.SQLHelper;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
import com.yangpeilin.aaa.Bean.NodeBean;
import com.yangpeilin.aaa.Constant.Constant;
import java.util.ArrayList;
import java.util.List;
public class MySQLHelper extends SQLiteOpenHelper {
private final SQLiteDatabase database;
private final String createTable
= "create table node(node_id integer primary key autoincrement,node_context text,node_time text)";
/**
*
* @param context 上下文
* @param //name 数据库
* @param //factory 工厂
* @param //version 版本号
*/
public MySQLHelper(@Nullable Context context) {
super(context, Constant.DBNAME, null, 1);
// 实例化该类时就创建database操作
// getWritableDatabase同样可以进行读取
database = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(createTable);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
/**
* 增删改查
* insert delete update queryall
*/
public void insert(String context,String time){
ContentValues values = new ContentValues();
values.put(Constant.CONTEXT,context);
values.put(Constant.TIME,time);
database.insert(Constant.TABLENAME, null, values);
// 操作完关闭
database.close();
}
public void update(String context,String time,String id){
ContentValues values = new ContentValues();
values.put(Constant.CONTEXT,context);
values.put(Constant.TIME,time);
database.update(Constant.TABLENAME, values,"node_id=?",new String[]{id});
// 操作完关闭
database.close();
}
public void delete(String id){
database.delete(Constant.TABLENAME,"node_id=?",new String[]{id});
// 操作完关闭
database.close();
}
public List<NodeBean> queryAll(){
@SuppressLint("Recycle") Cursor cursor = database.rawQuery("select * from node", null);
List<NodeBean> list = new ArrayList<>();
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndex(Constant.ID));
String context = cursor.getString(cursor.getColumnIndex(Constant.CONTEXT));
String time = cursor.getString(cursor.getColumnIndex(Constant.TIME));
NodeBean bean = new NodeBean(String.valueOf(id),context,time);
list.add(bean);
}
cursor.close();
database.close();
return list;
}
}
十三、编写自定义alterdialog
布局不做赘述,直接贴代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:gravity="center"
android:orientation="vertical"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="80dp">
<TextView
android:text="@string/delete"
android:gravity="center"
android:textStyle="bold"
android:textSize="20sp"
android:textColor="@color/white"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:gravity="center"
android:id="@+id/tv_delete_yes"
android:textStyle="bold"
android:textSize="16sp"
android:layout_weight="1"
android:text="@string/yes"
android:layout_width="0dp"
android:layout_height="match_parent"/>
<TextView android:gravity="center"
android:id="@+id/tv_delete_no"
android:textStyle="bold"
android:textSize="16sp"
android:layout_weight="1"
android:text="@string/no"
android:layout_width="0dp"
android:layout_height="match_parent"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
十四、列表条目布局文件的编写
该布局中就两个文本,一个用于显示title,一个用于显示时间
代码如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_marginBottom="1px"
android:layout_height="wrap_content">
<TextView
android:id="@+id/item_title"
android:lines="1"
android:enabled="true"
android:textSize="10sp"
android:textColor="@color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:textColor="@color/white"
android:id="@+id/item_time"
android:textSize="6sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<View
android:layout_marginTop="1dp"
android:background="#ffffff"
android:layout_width="match_parent"
android:layout_height="1px"/>
</LinearLayout>
十五、编写适配器
wearablerecyclerview使用的适配器与recyclerview适配器相同
需要两个成员变量,一个上下文,一个集合
适配器的编写不做介绍
不知为何通过接口再activity中调用不到点击事件,莫不是被消化了?这里的点击事件我们直接在适配器中操作
长按弹出提示框,删除条目选项
点击跳转到详情页面,同时传递参数,用于判断是修改还是删除
完整代码如下
package com.yangpeilin.aaa.Adapter;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.yangpeilin.aaa.Bean.NodeBean;
import com.yangpeilin.aaa.MainActivity;
import com.yangpeilin.aaa.R;
import com.yangpeilin.aaa.SQLHelper.MySQLHelper;
import com.yangpeilin.aaa.SecondActivity;
import java.util.ArrayList;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {
Context context;
List<NodeBean> list = new ArrayList<>();
public MyAdapter(Context context) {
this.context = context;
}
public void addList(List<NodeBean> list) {
this.list = list;
notifyDataSetChanged();
}
/* AdapteronClick adapteronClick;
public interface AdapteronClick{
void shortClick(String id,String tite,String time);
void longClick(String id,String tite,String time);
}
public void setOnItemClickListener(AdapteronClick adapteronClick) {
adapteronClick = adapteronClick;
}*/
@NonNull
@Override
public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new MyHolder(LayoutInflater.from(context).inflate(R.layout.item,parent,false));
}
@Override
public void onBindViewHolder(@NonNull MyHolder holder, int position) {
final NodeBean bean = list.get(position);
holder.title.setText(bean.getContext());
holder.time.setText(bean.getTime());
// 条目点击事件
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TAGAdapter", "onClick: ");
Intent intent = new Intent(context, SecondActivity.class);
intent.putExtra("id",bean.getId());
intent.putExtra("tite", bean.getContext());
Log.d("TAG", "shortClick: \n点击条目进入");
Log.d("TAG", "shortClick: \n"+bean.getContext()+"\n"+bean.getId());
context.startActivity(intent);
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
final AlertDialog alertDialog = builder.create();
View inflate = View.inflate(context, R.layout.dialog_item, null);
alertDialog.setView(inflate);
alertDialog.show();
inflate.findViewById(R.id.tv_delete_no).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
alertDialog.dismiss();
}
});
inflate.findViewById(R.id.tv_delete_yes).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MySQLHelper helper = new MySQLHelper(context);
helper.delete(bean.getId());
Log.d("TAG", "onClick: 删除成功");
MyAdapter.this.notifyDataSetChanged();
alertDialog.dismiss();
}
});
/*Log.d("TAG", "onLongClick: ");
if (adapteronClick!=null) {
adapteronClick.longClick(bean.getId(),bean.getContext(),bean.getTime());
Log.d("TAG", "onLongClick: ");
}*/
// 消化事件
return true;
}
});
}
@Override
public int getItemCount() {
return list.size()>0?list.size():0;
}
class MyHolder extends RecyclerView.ViewHolder{
private final TextView title;
private final TextView time;
public MyHolder(@NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.item_title);
time = itemView.findViewById(R.id.item_time);
}
}
}
十六 mainactivity 主界面的编写
主界面编写就简单了,初始化控件,调用SQL的查询方法,返回集合,实例化适配器,给适配器传入数据,给列表条目设置适配器。 设置swiperefresh下拉刷新控件的方法,刷新时重新获取数据并展示,返回false,刷新操作完成后圈圈消化掉。
实现添加按钮的点击操作,点击跳转到日记详情页面
package com.yangpeilin.aaa;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.wearable.activity.WearableActivity;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.wear.widget.BoxInsetLayout;
import androidx.wear.widget.WearableRecyclerView;
import com.yangpeilin.aaa.Adapter.MyAdapter;
import com.yangpeilin.aaa.Bean.NodeBean;
import com.yangpeilin.aaa.SQLHelper.MySQLHelper;
import java.util.List;
public class MainActivity extends WearableActivity{
private WearableRecyclerView main_recyclerview;
private ImageView img_add;
private Context context;
private String tag;
private MyAdapter adapter;
private SwipeRefreshLayout swiper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tag = getClass().getName();
// Enables Always-on
setAmbientEnabled();
// 初始化控件
initView();
// 监听事件
imgListener();
// recyclerview的相关配置以及条目的点击事件
recyclerInit();
}
// 生命周期能执行到,但是刷新不了适配器数据,改用swiperefresh实现
@Override
protected void onResume() {
super.onResume();
recyclerInit();
Log.d("TAG", "onResume: \n刷新刷新");
}
public void recyclerInit() {
MySQLHelper helper = new MySQLHelper(this);
List<NodeBean> list = helper.queryAll();
main_recyclerview.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyAdapter(this);
adapter.addList(list);
main_recyclerview.setAdapter(adapter);
}
private void imgListener() {
img_add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(context, SecondActivity.class));
Log.d(tag, "onClick: \n进入详情页面");
}
});
swiper.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
recyclerInit();
swiper.setRefreshing(false);
}
});
}
private void initView() {
context = MainActivity.this;
main_recyclerview = findViewById(R.id.main_recyclerview);
img_add = findViewById(R.id.img_add);
swiper = findViewById(R.id.swiper);
}
}
十七、详情页面的逻辑实现
该页面也好实现
首先初始化控件
接收主页面传过来的数据,也就是条目点击进行的跳转时发送的数据,如果是点击添加按钮进行跳转,则没有数据传输。如果有数据传过来,就将传过来的内容自动填充到输入框内由用户进行修改编辑
Intent intent = getIntent();
id = intent.getStringExtra("id");
tite = intent.getStringExtra("tite");
if (!TextUtils.isEmpty(id)){
node_et_context.setText(tite);
}
使用activity的生命周期,在用户滑动退出时,也就是失去焦点,不可见,销毁时调用SQL的添加方法,自动保存用户的内容。当然,在在方法内判断传过来的id是否为空,如果为空,执行添加事件,如果不为空,则根据id进行数据库的修改操作。
if (!TextUtils.isEmpty(trim)) {
if (TextUtils.isEmpty(id)) {
// id为空表示点击添加按钮进来的,实施增的做法
helper.insert(trim, Constant.getTime());
Log.d("TAG", "onStop: \n我再"+Constant.getTime()+"保存了"+trim);
}else {
helper.update(trim,Constant.getTime(),id);
Log.d("TAG", "onStop: \n我再"+Constant.getTime()+"更新了"+tite+"、变成了"+trim);
}
}else {
Log.d("TAG", "onStop: \n没东西,保存个大西瓜");
}
}
定义一个静态变量,进行字号的大小调整,完成加大字体和减小字体的逻辑功能
实现字体颜色切换的功能
package com.yangpeilin.aaa;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.wearable.activity.WearableActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import androidx.wear.widget.SwipeDismissFrameLayout;
import com.yangpeilin.aaa.Constant.Constant;
import com.yangpeilin.aaa.SQLHelper.MySQLHelper;
import java.sql.Time;
public class SecondActivity extends WearableActivity implements View.OnClickListener {
private EditText node_et_context;
private ImageView img_big;
private ImageView img_small;
private ImageView img_red;
private ImageView img_black;
private SwipeDismissFrameLayout swipe;
private static int FONT_SIZE = 12;
private String id;
private String tite;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
// Enables Always-on
setAmbientEnabled();
// 初始化控件
initView();
// 监听事件
mClick();
// 获取点击条目进入的数据
Intent intent = getIntent();
id = intent.getStringExtra("id");
tite = intent.getStringExtra("tite");
if (!TextUtils.isEmpty(id)){
node_et_context.setText(tite);
}
}
// 用swipedismiss右滑状态保存的话,在圆形界面,手指沿着左侧划出的话会执行不到他的onDismissed监听方法,
// 而是直接被wear的基层覆盖,用其他两个方法的话存在用户手误状态下退出,所以这里才用onstop生命周期,当用户回退时
//执行保存的方法
@Override
protected void onStop() {
super.onStop();
MySQLHelper helper = new MySQLHelper(this);
String trim = node_et_context.getText().toString().trim();
if (!TextUtils.isEmpty(trim)) {
if (TextUtils.isEmpty(id)) {
// id为空表示点击添加按钮进来的,实施增的做法
helper.insert(trim, Constant.getTime());
Log.d("TAG", "onStop: \n我再"+Constant.getTime()+"保存了"+trim);
}else {
helper.update(trim,Constant.getTime(),id);
Log.d("TAG", "onStop: \n我再"+Constant.getTime()+"更新了"+tite+"、变成了"+trim);
}
}else {
Log.d("TAG", "onStop: \n没东西,保存个大西瓜");
}
}
private void mClick() {
img_big.setOnClickListener(this);
img_black.setOnClickListener(this);
img_red.setOnClickListener(this);
img_small.setOnClickListener(this);
/* swipe.addCallback(new SwipeDismissFrameLayout.Callback() {
@Override
public void onSwipeStarted(SwipeDismissFrameLayout layout) {
super.onSwipeStarted(layout);
Log.d("TAG", "onSwipeStarted: ");
}
@Override
public void onSwipeCanceled(SwipeDismissFrameLayout layout) {
super.onSwipeCanceled(layout);
Log.d("TAG", "onSwipeCanceled: ");
}
@Override
public void onDismissed(SwipeDismissFrameLayout layout) {
super.onDismissed(layout);
Log.d("TAG", "onDismissed: \n我保存了");
finish();
Log.d("TAG", "onDismissed: ");
}
});*/
}
private void initView() {
node_et_context = findViewById(R.id.node_et_context);
img_big = findViewById(R.id.img_big);
img_small = findViewById(R.id.img_small);
img_red = findViewById(R.id.img_red);
img_black = findViewById(R.id.img_black);
swipe = findViewById(R.id.swipe);
}
@Override
public void onClick(View v) {
int i;
switch (v.getId()) {
case R.id.img_big:
i = FONT_SIZE += 2;
node_et_context.setTextSize(i);
break;
case R.id.img_small:
i = FONT_SIZE -=2;
node_et_context.setTextSize(i);
break;
case R.id.img_red:
node_et_context.setTextColor(Color.parseColor("#ff0000"));
break;
case R.id.img_black:
node_et_context.setTextColor(Color.parseColor("#000000"));
break;
}
}
}
十八、主界面xml文件代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.wear.widget.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fm"
android:background="@color/dark_grey"
tools:context=".MainActivity"
tools:deviceIds="wear">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:boxedEdges="all">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swiper"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.wear.widget.WearableRecyclerView
android:id="@+id/main_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ImageView
android:id="@+id/img_add"
android:layout_alignParentRight="true"
android:scaleType="centerCrop"
android:layout_alignParentBottom="true"
android:background="@drawable/add"
android:layout_width="30dp"
android:layout_height="30dp"/>
</RelativeLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</FrameLayout>
</androidx.wear.widget.BoxInsetLayout>
十九、日记详情界面xml文件代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.wear.widget.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:deviceIds="wear">
<FrameLayout
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:boxedEdges="all">
<androidx.wear.widget.SwipeDismissFrameLayout
android:id="@+id/swipe"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:gravity="top"
android:id="@+id/node_et_context"
android:background="@drawable/border"
android:minHeight="120dp"
android:textSize="12sp"
android:textColor="@color/black"
android:textColorHint="@color/black"
android:hint="please input context"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:background="#61000000"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_below="@id/node_et_context"
android:layout_marginTop="3dp"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/img_big"
android:src="@drawable/add"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="15dp"/>
<ImageView
android:id="@+id/img_small"
android:src="@drawable/sub"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="15dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/img_red"
android:src="@drawable/red"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="15dp"/>
<ImageView
android:id="@+id/img_black"
android:src="@drawable/black"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="15dp"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</ScrollView>
</androidx.wear.widget.SwipeDismissFrameLayout>
</FrameLayout>
</androidx.wear.widget.BoxInsetLayout>