文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android怎么实现可拖动层叠卡片布局

2023-06-25 12:37

关注

本篇内容主要讲解“Android怎么实现可拖动层叠卡片布局”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android怎么实现可拖动层叠卡片布局”吧!

公司app要求做一个扭蛋功能,其实就是一个可拖动层叠卡片列表,原理还是由一个自定义Recyclerview和LayoutManager来实现

自定义RecyclerView很简单,只是修改touch事件,防止点击到卡片外还被处理的情况

@Override    public boolean onTouchEvent(MotionEvent e) {        if(e.getY()< UIUtil.dip2px(TutuApplication.getInstance().getContext(),95)||e.getY()>getHeight()-UIUtil.dip2px(TutuApplication.getInstance().getContext(),95)){            if(e.getAction()!=MotionEvent.ACTION_UP && e.getAction()!=MotionEvent.ACTION_MOVE) {                return false;            }        }        return super.onTouchEvent(e);    }

实际的层叠效果还是需要LayoutManager来实现

public class SwipeCardLayoutManager extends RecyclerView.LayoutManager {    Context context;    int TRANS_Y_GAP;    public SwipeCardLayoutManager(Context context){        TRANS_Y_GAP= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,15,                context.getResources().getDisplayMetrics());    }    @Override    public RecyclerView.LayoutParams generateDefaultLayoutParams() {        return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,                ViewGroup.LayoutParams.WRAP_CONTENT);    }     @Override    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {        super.onLayoutChildren(recycler, state);        //1.如何实现层叠效果--cardView.layout(l,t,r,b)        //2.如何让8个条目中的4个展示在RecylerView里面        //1在布局layout之前,将所有的子View先全部detach掉,然后放到Scrap集合里面缓存。        detachAndScrapAttachedViews(recycler);        //2)只将最上面4个view添加到RecylerView容器里面        int itemCount=getItemCount();//8个        int bottomPosition;        if(itemCount< CardConfig.MAX_SHOW_COUNT){            bottomPosition=0;         }else{            bottomPosition=itemCount-CardConfig.MAX_SHOW_COUNT;        }        for(int i=bottomPosition;i<itemCount;i++){            View view=recycler.getViewForPosition(i);            addView(view);            measureChildWithMargins(view,0,0);            int widthSpace=getWidth()-getDecoratedMeasuredWidth(view);            int heightSpace=getHeight()-getDecoratedMeasuredHeight(view);            //摆放cardView            //层叠效果--Scale+TranslationY            //层级的位置关系1/2/3/4            int level=itemCount-i-1;            layoutDecorated(view,                    widthSpace/2,                    heightSpace/2+StatusBarUtil.getStatusBarHeight(TutuApplication.getInstance().getContext()),                    widthSpace/2+getDecoratedMeasuredWidth(view),                    heightSpace/2+StatusBarUtil.getStatusBarHeight(TutuApplication.getInstance().getContext())+getDecoratedMeasuredHeight(view));             if(level>0){                if(level<CardConfig.MAX_SHOW_COUNT){                    view.setTranslationY(CardConfig.TRANS_V_GAP*level*1.3f);                    view.setScaleX(1-CardConfig.SCALE_GAP*level);                    view.setScaleY(1-CardConfig.SCALE_GAP*level);                }            }else {                view.setTranslationY(CardConfig.TRANS_V_GAP*(level-1));                view.setScaleX(1-CardConfig.SCALE_GAP*(level-1));                view.setScaleY(1-CardConfig.SCALE_GAP*(level-1));            }        }     }}

显示出来就是这个样子

Android怎么实现可拖动层叠卡片布局

对于滑动显示下一张,则使用自定义ItemTouchHelper.simpleCallBack来展示

自定义itemTouchHelper.simpleCallBack

public class SwipeCardCallBack extends ItemTouchHelper.SimpleCallback {    private GameGachaAdapter adapter;    private RecyclerView mRv;    private OnSwipeEndListener listener;    private TextView tv;    private int x = 1;    private Context context;     public void refresh(){//        x = 1;//        tv.setText(context.getResources().getString(R.string.explored)+(++x)+"/????");        removeCard();    }    public SwipeCardCallBack(GameGachaAdapter adapter, RecyclerView mRv, TextView view, Context context) {        super(0,                ItemTouchHelper.LEFT | ItemTouchHelper.UP |                        ItemTouchHelper.RIGHT | ItemTouchHelper.DOWN        );        this.adapter = adapter;        this.mRv = mRv;        this.tv = view;        this.context = context;    }    public void addGameGachaList(List<IMulTypeHelper> mDatas){        adapter.addAdapterData(0,mDatas);        adapter.notifyDataSetChanged();        listener.onSwipe();    }    public SwipeCardCallBack(int dragDirs, int swipeDirs) {        super(dragDirs, swipeDirs);    }     public SwipeCardCallBack() {                super(0,                ItemTouchHelper.LEFT | ItemTouchHelper.UP |                        ItemTouchHelper.RIGHT | ItemTouchHelper.DOWN        );    }      @Override    public boolean onMove(RecyclerView recyclerView,                          RecyclerView.ViewHolder viewHolder,                          RecyclerView.ViewHolder target) {        return false;    }     @Override    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {        //当已经滑动删除了的时候会被回掉--删除数据,循环的效果        removeCard();    }     public void removeCard() {        if(adapter!=null && adapter.getItemCount()>0) {            adapter.removeAdapterData(adapter.getItemCount() - 1);//        mDatas.add(0, remove);            adapter.notifyDataSetChanged();            listener.onSwipe();            if (adapter.getItemCount() == 6) {                listener.onSwipeEnd();            }            tv.setText(context.getResources().getString(R.string.explored) + (++x) + "/????");        }    }     @Override    public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {        super.clearView(recyclerView, viewHolder);    }     @Override    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);        //监听话滑动的距离--控制动画的执行程度         if(dY == 0f&&!isCurrentlyActive){            int itemcount = recyclerView.getChildCount();            for (int i = 0; i < itemcount; i++) {                //执行                View view = recyclerView.getChildAt(i);                //几个view层叠的效果,错开的效果--便宜动画+缩放动画                int level = itemcount - i - 1;                view.setRotation(0);                if(dX == 0) {                    if(level>0){                        if(level<CardConfig.MAX_SHOW_COUNT){                            view.setTranslationY(CardConfig.TRANS_V_GAP*level*1.3f);                            view.setScaleX(1-CardConfig.SCALE_GAP*level);                            view.setScaleY(1-CardConfig.SCALE_GAP*level);                        }                    }else {                        view.setTranslationY(CardConfig.TRANS_V_GAP*(level-1));                        view.setScaleX(1-CardConfig.SCALE_GAP*(level-1));                        view.setScaleY(1-CardConfig.SCALE_GAP*(level-1));                    }                }            }        }else {            //灵界点            double maxDistance = recyclerView.getWidth() * 1f;            double distance = Math.sqrt(dX * dX)*2;            //动画执行的百分比            double fraction = distance / maxDistance;            if (fraction > 1) {                fraction = 1;            }            int itemcount = recyclerView.getChildCount();            for (int i = 0; i < itemcount; i++) {                //执行                View view = recyclerView.getChildAt(i);                //几个view层叠的效果,错开的效果--便宜动画+缩放动画                int level = itemcount - i - 1;                if(level == 0){//最外层动画                    if(Math.abs(dX) == 1080f && dY == 0f&&!isCurrentlyActive){                        view.setRotation(0);                    }else {                        if(dX<0){                            view.setRotation((float) (360f - (30 * fraction)));                        }else {                            view.setRotation((float) (30 * fraction));                        }                    }                } else if(level ==CardConfig.MAX_SHOW_COUNT-1){//最内层动画                    view.setTranslationY((float) (CardConfig.TRANS_V_GAP*(level-fraction)*1.3f));                    view.setScaleX((float) (1-CardConfig.SCALE_GAP*(level-fraction)));                    view.setScaleY((float) (1-CardConfig.SCALE_GAP*(level-fraction)));                }else if (level < CardConfig.MAX_SHOW_COUNT - 1) {                    view.setTranslationY((float) ((level - (2*fraction)) * CardConfig.TRANS_V_GAP));                    view.setScaleX((float) (1 - CardConfig.SCALE_GAP * level + fraction * (CardConfig.SCALE_GAP*2)));                    view.setScaleY((float) (1 - CardConfig.SCALE_GAP * level + fraction * (CardConfig.SCALE_GAP*2)));                }             }        }     }     @Override    public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {        super.onSelectedChanged(viewHolder, actionState);    }     public interface OnSwipeEndListener{        void onSwipeEnd();        void onSwipe();    }    public void setOnSwipeEndListener(OnSwipeEndListener listener){        this.listener = listener;    }}

在Activity中:

private SwipeCardCallBack callback;private ItemTouchHelper helper;  ...helper = new ItemTouchHelper(callback); helper.attachToRecyclerView(swipeFlingAdapterView); callback.setOnSwipeEndListener(new SwipeCardCallBack.OnSwipeEndListener() {            @Override            public void onSwipeEnd() {                swipeFlingAdapterView.suppressLayout(true);                gameGachaRefresh.setClickable(false);                ToastUtils.createToast().showCenter(TutuGameGachaActivity.this,getString(R.string.wait_moment));                presenter.getGameGacha(PRESENTER_LOAD_STATE_REFRESH);            }             @Override            public void onSwipe() {                if(arrayAdapter.getItemCount()>0) {                    swipe();                }            }         });

到此,相信大家对“Android怎么实现可拖动层叠卡片布局”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯