Android随机生成一个位置在界面上,不重复。

摘出项目中比较特殊的控件备用,参考同事的代码。

package com.fable.artedu.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.ScaleAnimation;
import android.widget.RelativeLayout;

import com.fable.artedu.R;
import com.fable.artedu.activity.TimeMachineActivity;

import java.util.ArrayList;
import java.util.Random;

//**
//
// * 可以添加随机位置View的布局!
// * 主要的思路是:
// * 1、位置随机
// * 2、防止覆盖
// */

public class RandomLayout<T> extends RelativeLayout {
    /**
     * 此列表用于保存随机的View视图
     * 在添加随机View的时候应当判断此视图是否有覆盖的
     * 有的话应该重新进行随机!
     */
    public ArrayList<View> randomViewList = new ArrayList<>();
    private OnRandomItemClickListener<T> onRandomItemClickListener;
    private OnRandomItemLongClickListener<T> onRandomItemLongClickListener;
    private boolean itemClickable = true;
    private boolean itemLongClickable = true;
    private Context context;
    public RandomLayout(Context context) {
        super(context);
    }
 
    public RandomLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setContext(Context context){
        this.context=context;
    }
 
    /**
     * 添加到一个随机的XY位置,且不重复。
     */
    public void addViewAtRandomXY(final View view, final T t) {
        if (view == null) return;
        view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
        post(new Runnable() {
            @Override
            public void run() {
                randomViewList.remove(view);
                // 100次随机上限
                for (int i = 0; i < 100; i++) {
                    int[] xy = createXY(
                            view.getMeasuredHeight(),
                            view.getMeasuredWidth()
                    );
                    if (randomViewList.size() == 0) {
                        addViewAndSetXY(view, xy[0], xy[1], t);
                    } else {
                        boolean isRepeat = false;
                        // 迭代已经存在的View,判断是否重叠!
                        for (View subView : randomViewList) {
                            // 得到XY
                            int x = (int) subView.getX();
                            int y = (int) subView.getY();
                            int width = subView.getMeasuredWidth();
                            int height = subView.getMeasuredHeight();
                            // 创建矩形
                            Rect v1Rect = new Rect(x, y, width + x, height + y);
                            Rect v2Rect = new Rect(xy[0], xy[1], view.getMeasuredWidth() + xy[0], view.getMeasuredHeight() + xy[1]
                            );
                            if (Rect.intersects(v1Rect, v2Rect)) {
                                isRepeat = true;
                                break;
                            }
                        }
                        if (!isRepeat) {
                            addViewAndSetXY(view, xy[0], xy[1], t);
                            return;
                        }
                    }
                }
            }
        });
    }
 
    public void addViewAndSetXY(View view, int x, int y, final T t) {

        removeView(view);
        addView(view);
        randomViewList.add(view);
        view.setX(x);
        view.setY(y);
        // 设置单击事件!
        view.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onRandomItemClickListener != null && isItemClickable()) {
                    onRandomItemClickListener.onRandomItemClick(v, t);
                }
            }
        });
        // 设置长按事件!
        view.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (onRandomItemLongClickListener != null && itemLongClickable)
                    return onRandomItemLongClickListener.onRandomItemLongClick(v, t);
                return false;
            }
        });
    }


    /**
     * 添加一个View到随机列表中,以此达到防止覆盖的效果!
     */
    public void addViewToRandomList(View view) {
        randomViewList.add(view);
    }
 
    /**
     * 清除所有的随机视图!
     */
    public void removeAllRandomView() {
        for (View v : randomViewList) {
            removeView(v);
        }
        randomViewList.clear();
    }
 
    /**
     * 从列表中移除一个随机视图!
     */
    public void removeRandomViewFromList(View view) {
        randomViewList.remove(view);
    }
 
    /**
     * 随机生成一个 0 到指定区间的值!
     *
     * @param max 0到max但是不包括max
     * @return 同上
     */
    private int random(int max) {
        // LogUtils.d("Max是:" + max);
        return new Random().nextInt(max);
    }
 
    /**
     * 根据传入的宽和高返回一个随机的座标!
     */
    @SuppressLint("NewApi")
    private int[] createXY(int height, int width) {
        int[] xyRet = new int[]{0, 0};
        // 初始化我们当前布局的屏幕XY!
        int layoutHeight = getMeasuredHeight();
        int layoutWidth = getMeasuredWidth();
        // 先随机一个X,注意一下就是,X轴是从View的左向右延申的
        // 注意,要减去内部填充!!!
        // LogUtils.d("paddingEnd: " + paddingEnd);
        xyRet[0] = random(
                layoutWidth - (
                        width + getPaddingStart() + getPaddingEnd()
                )
        );
        // LogUtils.d(" 布局宽度:" + layoutWidth + ",X轴:" + xyRet[0] + ",最终宽度:" + (xyRet[0] + width + paddingEnd + paddingStart));
        // 然后从Y是从View的上向下延申,所以我们需要进行下限值限制,避免越界!
        xyRet[1] = random(
                layoutHeight - (
                        height + getPaddingBottom() + getPaddingTop()
                )
        );
        return xyRet;
    }
 
    public boolean isItemClickable() {
        return itemClickable;
    }
 
    public void setItemClickable(boolean itemClickable) {
        this.itemClickable = itemClickable;
    }
 
    public boolean isItemLongClickable() {
        return itemLongClickable;
    }
 
    public void setItemLongClickable(boolean itemLongClickable) {
        this.itemLongClickable = itemLongClickable;
    }
 
    public OnRandomItemClickListener getOnRandomItemClickListener() {
        return onRandomItemClickListener;
    }
 
    public void setOnRandomItemClickListener(OnRandomItemClickListener<T> onRandomItemClickListener) {
        this.onRandomItemClickListener = onRandomItemClickListener;
    }
 
    public OnRandomItemLongClickListener<T> getOnRandomItemLongClickListener() {
        return onRandomItemLongClickListener;
    }
 
    public void setOnRandomItemLongClickListener(OnRandomItemLongClickListener<T> onRandomItemLongClickListener) {
        this.onRandomItemLongClickListener = onRandomItemLongClickListener;
    }
 
    public interface OnRandomItemClickListener<T> {
        void onRandomItemClick(View view, T t);
    }
 
    public interface OnRandomItemLongClickListener<T> {
        boolean onRandomItemLongClick(View view, T t);
    }
}
调用  初始化
  RandomLayout randomlayout = findViewById(R.id.randomlayout);
   randomlayout.setContext(this);

//添加View


调用方法

//设置占位view
public void setZwView() {
View view = LayoutInflater.from(TimeMachineActivity.this).inflate(R.layout.machine_ortherday_layout, null, false);
TextView textView = view.findViewById(R.id.tv_mac);
textView.setBackground(ContextCompat.getDrawable(TimeMachineActivity.this, R.mipmap.day_bg));
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight() - StringCompat.dip2px(TimeMachineActivity.this, 360);
view.setVisibility(View.INVISIBLE);
randomlayout.addViewAndSetXY(view, (width - StringCompat.dip2px(TimeMachineActivity.this, 109)) / 2, (height - StringCompat.dip2px(TimeMachineActivity.this, 109)) / 2, -1);
mHandler.postDelayed(runnable, 500);
}

//设置监听
randomlayout.setOnRandomItemClickListener();

//清除所有的View
randomlayout.removeAllRandomView();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章