一、列表优化问题
先来看一下 app 原来的列表效果:
app原来效果
之前发现的问题已经优化建议有:
- 使用 TabLayout + ViewPager 使该页面可左右滑动;
- item 控件间距不规范,视觉效果不好;
- 使用 CardView。
1.1 TabLayout + ViewPager
这个没什么好说的,给新司机的一点小建议:Fragment 的复用。
创建 ViewPager 时一般会有多种类似的 Fragment,可以在创建时通过 setArguments()
方法将 Bundle 设置给 Fragment,然后在 Fragment 的 onCreateView()
获取该 Bundle。
举个栗子:
public class OfferFragment extends BaseFragment {
private String mCurrentType = "";
public static OfferFragment newInstance(String type) {
Bundle args = new Bundle();
args.putString("type", type);
OfferFragment fragment = new OfferFragment();
fragment.setArguments(args);
return fragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
...
if(null != getArguments()){
getBundleExtras(getArguments());
}
...
return v;
}
private void getBundleExtras(Bundle arguments) {
if (arguments.containsKey("type")) {
mCurrentType = arguments.getString("type");
}
}
这时就可以根据 mCurrentType 来获取不同类型的数据,当然也可以把这部分代码写到 BaseFragment 里。
1.2 item 布局规范
先来看一张从 MD 官网扣来的一张 三行列表(需科学上网) 的间距示意图:
列表:三行通过仔细观察上图可得出以下基本结论:
- item 最外层 padding 为 16dp;
- 第一行文字基线(Text baseline)与顶部距离为 28dp,再减去 padding 的 16dp,文字高度为 12dp;
- 第二行文字基线与第一行文字基线间距为 20dp,说明文字行间距为 8dp,也就是说第二行 marginTop=8dp。
- 带图片的可以根据以上标注调整图片位置以及大小。
然鹅,实际项目中一般 UI 会标注各个文本间距,上面权当是给没有 UI 的童鞋们一些参考。像我们的项目,以前也没有 UI,现在到我手上基本可以改改间距:
列表页面
大概就是这样子,看上去比之前好了很多,重点是 margin/pading 为 4dp 的倍数。比如第一行加粗标题,为了突出它,第二行与第一行间距为 12dp。第二到三四行的间距为 8dp,因为它们属于同级描述。
在外层套了 CardView,看上去就比较有立体感了。上图 item 布局 源码。
二、 CardView 的使用
CardView 的基本使用已经无需再提,本文记录 CardView 使用要注意的一些地方。先大概看一下效果:
5.0 以上 CardView效果2.1 CardView Style
- values 文件夹下 Style 设置示例:
<style name="CardViewStyle" parent="Widget.MaterialComponents.CardView">
<item name="android:layout_margin">4dp</item>
<item name="cardCornerRadius">4dp</item>
<item name="cardElevation">4dp</item>
<item name="android:foreground">?android:attr/selectableItemBackground</item>
</style>
-
圆角弧度:
cardCornerRadius
; -
阴影:
cardElevation
; -
点击相应:
android:foreground
;
- values-v21 文件夹,适配 21 以上版本设备。也就是说 Android 5.0 以上的设备会优先使用这个文件夹下的配置内容。其中一些配置低版本使用无效或不可使用。
<style name="CardViewStyle" parent="Widget.MaterialComponents.CardView">
<item name="android:layout_margin">4dp</item>
<item name="cardCornerRadius">4dp</item>
<item name="cardElevation">4dp</item>
<item name="android:foreground">?android:attr/selectableItemBackgroundBorderless</item>
<item name="android:stateListAnimator">@animator/mtrl_card_state_list_anim</item>
</style>
这里的 android:foreground
使用的是 selectableItemBackgroundBorderless
,android 内置的水波纹效果,也可以自定义效果,用来实现点击响应。
-
点击抬起阴影效果:
android:stateListAnimator
:API Level 21 引入的 z 轴动画,简单的说是 MD 的 UI 抬起动画。看一下mtrl_card_state_list_anim
代码:
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true">
<set>
<objectAnimator
android:duration="150"
android:propertyName="translationZ"
android:valueTo="15dp"
android:startDelay="75"
android:interpolator="@anim/mtrl_card_fast_interpolator"
android:valueType="floatType"/>
</set>
</item>
<item>
<set>
<objectAnimator
android:duration="150"
android:propertyName="translationZ"
android:valueTo="0dp"
android:interpolator="@anim/mtrl_card_lowers_interpolator"
android:valueType="floatType"/>
</set>
</item>
</selector>
-
android:duration
:动画时长; -
android:propertyName
:属性名称,translationZ 表示 Z 轴移动; -
android:valueTo
:移动到 15 dp; -
android:startDelay
:延时执行; -
android:interpolator
:插值器,控制动画执行速率,比如先慢后快、匀速等; -
android:valueType
:移动类型,此处为浮点数。
MD 示例 Z 轴抬起动画是在 CardView 拖拽时执行,本文 demo 中是在点击时触发,推荐在 CardView 移动时添加 Z 轴抬起下落动画。
image.png有关 CardView Style 设置还有更多属性,大家可根据需要查阅和添加。
2.2 RecyclerView + CardView
在本项目中,把 CardView 用于列表,既然是列表就需要用到 RecyclerView 了。常见的列表有横向的、纵向的,表格、瀑布流等等。上面展示的是纵向列表,接下来是瀑布流的实现:
瀑布流这样展示列表信息,与普通纵向相比:
- 优点:新颖,美观。同一页面可以展示更多信息。
- 缺点:信息展示过多过密集,容易引起视觉疲劳。
接下来看一下瀑布流的实现,核心代码在与给 RecyclerView 设置 LayoutManager:
//设置layoutManager
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2,
StaggeredGridLayoutManager.VERTICAL);
//解决item跳动
manager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
mRecyclerView.setLayoutManager(manager);
布局的话就比较简单了,使用 CardView 包裹 RelativeLayout,将所有 item 相对摆放即可。
2.3 item 展开动画
结合项目需求,假设货主用户发布某一订单之后,会有承运商来报价。页面默认展示最低报价,因为一般情况下,货主希望能以最低的价格把这批货运到目的地。那么如果想看其他承运商的报价,可以点击按钮展开报价信息。
展开动画这个效果的实现也比较简单,使用 RecyclerView 的局部刷新功能,让默认隐藏的更多报价展示:
mOfferAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
switch (view.getId()){
case R.id.btn_expand:
OfferBean bean = mOfferAdapter.getItem(position);
bean.setExpand(!bean.isExpand());
mOfferAdapter.notifyItemChanged(position,"payload");
break;
}
}
});
关于列表写到这里,下文记录 跳转动画 以及 CoordinatorLayout 的使用。
源码地址 欢迎 Star。
网友评论