利用Layout实现Button的不规则布局

工作中,有个哥们碰到了一个特殊的界面需求,就是按钮不按规则的布局。

这是自定义的一个布局文件UnruleMenu.java:

package com.wen.but;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.content.Context;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;

public class UnruleMenu extends FrameLayout {
    public final int WC = android.widget.LinearLayout.LayoutParams.WRAP_CONTENT;
    public final int MC = android.widget.LinearLayout.LayoutParams.MATCH_PARENT;
    // 屏幕高宽
    public int screenWidth;
    public int screenHeight;

    public UnruleMenu(Context context) {
        super(context);
        DisplayMetrics dm = getResources().getDisplayMetrics();
        screenWidth = dm.widthPixels;
        screenHeight = dm.heightPixels - 50;
        LayoutParams params = new LayoutParams(WC, WC);

        // Button b6 = new Button(context);
        // b6.setText("好的是的阿斯");
        // this.addView(b6, params);
        //
        // Button b7 = new Button(context);
        // b7.setText("阿斯顿飞而非");
        // this.addView(b7, params);

        Button b8 = new Button(context);
        b8.setText("打发斯蒂芬");
        this.addView(b8, params);

        Button b9 = new Button(context);
        b9.setText("对方如果飞");
        this.addView(b9, params);

        Button b10 = new Button(context);
        b10.setText("红烧牛仔");
        this.addView(b10, params);

        Button b11 = new Button(context);
        b11.setText("番茄蛋疼");
        this.addView(b11, params);

        Button but1 = new Button(context);
        but1.setText("几把烧饭");
        this.addView(but1, params);

        Button but2 = new Button(context);
        but2.setText("且自己当");
        this.addView(but2, params);

        Button but3 = new Button(context);
        but3.setText("阿斯达是");
        this.addView(but3, params);

        Button but4 = new Button(context);
        but4.setText("阿迪达斯");
        this.addView(but4, params);

        Button but5 = new Button(context);
        but5.setText("儿童的发");
        this.addView(but5, params);

        Button but6 = new Button(context);
        but6.setText("炒牛肉");
        this.addView(but6, params);

        Button but7 = new Button(context);
        but7.setText("炒猪肉");
        this.addView(but7, params);

        Button but8 = new Button(context);
        but8.setText("炒青菜");
        this.addView(but8, params);

        Button but9 = new Button(context);
        but9.setText("白菜");
        this.addView(but9, params);

        Button but10 = new Button(context);
        but10.setText("米饭");
        this.addView(but10, params);

        Button t1 = new Button(context);
        t1.setText("米饭");
        this.addView(t1, params);

        Button t2 = new Button(context);
        t2.setText("米饭");
        this.addView(t2, params);

        Button t3 = new Button(context);
        t3.setText("米饭");
        this.addView(t3, params);

        Button but11 = new Button(context);
        but11.setText("蛋疼");
        this.addView(but11, params);

        Button but12 = new Button(context);
        but12.setText("汤");
        this.addView(but12, params);

        Button but13 = new Button(context);
        but13.setText("水");
        this.addView(but13, params);

        Button but14 = new Button(context);
        but14.setText("肉");
        this.addView(but14, params);

        Button t4 = new Button(context);
        t4.setText("菜");
        this.addView(t4, params);

        rects = new ArrayList<Rect>();
    }

    List<Rect> rects = null;

    @Override
    protected void onLayout(boolean changed, int left, int top, int right,
            int bottom) {
        if (changed) {
            for (int i = 0; i < getChildCount(); i++) {
                Button button = (Button) getChildAt(i);
                Rect rect = getTwoLocation(button);
                button.layout(rect.left, rect.top, rect.right, rect.bottom);
            }
        }
        System.out.println("运行几次了");
    }

    public boolean isCovered(Rect rect, Rect tempRect) {
        // 如果重合,那么必定有一个坐标在重合区域内部
        // 左上坐标点
        if (rect.left >= tempRect.left && rect.left <= tempRect.right
                && rect.top >= tempRect.top && rect.top <= tempRect.bottom) {

            return true;
        }
        // 左下坐标点
        if (rect.left >= tempRect.left && rect.left <= tempRect.right
                && rect.bottom >= tempRect.top
                && rect.bottom <= tempRect.bottom) {
            return true;
        }
        // 右上坐标点
        if (rect.right >= tempRect.left && rect.right <= tempRect.right
                && rect.top >= tempRect.top && rect.top <= tempRect.bottom) {
            return true;
        }
        // 右下坐标点
        if (rect.right >= tempRect.left && rect.right <= tempRect.right
                && rect.bottom >= tempRect.top
                && rect.bottom <= tempRect.bottom) {
            return true;
        }
        return false;
    }

    public boolean beCovered(Rect rect) {
        for (int i = 0; i < rects.size(); i++) {
            Rect tempRect = rects.get(i);
            if (isCovered(rect, tempRect)) {
                return false;
            }
        }
        return true;
    }

    // 根据屏幕的宽高,获取在屏幕之内的区域坐标
    public Rect getTwoLocation(View childView) {
        int viewHeight = childView.getMeasuredHeight();
        int viewWidth = childView.getMeasuredWidth();
        Rect resu = null;
        boolean finish = true;
        int num1 = getRandoNum(15);
        int num2 = getRandoNum(screenWidth - viewHeight - 50);
        while (finish) {
            num1 += getRandoNum(20);
            if (num1 > screenWidth - viewWidth) {
                num1 = getRandoNum(10);
                if (num2 > screenWidth - viewHeight) {
                    num2 = getRandoNum(50);
                } else {
                    num2 += getRandoNum(10);
                }
            }
            resu = new Rect(num1, num2, num1 + viewWidth, num2 + viewHeight);
            if (beCovered(resu)) {
                finish = false;
                rects.add(resu);
                System.out.println(resu.left + "--------" + resu.top);
            }
        }
        return resu;
    }

    public Random random = null;

    // 获取随机数
    public int getRandoNum(int maxNum) {
        if (random == null) {
            random = new Random();
        }
        return random.nextInt(maxNum);
    }
}
原文地址:https://www.cnblogs.com/crazywenza/p/2961344.html