侧边栏壁纸
  • 累计撰写 402 篇文章
  • 累计创建 63 个标签
  • 累计收到 122 条评论

目 录CONTENT

文章目录

Android 小技巧 2

Z同学
2022-12-05 / 0 评论 / 1 点赞 / 137 阅读 / 1,641 字
温馨提示:
本文最后更新于 2022-12-21,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1. 介绍

本篇内容不成体系,专门介绍一些在使用过程中。碰见的不明确的地方,通过搜索得到的结果进行的一个汇总。

可以算是一些小笔记汇合集了。

PS:内容都是基于Java版本的,Kotlin版本没有哦。

2. 内容

一些小操作的汇总介绍

2.1 泛型T适配 ViewBinding ,满足viewBinding和dataBinding

我们开启视图绑定和数据绑定之后:

    buildFeatures {
        dataBinding = true
        viewBinding true
    }

在Activity中使用:

 private ActivityMainBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot()); //添加绑定
    }

}

PS:我们如果有些类不想自动生成对应的binding类,那么只需要在该布局的layout中添加忽略字段即可:tools:viewBindingIgnore="true"

如果是dataBinding

我们还需要在xml中配置如下。

<layout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
		...

    </data>
    <androidx.constraintlayout.widget.ConstraintLayout>
    ......
   </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

而在Activity中初始化的配置:

    private ActivityMainBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding =DataBindingUtil.setContentView(this,R.layout.activity_main);
    }

}

PS: 其实两种绑定布局的方式是一样的,只是DataBinding由于有数据的绑定,所以有了一个封装操作。

我们如果每个类都这么写,有些样板了。可以通过反射实现两种方法动态绑定

public abstract class BaseActivity<T extends ViewBinding> extends AppCompatActivity {

protected T viewBinding;
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
        Class cls = (Class) type.getActualTypeArguments()[0];
        try {
            Method inflate = cls.getDeclaredMethod("inflate", LayoutInflater.class);
            viewBinding = (T) inflate.invoke(null, getLayoutInflater());
            setContentView(viewBinding.getRoot());

        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        
    }
}

然后哪里需要使用,就继承封装就可以了。我们上面的绑定方法就可以改为:

public class MainActivity extends BaseActivity<ActivityMainBinding> {
     @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       	viewBinding.tvZinyan.setText("zinyan.com")
    }
   
}

如果对于DataBinding不太了解,可以通过:https://zinyan.com/?p=105文章来学习。

如果对于ViewBinding不太了解,可以通过:https://zinyan.com/?p=340文章来学习。

2.2 merge 标签依赖的layout 在Viewbinding或Databinding中的使用

我们如果在xml布局中,通过include 引用了其他的layout布局文档,而且该layout是通过merge关键字包裹的。

例如:有一个activity_main.xml 文件中,引入了一个layout_message.xml 文件:

activity_main.xml的内容如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

	...

    <include layout="@layout/layout_message" />


</androidx.constraintlayout.widget.ConstraintLayout>

layout_message.xml的内容如下:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

	...
    <ImageView />
     <ImageView />
    <ImageView />
</merge>

我们如果要访问layout_message中的View并修改:

   public class MainActivity extends BaseActivity<ActivityMainBinding> {
     @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       	viewBinding.tvZinyan.setText("zinyan.com")
        //获取该xml文件的binding对象。后面的使用就和普通的binding对象使用是一样的。
        LayoutMessageBinding layoutmessageBind= LayoutMessageBinding.bind(viewBinding.getRoot())
    }
}

当我们通过bind方法,绑定成功后,就会得到merge标签的xml文件的Binding对象了。后面的使用就和普通的binding对象使用是一样的。

2.3 org.joda.time.LocalDate 中的日期获取

项目集成了implementation'com.necer.ncalendar:ncalendar:5.0.2' NCalendar库,实现日历效果展示。

而在该库中,针对日期数据使用的对象是LocalDate。而该对象是依赖于:joda-time 三方库的。

并不是使用java自带的LocalDate对象。
下面列一些该LocalData的常用方法:

  1. 获取当前时间 :LocalDate now = LocalDate.now();
  2. 默认输出:LocalDate.now().toString(); 默认输出 yyyy-MM-dd的日期。
  3. 按照指定格式输出:LocalDate.now().toString("MM月dd日"); 输出xx月xx日。
  4. 获取当前月份第一天:LocalDate firstDayOfCurrentMouth = now.dayOfMonth().withMinimumValue();
  5. 获取当前月份最后一天:LocalDate lastDayOfCurrentMouth = now.dayOfMonth().withMaximumValue();
  6. 获取上个月的最后一天:LocalDate lastDayOfPreviousMonth = now.minusMonths(1).dayOfMonth().withMaximumValue();
  7. 获取下个月的最后一天:LocalDate firstDayOfNextMouth = now.plusMonths(1).dayOfMonth().withMinimumValue();
关键字 意义 例子
G 时代 21
C 时代的世纪 21
Y 时代年份 2022
x 周年 2022
w 周年中第几周 27
e 一周中的星期几 2
E 一周中的星期几 Tue,Tuesday
y 2022
D 一年中的第几天 189
M 一年中的第几月 July,Jul,07
d 一个月中第几天 28(最大为31,根据月份来确定)
a 半天 PM
K 半天中的小时 0~11
h 半天的钟点(12小时制) 1~12
H 一天中的几个小时(24小时制) 0~23
k 一天的钟点 1~24
m 分钟 0~59
s 秒钟 0~59
S 毫秒 0~1000
z 时区 Pacific Standard Time; PST
Z 时区偏移量/id -0800; -08:00; America/Los_Angeles
文本转义
‘’ 单引号

PS: 可以直接阅读LocalDate源码,里面有详细的介绍

2.4 无侵入动态布局切换

我们如果想在Loading加载过程中,Empty空数据,Error 错误。等情况提供统一的UI显示,

那么可推荐https://github.com/li-xiaojun/StateLayout库。来实现

  • 对已有布局零侵入,无需修改现有布局
  • 支持对Activity, Fragment, View进行状态切换
  • 支持自定义每种状态的布局
  • 暴露失败状态View点击回调

PS: 我们如果通过java使用,想替换默认的加载布局,可以通过两种方式:

  1. 在xml中添加指定的加载布局:
 <com.lxj.statelayout.StateLayout
                app:sl_loadingLayoutId="@layout/layout_loading_dialog"
                android:id="@+id/statelayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

      <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/recycler"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
</com.lxj.statelayout.StateLayout>
  1. 我们直接创建一个命名为:_loading_layout_loading.xml的布局文件。在编译的时候由于名称相同。会自动覆盖掉StateLayout库中的布局文件。
1

评论区