【MyAndroid】RecyclerView+cardView卡片叠层效果展示(3)--100个经典UI设计模板(98/100)

在这里插入图片描述
布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
    tools:context=".CardOverlayRecyclerViewActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>

自定义布局管理器


public class CardLayoutManager extends RecyclerView.LayoutManager {
    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
        return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT, RecyclerView.LayoutParams.WRAP_CONTENT);
    }

    /**
     * 自定义LayoutManager核心是摆放控件,所以onLayoutChildren方法是我们要改写的核心
     *
     * @param recycler
     * @param state
     */
    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        //缓存
        detachAndScrapAttachedViews(recycler);

        //获取所有item(包括不可见的)个数
        int count = getItemCount();
        //由于我们是倒序摆放,所以初始索引从后面开始
        int initIndex = count - CardConfig.SHOW_MAX_COUNT;
        if (initIndex < 0) {
            initIndex = 0;
        }

        for (int i = initIndex; i < count; i++) {
            //从缓存中获取view
            View view = recycler.getViewForPosition(i);
            //添加到recyclerView
            addView(view);
            //测量一下view
            measureChild(view, 0, 0);

            //居中摆放,getDecoratedMeasuredWidth方法是获取带分割线的宽度,比直接使用view.getWidth()精确
            int realWidth = getDecoratedMeasuredWidth(view);
            int realHeight = getDecoratedMeasuredHeight(view);
            int widthPadding = (int) ((getWidth() - realWidth) / 2f);
            int heightPadding = (int) ((getHeight() - realHeight) / 2f);

            //摆放child
            layoutDecorated(view, widthPadding, heightPadding,
                    widthPadding + realWidth, heightPadding + realHeight);
            //根据索引,来位移和缩放child
            int level = count - i - 1;
            //level范围(CardConfig.SHOW_MAX_COUNT-1)- 0
            // 最下层的不动和最后第二层重叠
            if (level == CardConfig.SHOW_MAX_COUNT - 1) {
                level--;
            }
            view.setTranslationY(level * CardConfig.TRANSLATION_Y);
            view.setScaleX(1 - level * CardConfig.SCALE);
            view.setScaleY(1 - level * CardConfig.SCALE);
        }
    }
}

实现ItemTouchHelperCallback接口。启用ItemTouchHelper


public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {

    private List<String> mDatas;
    private RecyclerView.Adapter mAdapter;

    public ItemTouchHelperCallback(List<String> mDatas, RecyclerView.Adapter mAdapter) {
        this.mDatas = mDatas;
        this.mAdapter = mAdapter;
    }
/**
makeMovementFlags(p1,p2)
p1:侧滑删除使用:0忽略手势;ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.UP | ItemTouchHelper.DOWN
p2:拖动滑动使用:0忽略手势;ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.UP | ItemTouchHelper.DOWN
*/

    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {

        return makeMovementFlags(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.UP | ItemTouchHelper.DOWN);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) {
        return false;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
        String s = mDatas.remove(viewHolder.getLayoutPosition());
        mDatas.add(0, s);
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        //计算移动距离
        float distance = (float) Math.hypot(dX, dY);
        float maxDistance = recyclerView.getWidth() / 2f;

        //比例
        float fraction = distance / maxDistance;
        if (fraction > 1) {
            fraction = 1;
        }
        //为每个child执行动画
        int count = recyclerView.getChildCount();

        for (int i = 0; i < count; i++) {
            //获取的view从下层到上层
            View view = recyclerView.getChildAt(i);

            int level = CardConfig.SHOW_MAX_COUNT - i - 1;
            //level范围(CardConfig.SHOW_MAX_COUNT-1)-0,每个child最大只移动一个CardConfig.TRANSLATION_Y和放大CardConfig.SCALE

            if (level == CardConfig.SHOW_MAX_COUNT - 1) { // 最下层的不动和最后第二层重叠
                view.setTranslationY(CardConfig.TRANSLATION_Y * (level - 1));
                view.setScaleX(1 - CardConfig.SCALE * (level - 1));
                view.setScaleY(1 - CardConfig.SCALE * (level - 1));
            } else if (level > 0) {
                view.setTranslationY(level * CardConfig.TRANSLATION_Y - fraction * CardConfig.TRANSLATION_Y);
                view.setScaleX(1 - level * CardConfig.SCALE + fraction * CardConfig.SCALE);
                view.setScaleY(1 - level * CardConfig.SCALE + fraction * CardConfig.SCALE);
            }
        }

        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

		//控制滑动距离生效灵敏度
    @Override
    public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) {
        return 0.3f;
    }

然后结合Activity使用

rv.setLayoutManager(new CardLayoutManager());

        for (int i = 1; i < 21; i++) {
            mStrings.add(String.valueOf(i));
        }

        MyAdapter myAdapter = new MyAdapter(this, mStrings);
        rv.setAdapter(myAdapter);

        ItemTouchHelperCallback itemTouchHelperCallback = new ItemTouchHelperCallback(mStrings, myAdapter);
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemTouchHelperCallback);
        itemTouchHelper.attachToRecyclerView(rv);

搞定收工

自研产品推荐

历时一年半多开发终于smartApi-v1.0.0版本在2023-09-15晚十点正式上线
smartApi是一款对标国外的postman的api调试开发工具,由于开发人力就作者一个所以人力有限,因此v1.0.0版本功能进行精简,大功能项有:

  • api参数填写
  • api请求响应数据展示
  • PDF形式的分享文档
  • Mock本地化解决方案
  • api列表数据本地化处理
  • 再加上UI方面的打磨

为了更好服务大家把之前的公众号和软件激活结合,如有疑问请大家反馈到公众号即可,下个版本30%以上的更新会来自公众号的反馈。
嗯!先解释不上服务端原因,API调试工具的绝大多数时候就是一个数据模型、数据处理、数据模型理解共识的问题解决工具,所以作者结合自己十多年开发使用的一些痛点来打造的,再加上服务端开发一般是面向企业的,作者目前没有精力和时间去打造企业服务。再加上没有资金投入所以服务端开发会滞后,至于什么时候会进行开发,这个要看募资情况和用户反馈综合考虑。虽然目前国内有些比较知名的api工具了,但作者使用后还是觉得和实际使用场景不符。如果有相关吐槽也可以在作者的公众号里反馈蛤!
下面是一段smartApi使用介绍:
在这里插入图片描述

下载地址:

https://pan.baidu.com/s/1iultkXqeLNG4_eNiefKTjQ?pwd=cnbl

posted @ 2022-06-30 12:14  lichong951  阅读(50)  评论(0编辑  收藏  举报  来源