瀑布流布局(横向)

自定义

public class CustomView extends ViewGroup {

//行数
private int Line = 3;
//每个孩子的高度
private int childHeight = 0;
//行间距
private int LineSpacing = 18;
//列间距
private int SpaceBetweenCols = 18;
//每一行的宽度
private int[] LineWidth;

public CustomView(Context context) {
    this(context, null);
}

public CustomView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    LineWidth = new int[Line];
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int mode = MeasureSpec.getMode(heightMeasureSpec);
    int size = MeasureSpec.getSize(heightMeasureSpec);

    measureChildren(widthMeasureSpec, heightMeasureSpec);

    childHeight = (size - (Line - 1) * SpaceBetweenCols) / Line;

    int warpHeight;

    int childCount = getChildCount();
    //
    if (childCount < Line) {
        warpHeight = childCount * childHeight + (childCount - 1) * LineSpacing;
    } else {
        warpHeight = size;
    }
    //清除所有记录,重新计算所有孩子
    cleanAllWidth();

    for (int i = 0; i < childCount; i++) {
        View childAt = this.getChildAt(i);
        int childWidth = (int) (childAt.getMeasuredWidth() * (float) childHeight / childAt.getMeasuredHeight());
        int position = getMinWidthPosition();

        LineWidth[position] += LineSpacing + childWidth;
    }

    int warpWidth;

    warpWidth = getMaxWidth();
    //重新计算宽高
    setMeasuredDimension(warpWidth, mode == MeasureSpec.AT_MOST ? warpWidth : size);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int childCount = getChildCount();
    cleanAllWidth();
    for (int i = 0; i < childCount; i++) {
        View childAt = this.getChildAt(i);
        int childWidth = (int) (childAt.getMeasuredWidth() * (float) childHeight / childAt.getMeasuredHeight());
        int mposition = getMinWidthPosition();
        //计算子控件的布局
        int left = LineWidth[mposition];
        int top = mposition * (childHeight + SpaceBetweenCols);
        int right = left + childWidth;
        int below = top + childHeight;

        LineWidth[mposition] += LineSpacing + childWidth;

        childAt.layout(left, top, right, below);
    }

}

//找到最小宽度的行下标
private int getMinWidthPosition() {
    int mposition = 0;
    for (int i = 0; i < Line; i++) {
        if (LineWidth[i] < LineWidth[mposition]) {
            mposition = i;
        }
    }
    return mposition;
}

//清除记录的宽度
private void cleanAllWidth() {
    for (int i = 0; i < Line; i++) {
        LineWidth[i] = 0;
    }
}

/**
 * 获取最宽那个行的宽度
 *
 * @return
 */
private int getMaxWidth() {
    int maxWidth = 0;
    for (int i = 0; i < Line; i++) {
        if (LineWidth[i] > maxWidth) {
            maxWidth = LineWidth[i];
        }
    }
    return maxWidth;
}

}

布局


主页

public class MainActivity extends AppCompatActivity {

private CustomView custom_view;
private Button bt;
private static int IMG_COUNT = 5;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    custom_view = findViewById(R.id.custom_view);
    bt = findViewById(R.id.bt);
    bt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            addHView(custom_view);
        }
    });
}

private void addHView(CustomView custom_view) {
    Random random = new Random();
    Integer num = Math.abs(random.nextInt());
    ViewGroup.LayoutParams layoutParams = new CustomView.LayoutParams(
            CustomView.LayoutParams.WRAP_CONTENT,
            CustomView.LayoutParams.WRAP_CONTENT
    );
    ImageView imageView = new ImageView(this);
     // final int[] img = {R.mipmap.pic_1, R.mipmap.pic_2, R.mipmap.pic_3, R.mipmap.pic_4, R.mipmap.pic_5};
    if (num % IMG_COUNT == 0) {
        imageView.setImageResource(R.mipmap.pic_1);
    } else if (num % IMG_COUNT == 1) {
        imageView.setImageResource(R.mipmap.pic_2);
    } else if (num % IMG_COUNT == 2) {
        imageView.setImageResource(R.mipmap.pic_3);
    } else if (num % IMG_COUNT == 3) {
        imageView.setImageResource(R.mipmap.pic_4);
    } else if (num % IMG_COUNT == 4) {
        imageView.setImageResource(R.mipmap.pic_5);
    }
    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    custom_view.addView(imageView, layoutParams);

}

}

你可能感兴趣的:(瀑布流布局(横向))