烟草仓储管理系统开发笔记(三)

本文最后更新于:2024年3月18日 晚上

IconFont字体的导入

正常使用

参考内容
由此本次项目中应该会多处使用到IconFont字体,以及更倾向于在xml文件中直接设置IconFont图标,而不是在Java代码中进行设置,因此采用的是自定义类的方式。

首先在IconFont网站上挑选好需要的图标,并添加到项目,然后进入到项目文件中将内容下载到本地。下载得到一个压缩包,解压后可以得到一个ttf后缀的文件,将其导入到Android Studio的assets文件夹中,assets文件夹默认没有创建,需要手动新建,文件夹跟java和res位于同一层级。之后在assets文件夹中创建iconfont文件夹,将ttf文件导入到其中。

然后新建一个自定义类IconFontTextView,继承自AppCompatTextView,重写其中的构造方法,在构造方法中调用一个自己新建的方法,新建的方法通过调用Typeface来渲染字体。具体代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class IconFontTextView extends AppCompatTextView {  
public IconFontTextView(@NonNull Context context) {
super(context);
Init(context);
}

public IconFontTextView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
Init(context);
}

public IconFontTextView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Init(context);
}

public void Init(Context context){
Typeface icon = Typeface.createFromAsset(context.getAssets(),"iconfont/iconfont.ttf");
setTypeface(icon);
}
}

之后在需要使用IconFont图标的时候,将默认的TextView改成自定义的IconFontTextView,并在其中填写IconFont代码即可。

菜单中使用

之前想着将抽屉菜单中的图标也用IconFont图标进行替换,但是菜单中的文本只是<Item>标签,也无法使用<TextView>标签,自然无法用自定义的IconFontTextView来替换了,因此行不通,最后只能将图标一个个以svg的形式下载下来,再从本地文件中导入到Android Studio中,通过Icon属性,将图标设置到菜单中。

客户信息界面实现

基本框架设计

总体想的以简洁的信息展示为主,大致结构布局如下

其中的Header块内容很简单,为一个菜单中对应的IconFont图标和对应的页面名称,通过中英文的搭配使整体更美观一点。

Item设计实现

其中Item部分设计主要分为两部分,左侧为一个ImageView,设想是添加客户的Logo,右侧则是垂直方向的三行文本框,用于显示客户信息。每个Item设定为圆角矩形,这一块原本想使用ShadowLayout来实现,但在使用时出现了一些兼容性问题^ShadowLayout,导致编译无法通过,所以改为使用上篇中提到的RWidgetHelper来实现,最终Item的呈现结果如下:

SearchBar实现

在之前重新学习时做的一个单词本Demo,那里使用到的搜索按钮自带动画,点击可以伸开搜索框填满整个标题栏,这里感觉很适合。因此尝试了一下,将一个Toolbar组件拖至RecycleView上方,将长度与RecycleView对齐,在其中添加一个SearchView,即实现了想要的效果,但其默认的搜索图标显示在左侧,且搜索框向右展开。但因为我还需要放置一个”添加”按钮,那么都放左边感觉怪怪的,一左一右就更奇怪了。于是就是网上查了查怎么将图标放到右侧,发现可以使用layout_gravity=right属性来将其移动到右侧,但是并没有效果,在仔细比对了代码后才发现,我这里的SearchView使用的是match_parents,所以是填满整个Toolbar的,将其改成wrap_content即可😂

然后在Toolbar组件中再使用IconFontTextView组件添加一个“+”的符号,即完成了Searchbar的效果。

Adapter实现

有了几个Layout文件后便是创建Adapter,这里使用的也是第三方库BaseRecyclerViewAdapterHelper ,虽然暂时也没用上其特定功能,但反正都是要用这个的,就先以其为框架,以后更加方便添加动画等效果。在Adapter中创建自定义的ViewHolder并继承BaseViewHolder,在其中定义视图中的组件,然后将泛型中的两个参数进行修改,前者为实例对象,即数据源,后者为自定义的ViewHolder,即视图,并重写其方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class CustomerListAdapter extends BaseQuickAdapter<CustomerTest, MyCustomerViewHolder> {  
public CustomerListAdapter(int layoutResId) {
super(layoutResId);
}

@Override
protected void convert(@NonNull MyCustomerViewHolder holder, CustomerTest customer) {
holder.name.setText(customer.getName());
holder.address.setText(customer.getAddress());
holder.purchase.setText(Arrays.toString(customer.getMainPurchase()).replace('[',' ').replace(']',' '));
}
}

class MyCustomerViewHolder extends BaseViewHolder{
TextView name,address,purchase;
public MyCustomerViewHolder(@NonNull View view) {
super(view);
name = view.findViewById(R.id.customerName);
address = view.findViewById(R.id.customerAddress);
purchase = view.findViewById(R.id.customerMainPurchase);
}
}

根据文档所说,在重写的convert方法中进行组件内容的赋值。

Fragment中使用

首先在Fragment中创建RecycleView和自定义Adapter的对象,之后通过adapter的setNewInstance方法为adapter赋值,再将adapter绑定到RecycleView上。

1
2
3
4
5
6
7
8
9
10
11
12
@Override  
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
adapter = new CustomerListAdapter(R.layout.item_customer_information);
adapter.setAnimationEnable(true);
recyclerView = getView().findViewById(R.id.customerRecycleview);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
//获取list数据
//设定adapter数据
adapter.setNewInstance(newList);
}

得到如下的最终显示结果:

添加点击事件

接下来为添加按钮和列表Item添加点击事件,当点击时,弹出一个底部对话框用于添加/修改信息,当是点击添加按钮弹出对话框时,则数据全为空,当点击列表Item弹出对话框时,默认数据为当前点击的Item的数据,可进行修改。
对话框使用第三方库DialogX 实现,采用其自定义视图的底部对话框进行实现,效果图如下

不知为何,这里的布局会进行压缩,此外在设计布局文件时也会出现设置为wrap_content时,底下仍会流出很大一块空白的情况,就像是固定了高度一样,不知什么原因,因此这个布局只是个半成品,待修改完后在下篇写。

遇到的问题

ShadowLayout中的兼容性问题

在兼容性报错中,其提示ShadowLayout使用了support库,而这和AndroidX冲突,而且我这里的设定也确实是useAndroidX=true,因此我以为ShadowLayout不支持AndroidX,但我还是发了Issue提问了一下,在开发者的告知下才知道,光有useAndroidX=true并不是开启了AndroidX,还需要在gradle.properties中添加android.enableJetifier=true才算支持AndroidX,即在gradle.properties中添加

1
2
android.useAndroidX=true  
android.enableJetifier=true

才算开启AndroidX

看是否需要将RWidgetHelper的那个布局改成ShadowLayout,毕竟ShadowLayout的阴影可调属性更多,更好看。


烟草仓储管理系统开发笔记(三)
http://starnight.top/2022/04/15/烟草仓储管理系统开发笔记(三)/
作者
Cardy Xie
发布于
2022年4月15日
许可协议