自定义循环卡片

作者: 不听话好孩子 | 来源:发表于2017-12-03 14:19 被阅读0次

基于ViewDragHelper实现的循环卡片

1.效果

github地址1

gif2

2.使用

> 1.数据设置

    viewDrag.setAdapter(new ViewDrag.DragCardAdapter<String>(list,5) {

            @Override
            public View getView(int i, String str, View conventView, ViewGroup viewGroup) {
                if(conventView==null){
                    conventView=getLayoutInflater().inflate(R.layout.ss,viewGroup,false);
                }
                TextView tv=conventView.findViewById(R.id.tv);
                tv.setText(str);
                tv.setBackgroundColor(colors[i%colors.length]);
                return conventView;
            }
        });
        
>  2.回掉监听
       viewDrag.setSettingViewCallBack(new ViewDrag.SettingViewCallBack() {
            //达到移除刚放手
            @Override
            void startSetting(View view, int position) {
                super.startSetting(view, position);
            }

            //移除动画动画结束
            @Override
            void endSetting(View view, int position) {
                super.endSetting(view, position);
            }

            //抓住了View
            @Override
            void captureView(View view, int position) {
                super.captureView(view, position);
            }
        });

3.实现

一. 基于ViewDragHelper实现拖动


ViewDragHelper的使用

  1. 在构造函授实例化一个 viewDragHelper = ViewDragHelper.create(this, 1, callback);
  2. 将触摸事件委托给viewDragHelper
  @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return viewDragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        viewDragHelper.processTouchEvent(event);
        return true;
    }
  1. 重写ViewDragHelper.Callback实现View的滑动逻辑

二. 封装一个BaseAdapter用于设置数据

cachedSize是屏幕最多显示的View数量

public static abstract class DragCardAdapter<T> extends BaseAdapter{
        List<T> list;
        int cachedSize=7;
       
        public DragCardAdapter(List<T> list,int cachedSize){
            this.list=list;
            this.cachedSize=cachedSize;
        }

        public int getCachedSize() {
            return cachedSize;
        }
        @Override
        public int getCount() {
            return list==null?0:list.size();
        }

        @Override
        public  View getView(int i, View conventView, ViewGroup viewGroup){
            return getView(i,list.get(i),conventView,viewGroup);
        }

        public abstract View getView(int i,T t, View conventView, ViewGroup viewGroup);
    }

3.设置缩放平移,达到视差效果

最大的缩放限制为1-0.3

for (int i = 0; i < attchedView.size(); i++) {
     attchedView.get(i).setTranslationY(-(attchedView.size()-i-1)*dp2px(10));
     getChildAt(i).setScaleX(1f-0.3f*(getChildCount()-i)/getChildCount());
     getChildAt(i).setScaleY(1f-0.3f*(getChildCount()-i)/getChildCount());
}

4. 循环的实现

用一个变量记录当前最前面卡片的adapter位置,当最外层的被移动到后面时,变量++,并把这个view和adapter位置传给Adapter的getview()重新设置数据。保证最多cachedSize的view在屏幕循环使用

//当前最前面的adapter位置
 currentFront++;
attchedView.remove(frontview);
//移除再重新添加到index为0的位置,让层级放到最后面
removeView(frontview)
//重新调用getview设置view的数据显示,并添加进来
View view = adapter.getView((currentFront+attchedView.size()) % adapter.getCount(), frontview, this);
attchedView.add(0,view);
addView(view,0);

4.总结


  • 基于利用ViewDragHepler实现View的拖拽,根据释放的位置坐标判断是移到后面,还是归原位。
  • 将数据委托给自定义Adapter来获取View,并在需要重新设置数据时,再次调用getView。
  • 如有兴趣,请查阅源码,查看细节github地址

相关文章

网友评论

    本文标题:自定义循环卡片

    本文链接:https://www.haomeiwen.com/subject/vquabxtx.html