欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

上传图片控件自定义,流式布局

程序员文章站 2022-05-30 22:11:53
...

控件模仿微信的,点击“+”上传图片,封装为一个控件,实现流式布局,超过一行自动换行排布。
这个流式布局的作用只是,排布,摆放,具体展示的图片是通过将xml布局inflate然后添加到该流式布局中来实现的。

package com.family.fw.view;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

/**
 * 流式布局。可根据子View的宽度实现自动换行。
 * 
 */
public class FlowLayout extends ViewGroup {

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public FlowLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FlowLayout(Context context) {
        super(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int[] size = measure(this, widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(size[0], size[1]);
    }

    static int[] measure(ViewGroup group, int widthMeasureSpec, int heightMeasureSpec) {
        int width = resolveSize(0, widthMeasureSpec);

        int pl = group.getPaddingLeft();
        int pt = group.getPaddingTop();
        int pr = group.getPaddingRight();
        int pb = group.getPaddingBottom();

        int left = pl;
        int top = pt;
        int right = width - pr;
        int lineHeight = 0;

        // 通过计算每一个子控件的高度,得到自己的高度
        for (int i = 0, childCount = group.getChildCount(); i < childCount; ++i) {
            View child = group.getChildAt(i);
            if (child.getVisibility() == View.GONE) {
                continue;
            }

            MarginLayoutParams layout = (MarginLayoutParams) child.getLayoutParams();
            child.measure(getChildMeasureSpec(widthMeasureSpec, pl + pr, layout.width),
                    getChildMeasureSpec(heightMeasureSpec, pt + pb, layout.height));

            int cow = child.getMeasuredWidth() + layout.leftMargin;
            int coh = child.getMeasuredHeight() + layout.topMargin + layout.bottomMargin;
            left += cow;

            if (left > right) {
                left = pl + cow;
                top += lineHeight;
                lineHeight = coh;
            } else if (coh > lineHeight) {
                lineHeight = coh;
            }
            left += layout.rightMargin;
        }

        return new int[] { width, resolveSize(top + lineHeight + pb, heightMeasureSpec) };
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        layout(this, changed, l, t, r, b);
    }

    static void layout(ViewGroup group, boolean changed, int l, int t, int r, int b) {
        int pl = group.getPaddingLeft();
        int left = pl;
        int top = group.getPaddingTop();
        int right = r - l - group.getPaddingRight();

        int lineHeight = 0;
        // 根据子控件的宽高,计算子控件应该出现的位置。
        for (int i = 0, childCount = group.getChildCount(); i < childCount; ++i) {
            View child = group.getChildAt(i);
            if (child.getVisibility() == View.GONE) {
                continue;
            }

            MarginLayoutParams layout = (MarginLayoutParams) child.getLayoutParams();
            int cw = child.getMeasuredWidth();
            int ch = child.getMeasuredHeight();
            int ml = layout.leftMargin;
            int mt = layout.topMargin;
            int thisH = ch + mt + layout.bottomMargin;
            left += ml;

            if (left + cw > right) {
                left = pl + ml;
                top += lineHeight;
                lineHeight = thisH;
            } else {
                lineHeight = Math.max(thisH, lineHeight);
            }
            child.layout(left, top + mt, left + cw, top + mt + ch);
            left += cw + layout.rightMargin;
        }
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }

}

在xml布局中:

<com.family.fw.view.FlowLayout
    android:id="@+id/evaluationImgs"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="20dp"
    android:paddingRight="20dp" >

    <ImageView
      android:id="@+id/img"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="10dp"
      android:background="@drawable/advice_image"
      android:contentDescription="@string/desc"
      android:scaleType="centerCrop"
      round:radius="5dp" />
  </com.family.fw.view.FlowLayout>

效果图:
上传图片控件自定义,流式布局

上传图片控件自定义,流式布局