乱序卡片自定义View-DisorderCardView

作者: 剑小河 | 来源:发表于2017-11-15 17:33 被阅读0次

先看图

设置gravity.gif

再看看点击卡片的效果和回调


点击卡片.gif

基本就是这样的效果,一般用在搜索栏的备选词或者热词

使用

使用起来也比较简单

<com.riverlet.disordercard.DisorderCardView
        android:id="@+id/disorder"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
------------------------------------------------------------------------------
        final DisorderCardView disorderCardView = findViewById(R.id.disorder);
        String[] datas = new String[]{"",""};
        disorderCardView.setData(Arrays.asList(datas));
        disorderCardView.setOnCarkClickListener(new DisorderCardView.OnCarkClickListener() {
            @Override
            public void onCardClick(String text) {
                Toast.makeText(MainActivity.this,text,Toast.LENGTH_SHORT).show();
            }
        });

也可以这样使用,把它当成一个可以让子布局自动换行的ViewGroup,不过卡片的样式就要自定义了,而且同一行的卡片高度要尽量一致

  <com.riverlet.disordercard.DisorderCardView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="火影忍者" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="火影忍者疾风传" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="王牌特工之特工学院" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="雷神3" />

    </com.riverlet.disordercard.DisorderCardView>

一些set代码

setGravity(Gravity.LEFT | Gravity.RIGHT | Gravity.CENTER_HORIZONTAL);//设置卡片靠左 | 靠右 | 水平居中
setCardTextColor(int cardTextColor);.//设置卡片文字颜色
setCardTextSize(int cardTextSize);//设置卡片文字大小
setCardBackground(int cardBackground);//设置卡片背景资源文件

实现代码

思路就是自动换行,当一行显示不了下一个卡片的全部的时候,自动排到下一行显示

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //遍历子View,测量每个View的大小
        for (int i = 0; i < getChildCount(); i++) {
            View view = getChildAt(i);
            measureChild(view, widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        realWidth = r - l - paddingLeft - paddingRight;
        realHeight = b - t - paddingTop - paddingBottom;
        Log.d(TAG, "realWidth:" + realWidth + "...realHeight:" + realHeight);
        computeAndLayout();
    }

    //计算每一行要显示的卡片
    private void computeAndLayout() {
        int childCount = getChildCount();
        if (realWidth > 0 && realHeight > 0 && childCount > 0) {
            int hadUsedWidth = 0;
            int hadUsedHeight = 0;
            int startIndex = 0;
            int endIndex = 0;
            for (int i = 0; i < getChildCount(); i++) {
                View itemView = getChildAt(i);
                int cardWidth = itemView.getMeasuredWidth();
                int cardHeight = itemView.getMeasuredHeight();

                hadUsedWidth += cardWidth;
                if (hadUsedWidth > realWidth) {
                    endIndex = i - 1;
                    layoutItemInRaw(startIndex, endIndex, hadUsedHeight, hadUsedWidth - cardWidth - vertcalSpace);
                    hadUsedHeight += cardHeight + horizontalSpace;
                    hadUsedWidth = cardWidth;
                    startIndex = i;
                }

                if (i == childCount - 1) {
                    endIndex = i;
                    layoutItemInRaw(startIndex, endIndex, hadUsedHeight, hadUsedWidth);
                }

                hadUsedWidth += vertcalSpace;
            }
        }
    }

    //布局一行的卡片位置
    private void layoutItemInRaw(int startIndex, int endIndex, int hadUsedHeight, int widthInRaw) {
        Log.d(TAG, "layoutItem...startIndex:" + startIndex + "...endIndex:" + endIndex + "...widthInRaw:" + widthInRaw + "...realWidth:" + realWidth);
        int hadUsedWidth = 0;
        int leftSpace = 0;
        switch (gravity) {
            case Gravity.CENTER_HORIZONTAL:
                leftSpace = realWidth / 2 - widthInRaw / 2;
                break;
            case Gravity.LEFT:
                leftSpace = 0;
                break;
            case Gravity.RIGHT:
                leftSpace = realWidth - widthInRaw;
                break;
        }

        for (int i = startIndex; i <= endIndex; i++) {
            View itemView = getChildAt(i);
            int cardWidth = itemView.getMeasuredWidth();
            int cardHeight = itemView.getMeasuredHeight();
            hadUsedWidth += cardWidth;
            int left = hadUsedWidth - cardWidth + leftSpace + paddingLeft;
            int right = hadUsedWidth + leftSpace + paddingLeft;
            int top = hadUsedHeight + paddingTop;
            int bottom = hadUsedHeight + cardHeight + paddingTop;
            hadUsedWidth += vertcalSpace;
            Log.d(TAG, "left:" + left + "...right:" + right + "...top:" + top + "...bottom:" + bottom);
            itemView.layout(left, top, right, bottom);
        }
    }

我的需求比较简单,写的也就比较简单,满足不了的小伙不可以下载代码修改
代码地址:DisorderCard

暴富小时候.jpg

相关文章

网友评论

    本文标题:乱序卡片自定义View-DisorderCardView

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