摘出項目中比較特殊的控件備用,參考同事的代碼。
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();