千家信息网

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

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,本篇内容主要讲解"Android怎么实现可拖动层叠卡片布局",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Android怎么实现可拖动层叠卡片布局"吧!公司
千家信息网最后更新 2025年01月19日Android怎么实现可拖动层叠卡片布局

本篇内容主要讲解"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;i0){                if(level

显示出来就是这个样子

对于滑动显示下一张,则使用自定义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 mDatas){        adapter.addAdapterData(0,mDatas);        adapter.notifyDataSetChanged();        listener.onSwipe();    }    public SwipeCardCallBack(int dragDirs, int swipeDirs) {        super(dragDirs, swipeDirs);    }     public SwipeCardCallBack() {        /*        * 即我们对哪些方向操作关心。如果我们关心用户向上拖动,可以将         填充swipeDirs参数为LEFT | RIGHT 。0表示从不关心。        * */        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 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怎么实现可拖动层叠卡片布局"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0