仿iOS日历、飞书日历、Google日历的日模式
仿iOS日历、飞书日历、Google日历的日模式,24H内事件可自由上下拖动、自由拉伸。
以下是效果图:
具体实现比较简单,代码如下:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;import androidx.annotation.Nullable;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;//4、Java to c#
public class MultiRectView extends View {private Paint paintRect;private Paint borderPaint ;private Paint paintLine;private Paint paintDragText;private List<RectF> rectangles;private List<Map> rectanglesMapList;private RectF currentRect; // 当前操作的矩形private RectF preRect; // 操作的前一个矩形private int currentRectIndex = 0;// 当前被选中的矩形private float rectWidth = 200f; // 矩形宽度private float rectHeight = 100f; // 矩形高度private int currentHandle; // 记录当前操作的控制点private float lastX, lastY; // 手指最后位置private float preX, preY; // 手指起始位置private TextPaint textPaint;private Paint shadowPaint; // 用于阴影效果// 控制点private static final int NONE = -1;private static final int LEFT_TOP = 0;private static final int RIGHT_TOP = 1;private static final int LEFT_BOTTOM = 2;private static final int RIGHT_BOTTOM = 3;private static final int MOVE_RECT = 4;// 刻度设置private final int SCALE_INTERVAL = 30; // 30分钟private final int TOTAL_SCALES = 24 * 4; // 24小时,每小时4个15分钟刻度// 设置最小高度private final int MIN_RECT_HEIGHT = 100;long lineWidth = 6;long lineLen = 30;private String[] hours;private GestureDetector gestureDetector;private Context mContext;private onclickListener onclickListener;private onLongclicklistener onLongclickListener;private long longPressStartTime = 0;//长按时间private boolean isDragging = false;private ScrollView scrollView;private int mScaleWidth = 30;//上下间距private int mScaleLineX = 140;//横线距离左侧的起始距离点private int mScaleLineText = 30;//刻度的起始点private int mScaleRectToLeft = 150;//矩形距离左侧间距private List<String> texts; // 存储每个矩形内的文本private Canvas mCanvas;private String topText = "";private String bottomText = "";int topScale = 0;int bottomScale = 0;private RectF rectMove;private boolean isCancleClickStatus = true;private boolean isLongPressStatus = false;//长按状态//计时器,计时点击时长Timer timer;TimerTask timerTask;private final int LONGPRESSTIME = 500;//长按超过0.5秒,触发长按事件private float cornerRadius = 15f; // 圆角半径private List<ActiviesDataModel> activiesDataModelListl;private float offsetAmount = 20; // 偏移量,具体根据需求调整public MultiRectView(Context context) {super(context);mContext = context;init();}public MultiRectView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);mContext = context;init();}public MultiRectView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContext = context;init();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);int reHeight = resolveSize(heightSize, heightMeasureSpec);setMeasuredDimension(widthMeasureSpec, reHeight);}public void setScrollView(ScrollView scrollView1) {this.scrollView = scrollView1;}private void init() {texts = new ArrayList<>();rectangles = new ArrayList<>();rectanglesMapList = new ArrayList<>();// 初始化填充画笔paintRect = new Paint();paintRect.setAntiAlias(true);paintRect.setStyle(Paint.Style.FILL);paintRect.setColor(getResources().getColor(R.color.purple_200));paintRect.setStrokeCap(Paint.Cap.ROUND);paintRect.setStrokeWidth(3);//控制矩形宽高// 初始化边框画笔borderPaint = new Paint();borderPaint.setAntiAlias(true);borderPaint.setStyle(Paint.Style.STROKE);borderPaint.setColor(getResources().getColor(R.color.purple_300)); // 设置边框颜色为黄色borderPaint.setStrokeWidth(3); // 设置边框宽度//划线属性paintLine = new Paint();paintLine.setColor(Color.RED);//动态显示时间标签的画笔属性paintDragText = new Paint();paintDragText.setColor(Color.GREEN);paintDragText.setTextSize(30);//左侧时间的画笔属性textPaint = new TextPaint();textPaint.setColor(Color.BLACK);textPaint.setTextSize(32); // 设置文本大小//阴影shadowPaint = new Paint();shadowPaint.setAntiAlias(true);shadowPaint.setStyle(Paint.Style.FILL); // 设为填充样式shadowPaint.setColor(getResources().getColor(R.color.purple_300)); // 阴影主体的颜色shadowPaint.setShadowLayer(10f, 0f, 0f, getResources().getColor(R.color.black2)); // 设置阴影外圈渐变效果}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawScale(canvas); // 绘制刻度线、时间刻度for (int i = 0; i < rectangles.size(); i++) {if(i != currentRectIndex){// 绘制未选中的矩形RectF rect = rectangles.get(i);// 检查重叠并调整位置
// if (isOverlapping(rect, i)) {
// rect.left -= offsetAmount; // 向左偏移
// }drawRectAndText(canvas, rect, i);//画矩形框、内部写字drawCurrentScale(canvas, rect, i);//绘制显示实时刻度}}// 绘制当前选中的矩形,确保其在最上层if (currentRectIndex != -1) {RectF selectedRect = rectangles.get(currentRectIndex);drawRectAndText(canvas, selectedRect, currentRectIndex,true); // 画选中的矩形框、内部写字drawCurrentScale(canvas, selectedRect,currentRectIndex); // 绘制选中的矩形显示实时刻度}this.mCanvas = canvas;}private boolean isOverlapping(RectF currentRect, int currentIndex) {for (int i = 0; i < rectangles.size(); i++) {if (i != currentIndex) {RectF otherRect = rectangles.get(i);if (RectF.intersects(currentRect, otherRect)) {return true; // 矩形重叠}}}return false; // 矩形不重叠}private void drawScale(Canvas canvas) {// 绘制15分钟刻度线for (int n = 0; n <= TOTAL_SCALES; n++) {float y = n * mScaleWidth; // 计算刻度Y坐标// 计算并绘制时间标签(15分钟为单位)if (n % 4 == 0) { // 但每小时显示并绘制一次int hour = n / 4;if ((n / 4 + "").contains("24")) {hour = 0;}if (y == 0) {//第一根线防止画不全y = 15;}String timeText = String.format("%02d:00", hour);canvas.drawText(timeText, mScaleLineX - 100, y + 10, textPaint); // 绘制时间文本canvas.drawLine(mScaleLineX, y, getWidth() - 30, y + 20, paintLine); // 绘制刻度线}}}private String finalStartTime = "";private String finalEndTime = "";private void drawCurrentScale(Canvas canvas, RectF rect, int index) {//绘制显示实时的刻度// 计算矩形边界的时间刻度值topScale = (int) Math.round(rect.top / (mScaleWidth)); // 计算矩形上边界的刻度bottomScale = Math.round(rect.bottom / (mScaleWidth)); // 计算矩形下边界的刻度if (currentRect != rect) {//只有当前点击的矩形参与显示return;}boolean isLongPressStatus = (activiesDataModelListl.get(index)).isLongPressStatus();if (isLongPressStatus) {finalStartTime = "";finalEndTime = "";// 确保边界值在可用范围内if (topScale >= 0 && topScale < TOTAL_SCALES) {rectMove = rect;topText = String.format("%02d:%02d", topScale / 4, (topScale % 4) * 15);finalStartTime = topText;// canvas.drawText(topText, mScaleLineX + 10, rect.top + 20, textPaint); // 绘制上边界刻度canvas.drawText(topText, mScaleLineX - 100, rect.top + 20, paintDragText); // 绘制上边界刻度}if (bottomScale >= 0 && bottomScale < TOTAL_SCALES) {bottomText = String.format(" %02d:%02d", bottomScale / 4, (bottomScale % 4) * 15);finalEndTime = bottomText;canvas.drawText(bottomText, mScaleLineX - 100, rect.bottom - 10, paintDragText); // 绘制下边界刻度//canvas.drawText(bottomText, mScaleLineX + 10, rect.bottom - 10, textPaint); // 绘制下边界刻度}if (!TextUtils.isEmpty(finalStartTime) && !TextUtils.isEmpty(finalEndTime)) {//更新调整后的时间activiesDataModelListl.get(index).setStart_time(finalStartTime);activiesDataModelListl.get(index).setEnd_time(finalEndTime);}} else {}}private void drawRectAndText(Canvas canvas, RectF rect, int index) {canvas.drawRoundRect(rect, cornerRadius, cornerRadius, paintRect); // 绘制圆角矩形-填充canvas.drawRoundRect(rect, cornerRadius, cornerRadius, borderPaint); // 绘制圆角矩形-边框boolean isLongPressStatus = (activiesDataModelListl.get(index)).isLongPressStatus();//绘制矩形的四个边角if (isLongPressStatus) {if (currentRect != null && currentRect == rect) {// lt h 左上角// canvas.drawLine(rect.left, rect.top, rect.left + lineLen, rect.top, paintRect);// lt v// canvas.drawLine(rect.left, rect.top, rect.left, rect.top + lineLen, paintRect);// rt h 右上角// canvas.drawLine(rect.right - lineLen, rect.top, rect.right, rect.top, paintRect);// rt v// canvas.drawLine(rect.right, rect.top, rect.right, rect.top + lineLen, paintRect);// lb h左下角// canvas.drawLine(rect.left, rect.bottom, rect.left + lineLen, rect.bottom, paintRect);// lb v// canvas.drawLine(rect.left, rect.bottom - lineLen, rect.left, rect.bottom, paintRect);// rb h 右下角// canvas.drawLine(rect.right - lineLen, rect.bottom, rect.right, rect.bottom, paintRect);// rb v// canvas.drawLine(rect.right, rect.bottom - lineLen, rect.right, rect.bottom, paintRect);drawShadowEffect(canvas, rect); // 绘制阴影效果}}ActiviesDataModel activiesDataModel = activiesDataModelListl.get(index);String name = activiesDataModel.getPop_name();String address = activiesDataModel.getPop_address();int popdb_id = activiesDataModel.getPopdb_id();String startTime = activiesDataModel.getStart_time();String endTime = activiesDataModel.getEnd_time();String value = name + " \n " + address + " \n " + startTime + " -- " + endTime;// 绘制矩形内的文本StaticLayout staticLayout = new StaticLayout(value, textPaint,(int) rect.width(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);canvas.save();canvas.translate(rect.left, rect.top); // 移动画布到矩形的左上角staticLayout.draw(canvas);canvas.restore();}private void drawRectAndText(Canvas canvas, RectF rect, int index,boolean isInUp) {canvas.drawRoundRect(rect, cornerRadius, cornerRadius, paintRect); // 绘制圆角矩形-填充canvas.drawRoundRect(rect, cornerRadius, cornerRadius, borderPaint); // 绘制圆角矩形-边框boolean isLongPressStatus = (activiesDataModelListl.get(index)).isLongPressStatus();//绘制矩形的四个边角if (isLongPressStatus) {if (currentRect != null && currentRect == rect) {// lt h 左上角// canvas.drawLine(rect.left, rect.top, rect.left + lineLen, rect.top, paintRect);// lt v// canvas.drawLine(rect.left, rect.top, rect.left, rect.top + lineLen, paintRect);// rt h 右上角// canvas.drawLine(rect.right - lineLen, rect.top, rect.right, rect.top, paintRect);// rt v// canvas.drawLine(rect.right, rect.top, rect.right, rect.top + lineLen, paintRect);// lb h左下角// canvas.drawLine(rect.left, rect.bottom, rect.left + lineLen, rect.bottom, paintRect);// lb v// canvas.drawLine(rect.left, rect.bottom - lineLen, rect.left, rect.bottom, paintRect);// rb h 右下角// canvas.drawLine(rect.right - lineLen, rect.bottom, rect.right, rect.bottom, paintRect);// rb v// canvas.drawLine(rect.right, rect.bottom - lineLen, rect.right, rect.bottom, paintRect);drawShadowEffect(canvas, rect); // 绘制阴影效果}}ActiviesDataModel activiesDataModel = activiesDataModelListl.get(index);String name = activiesDataModel.getPop_name();String address = activiesDataModel.getPop_address();int popdb_id = activiesDataModel.getPopdb_id();String startTime = activiesDataModel.getStart_time();String endTime = activiesDataModel.getEnd_time();String value = name + " \n " + address + " \n " + startTime + " -- " + endTime;// 绘制矩形内的文本StaticLayout staticLayout = new StaticLayout(value, textPaint,(int) rect.width(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);canvas.save();canvas.translate(rect.left, rect.top); // 移动画布到矩形的左上角staticLayout.draw(canvas);canvas.restore();}private void drawShadowEffect(Canvas canvas, RectF rect) {// 绘制阴影canvas.drawRoundRect(rect, cornerRadius, cornerRadius, shadowPaint); // 绘制圆角矩形}@Overridepublic boolean onTouchEvent(MotionEvent event) {float currentX = event.getX();float currentY = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 检查是否按下了控制点longPressStartTime = 0;for (int i = 0; i < rectangles.size(); i++) {RectF rect = rectangles.get(i);if (isInHandle(currentX, currentY, rect, LEFT_TOP)) {currentRect = rect;currentHandle = LEFT_TOP;} else if (isInHandle(currentX, currentY, rect, RIGHT_TOP)) {currentRect = rect;currentHandle = RIGHT_TOP;} else if (isInHandle(currentX, currentY, rect, LEFT_BOTTOM)) {currentRect = rect;currentHandle = LEFT_BOTTOM;} else if (isInHandle(currentX, currentY, rect, RIGHT_BOTTOM)) {currentRect = rect;currentHandle = RIGHT_BOTTOM;} else if (rect.contains(currentX, currentY)) {// 检测是否按下矩形currentRectIndex = i;longPressStartTime = System.currentTimeMillis(); // 记录长按开始时间currentRect = rect;currentHandle = MOVE_RECT;if (preRect != currentRect) {//前后两个矩形不是同一个// isLongPressStatus = false;}timer = new Timer();timerTask = new TimerTask() {@Overridepublic void run() {//长按逻辑触发if(currentRectIndex!=-1){activiesDataModelListl.get(currentRectIndex).setLongPressStatus(true);// 长按触摸区域,禁止父容器 (ScrollView) 拦截触摸事件if (scrollView != null) {scrollView.requestDisallowInterceptTouchEvent(true);}}invalidate(); // 刷新视图}};timer.schedule(timerTask, LONGPRESSTIME, 1000 * 60 * 60 * 24);} else {// activiesDataModelListl.get(i).setLongPressStatus(false);}}lastX = currentX;lastY = currentY;preX = currentX;preY = currentY;isCancleClickStatus = true;try {boolean longPressStatus = activiesDataModelListl.get(currentRectIndex).isLongPressStatus();if (currentRect != null && longPressStatus) {// 触摸区域在矩形内,禁止父容器 (ScrollView) 拦截触摸事件if (scrollView != null) {scrollView.requestDisallowInterceptTouchEvent(true);}}} catch (Exception e) {e.getMessage();}break;case MotionEvent.ACTION_MOVE:if (currentRect != null) {float dx = currentX - lastX;float dy = currentY - lastY;boolean isLongPressStatus = false;if(currentRectIndex!=-1){isLongPressStatus = (activiesDataModelListl.get(currentRectIndex)).isLongPressStatus();}switch (currentHandle) {case LEFT_TOP:// currentRect.left += dx;//只允许上下拉伸 禁止左右拉伸if (isLongPressStatus) {currentRect.top += dy;}break;case RIGHT_TOP:// currentRect.right += dx;if (isLongPressStatus) {currentRect.top += dy;}break;case LEFT_BOTTOM:// currentRect.left += dx;if (isLongPressStatus) {currentRect.bottom += dy;}break;case RIGHT_BOTTOM:// currentRect.right += dx;if (isLongPressStatus) {currentRect.bottom += dy;}break;case MOVE_RECT:if (currentRectIndex != -1) {long pressDuration = System.currentTimeMillis() - longPressStartTime;if (isLongPressStatus) {//长按的时间长度// isDragging = true; // 开始拖动// 计算拖动距离RectF rect = rectangles.get(currentRectIndex);rect.offset(0, (int) dy);//dx=0 只允许Y轴滑动 不允许x轴左右滑动}}break;}for (int n = 0; n < rectangles.size(); n++) {RectF rect = rectangles.get(n);boolean isLongPressStatusTemp = (activiesDataModelListl.get(n)).isLongPressStatus();if (rect != currentRect) {activiesDataModelListl.get(n).setLongPressStatus(false);}}//取消计时timerTask.cancel();timer.cancel();// 更新最后位置lastX = currentX;lastY = currentY;invalidate(); // 刷新视图}break;case MotionEvent.ACTION_UP:if (currentRect != null) {float dx = currentX - preX;float dy = currentY - preY;boolean isLongPressStatus = false;if(currentRectIndex!=-1){isLongPressStatus = (activiesDataModelListl.get(currentRectIndex)).isLongPressStatus();}if (dx == 0 && dy == 00) {//此处应该用绝对值来判断一个较小的数值if (!isLongPressStatus) {//不是长按状态的矩形boolean isHasTrue = false;for (int n = 0; n < rectangles.size(); n++) {RectF rect = rectangles.get(n);boolean isLongPressStatusTemp = (activiesDataModelListl.get(n)).isLongPressStatus();if (isLongPressStatusTemp) {isHasTrue = true;//检查是否存在点击状态的矩形}if (rect != currentRect) {activiesDataModelListl.get(n).setLongPressStatus(false);}}invalidate(); // 刷新视图if (isHasTrue) {} else {//如果没有选中状态矩形 则允许回调点击事件if (onclickListener != null) {onclickListener.onclick(currentRectIndex + "--" + activiesDataModelListl.get(currentRectIndex).getPop_name());}}} else {//点击的是长按状态的矩形}}preRect = currentRect;} else {//点击在非矩形区域isCancleClickStatus = false;// isLongPressStatus = false;try {(activiesDataModelListl.get(currentRectIndex)).setLongPressStatus(false);} catch (Exception e) {e.getMessage();}invalidate(); // 刷新视图}// currentRectIndex = -1; // 取消触摸currentRect = null;currentHandle = NONE;//取消计时timerTask.cancel();timer.cancel();try {boolean longPressStatusUp = activiesDataModelListl.get(currentRectIndex).isLongPressStatus();// 恢复父容器 (ScrollView) 拦截触摸事件if (scrollView != null && !longPressStatusUp) {scrollView.requestDisallowInterceptTouchEvent(false);}} catch (Exception e) {e.getMessage();}break;case MotionEvent.ACTION_CANCEL:currentHandle = NONE;currentRectIndex = -1; // 取消触摸isLongPressStatus = false;// (activiesDataModelListl.get(currentRectIndex)).setLongPressStatus(false);// 恢复父容器 (ScrollView) 拦截触摸事件if (scrollView != null) {scrollView.requestDisallowInterceptTouchEvent(false);}break;}return true;}private boolean isInHandle(float x, float y, RectF rect, int handle) {float handleSize = 60f; // 控制点的尺寸switch (handle) {case LEFT_TOP:return x >= rect.left - handleSize / 2 && x <= rect.left + handleSize / 2 &&y >= rect.top - handleSize / 2 && y <= rect.top + handleSize / 2;case RIGHT_TOP:return x >= rect.right - handleSize / 2 && x <= rect.right + handleSize / 2 &&y >= rect.top - handleSize / 2 && y <= rect.top + handleSize / 2;case LEFT_BOTTOM:return x >= rect.left - handleSize / 2 && x <= rect.left + handleSize / 2 &&y >= rect.bottom - handleSize / 2 && y <= rect.bottom + handleSize / 2;case RIGHT_BOTTOM:return x >= rect.right - handleSize / 2 && x <= rect.right + handleSize / 2 &&y >= rect.bottom - handleSize / 2 && y <= rect.bottom + handleSize / 2;default:return false;}}public void addRectangle(float left, float top, int tags, String textC) {//rectWidth = getWidth()-400;RectF rect = new RectF(left, top, 1010, top + rectHeight);Map<Integer, RectF> map = new HashMap<Integer, RectF>();map.put(tags, rect);texts.add(textC);rectanglesMapList.add(map);rectangles.add(rect);invalidate(); // 刷新视图}public void addRectangle(ArrayList<ActiviesDataModel> list) {this.activiesDataModelListl = list;for (int i = 0; i < activiesDataModelListl.size(); i++) {ActiviesDataModel activiesDataModel = activiesDataModelListl.get(i);String name = activiesDataModel.getPop_name();String address = activiesDataModel.getPop_address();int popdb_id = activiesDataModel.getPopdb_id();String startTime = activiesDataModel.getStart_time();String endTime = activiesDataModel.getEnd_time();// 需要根据具体的业务逻辑计算 left 和 topfloat top_start = formatTimeToYValues(startTime);float bootom_end = formatTimeToYValues(endTime);float rect_height = bootom_end - top_start;float rect_width = this.getWidth() - mScaleRectToLeft;RectF rect = new RectF(mScaleRectToLeft, top_start, 1010, top_start + rect_height);Map<Integer, RectF> map = new HashMap<>();map.put(i, rect);texts.add(name + " \n " + address + " \n " + startTime + " \n " + endTime);rectanglesMapList.add(map);rectangles.add(rect);}invalidate(); // 刷新视图}// 转换刻度值为时间字符串private float formatTimeToYValues(String time_value) {float y_value = 0;String closesTime = findClosestTimeRange(time_value);// 绘制15分钟刻度线for (int n = 0; n <= TOTAL_SCALES; n++) {float y = n * mScaleWidth; // 计算刻度Y坐标int hour = n / 4;int minute = (n % 4) * 15; // 每个刻度15分钟if ((n / 4 + "").contains("24")) {hour = 0;}String timeHMText = String.format("%02d:%02d", hour, minute);if (closesTime.equals(timeHMText)) {y_value = y;break;}}return y_value;}public String findClosestTimeRange(String time) {String[] parts = time.split(":");int hour = Integer.parseInt(parts[0]);int minute = Integer.parseInt(parts[1]);int totalMinutes = hour * 60 + minute;// 找到最接近的15分钟的倍数int closestMultiple = Math.round((float) totalMinutes / 15) * 15;// 将最接近的总分钟数转换回HH:MM格式int closestHour = closestMultiple / 60;int closestMinute = closestMultiple % 60;return String.format("%02d:%02d", closestHour, closestMinute);}public void setonclicklistener(onclickListener listener) {this.onclickListener = listener;}public void setonLongclicklistener(onLongclicklistener listener) {this.onLongclickListener = listener;}public interface onclickListener {void onclick(String value);}public interface onLongclicklistener {void onLongclick(String value);}}
外面传入数据调用即可:
MultiRectView multiRectView = findViewById(R.id.multiRectView);multiRectView.setonclicklistener(this);multiRectView.setonLongclicklistener(this);multiRectView.setScrollView(scrollView);ActiviesDataModel activiesDataModel1 = new ActiviesDataModel();activiesDataModel1.setPop_name(" POP Name1 万客隆精选超市");activiesDataModel1.setPop_address("南京东路1024弄");activiesDataModel1.setPopdb_id(215639);activiesDataModel1.setStart_time("06:40");activiesDataModel1.setEnd_time("08:30");ActiviesDataModel activiesDataModel2 = new ActiviesDataModel();activiesDataModel2.setPop_name(" POP Name2 京东自营超市");activiesDataModel2.setPop_address("南京东路1024弄");activiesDataModel2.setPopdb_id(215638);activiesDataModel2.setStart_time("09:10");activiesDataModel2.setEnd_time("11:50");ActiviesDataModel activiesDataModel3 = new ActiviesDataModel();activiesDataModel3.setPop_name(" POP Name3 拼多多百亿补贴超市");activiesDataModel3.setPop_address("南京东路1024弄");activiesDataModel3.setPopdb_id(215637);activiesDataModel3.setStart_time("12:40");activiesDataModel3.setEnd_time("14:30");ActiviesDataModel activiesDataModel4 = new ActiviesDataModel();activiesDataModel4.setPop_name(" POP Name4 淘宝天猫超市");activiesDataModel4.setPop_address("南京东路1024弄");activiesDataModel4.setPopdb_id(215636);activiesDataModel4.setStart_time("15:40");activiesDataModel4.setEnd_time("17:30");
相关文章:
仿iOS日历、飞书日历、Google日历的日模式
仿iOS日历、飞书日历、Google日历的日模式,24H内事件可自由上下拖动、自由拉伸。 以下是效果图: 具体实现比较简单,代码如下: import android.content.Context; import android.graphics.Canvas; import android.graphics.Color;…...
机器人构建详解:售前售后服务客服机器人与广告生成机器人的微调数据处理方法
引言 大模型(如BERT、GPT等)在自然语言处理任务中展现了强大的能力,但为了使其更贴合特定应用场景,通常需要进行微调。本文将详细讲解如何为售前售后服务的客服机器人和广告生成机器人准备高质量的微调数据,并通过具体…...
【飞机纵向动力学建模与分析】
飞机纵向动力学建模与分析 文章目录 飞机纵向动力学建模与分析前言坐标系定义及转换机体坐标系定义机体坐标系定义气流角定义气流坐标系与机体坐标系相互转化 纵向动力学方程建立力的分解动力学方程的建立纵向动力学方程纵向动力学方程状态空间表达形式纵向运动分析短周期简化处…...
【机器人】控制之稳定性判定: 李雅普诺夫Lyapunov (7) 判定是否是李函数,思维导图
要判断一个函数 V(x)是否可以作为某个动力学方程的 Lyapunov 函数,需要满足特定的数学和物理条件。以下是详细说明: 1. 满足 Lyapunov 函数的基本条件 一个函数 V(x)能否作为 Lyapunov 函数,需要满足以下基本条件: 1.1 正定性 …...
Qwen 论文阅读记录
本文仅作自己初步熟悉大模型,梳理之用,慢慢会更改/增加/删除,部分细节尚未解释,希望不断学习之后,能够完善补充。若有同道之人,欢迎指正探讨。 关于后面的code-qwen and math-qwen,我个人认为依…...
ViewModel
ViewMode是MVVM架构模式中VM层对应的类,它的作用是存储界面数据,并和界面发生数据交互。ViewModel能感知生命周期,并且在界面由于配置问题发生重建时候,可以保持当前的数据不变。生命周期如下: ViewMode由ViewModePr…...
AI和SEO的完美结合关键词策略解析
内容概要 在当今数字营销环境中,AI与SEO的结合已成为提升网站流量和转化率的重要策略。为了更好地理解这一主题,本文将首先介绍AI技术在数字营销中的多种应用,其次分析SEO的基础知识和重要性,以便为后续讨论建立坚实的基础。 提示…...
网络基础 - TCP/IP 五层模型
文章目录 一、OSI 参考模型中各个分层的作用1、应用层2、表示层3、会话层4、传输层5、网络层6、数据链路层7、物理层 二、OSI 参考模型通信处理示例 一、OSI 参考模型中各个分层的作用 1、应用层 2、表示层 负责设备固有数据格式和网络标准数据格式间的转换 实际生活中&#…...
pyenv 管理多个 Python 版本(1)
引言 你是否曾希望参与一个支持多个 Python 版本的项目,但又不知道如何轻松地测试所有这些版本?你是否对 Python 的最新版本感到好奇?或许你想尝试这些新功能,但又不想冒险破坏你的开发环境。幸运的是,如果你使用 pyen…...
LLMs之ICL:《Bayesian scaling laws for in-context learning》翻译与解读
LLMs之ICL:《Bayesian scaling laws for in-context learning》翻译与解读 导读:这篇论文的核心议题是理解和建模大型语言模型(LLM)的上下文学习(ICL)能力。文章从贝叶斯学习的角度出发,提出了一…...
泷羽Sec学习笔记-Bp中ip伪造、爬虫审计
ip伪造与爬虫审计 ip伪造 下载插件:burpFakeIP 地址:GitHub - TheKingOfDuck/burpFakeIP: 服务端配置错误情况下用于伪造ip地址进行测试的Burp Suite插件 python版需要配置jython:下载地址:Maven Central: org.python:jython-…...
常用vim命令行-linux008
Vim 是一款功能强大的文本编辑器,广泛应用于编程、配置文件编辑以及日常文本处理。Vim 在其命令行模式下提供了丰富的操作命令,这些命令能够大幅提升编辑效率。以下是 Vim 中常用的命令及操作的总结,覆盖了 Vim 中的基本操作、查找、替换、文…...
Linux相关概念和易错知识点(24)(认识信号、信号捕捉)
目录 1.认识信号 (1)后台进程和前台进程 ①为什么Ctrl C能终止前台进程? ②如何终止这个后台程序? (2)信号、异步和同步 ①同步 ②异步 (3)信号的处理 2.信号捕捉 &#x…...
Scala的导入
//导入 //(1) 创建包:在src上右键,新建软件包 //(2)填写包名:小写 //(3)在包上右键,创建类。自动加入包名 //(4)导入。import 包名.类名 //导入多个类 //import jh.yuanlixueyuan.bigdata.scala03.{A,B,C} //导入包下的所有的类 /…...
strace,tcmalloc,asan使用
1、strace使用 1.1、编译strace strace开源库 解压strace-4.21.tar.xz 编译./configure --hostarm-ca9-linux-gnueabihf --prefix~/out make&&make install 1.2、参数 -c 统计每一系统调用的所执行的时间,次数和出错的次数等. -d 输出strace关于标准错误的调试信息…...
C++中多态性在实际项目中的应用场景;C++中面向对象编程实现数据隐藏的方法
1. C中多态性在实际项目中的应用场景 C中多态性是面向对象编程中的一个重要概念,它允许我们在使用基类指针或引用的情况下,调用派生类对象的特定方法。这种灵活性使得多态性在实际项目中有着广泛的应用场景,具体包括但不限于以下几个方面&am…...
【QT常用技术讲解】使用QMovie+QLabel播放gif动态图片,实现“正在加载”功能(源代码在资源中下载)
前言 界面在实现事件等待时,通过会显示一个转圈圈的动态图片,表示“正在加载”,事件完成之后关闭图片,QT中可以使用QMovieQLabel完成gif动态图片的播放及关闭的效果。 效果图 功能讲解 1、加载动画 void MainWindow::addloadgi…...
iPhone苹果相册视频怎么提取音频?
在数字时代,视频已成为我们记录生活、分享故事的重要方式。然而,有时候我们只想保留视频中的音频部分,比如一段动人的背景音乐或是一段珍贵的对话。那么,苹果相册视频怎么提取音频呢?本文将介绍三种简单且实用的方法&a…...
【PyTorch】动态调整学习率 torch.optim.lr_scheduler.StepLR 调度器
文章目录 1. torch.optim.lr_scheduler.StepLR 官方文档详解2. 使用示例2.1 官方提供使用示例2.2 自己写代码测试方法2.2.1 get_last_lr() 方法2.2.2 state_dict() 方法2.2.3 load_state_dict() 保存和加载调度器 3. 思考3.1 为什么需要state_dict()3.2 get_lr() 与 get_last_l…...
完全二叉树的节点个数
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。 完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最…...
在销售管理中,客户跟进时会出现什么问题?如何解决?
客户跟进表是销售工作中重要的一部分,用于记录与客户的每次沟通、执行计划和合作动态。然而,在实际使用中,客户跟进表经常会出现一些问题,导致效率低下甚至客户流失。本文就从常见问题出发,一一提供措施,让…...
【代码随想录|动态规划】
一、动态规划理论基础 |、动态规划包含题目类型 (1)背包问题 (2)打家劫舍 (3)股票问题 (4)子序列问题 ||、做一道题需要掌握(动态规划5步曲)࿱…...
时间敏感网络与工业通信的融合:光路科技电力专用交换机和TSN工业交换机亮相EP电力展
12月7日,第三十一届中国国际电力设备及技术展览会(EP Shanghai 2024)暨上海国际储能技术应用展览会在上海新国际博览中心圆满落幕。本届展会以“数字能源赋能新质生产力”为主题,系统地呈现了电力设备行业在技术融合、转型升级及上…...
初识Linux · 系统编程done
目录 前言: 死锁 可重入函数 读写锁 自旋锁 前言: 本文作为Linux系统编程的收尾工作,介绍的是些零碎的概念,比如死锁,可重入函数,自旋锁,读写锁等,其中死锁概念要重要些&#…...
JavaScript函数式编程: 实现不可变数据结构
# JavaScript函数式编程: 实现不可变数据结构 什么是不可变数据结构 在计算机编程中,不可变数据结构指的是数据一旦创建就不可更改或者修改。这意味着我们不能在原始数据上进行增删改操作,而是需要创建一个新的数据结构来代替原始数据进行操作。 为什么要…...
union find算法 c++
1.原理参考 labuladong-fucking-algorithm/算法思维系列/UnionFind算法详解.md at master jiajunhua/labuladong-fucking-algorithm GitHub 2.初级模式 #include <iostream>class UF {public:// 记录连通分量/* 构造函数,n 为图的节点总数 */UF(int n) {…...
路径规划 | 改进的人工势场法APF算法进行路径规划(Matlab)
目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 改进的人工势场法(APF)路径规划算法 在路径规划中,人工势场法(APF)是一种常见的方法,但传统的APF算法容易陷入局部极小值,导致路径规…...
ES语句——DSL(kibana语句)
一、查询操作 查看当前索引的数据结构 _mapping Get ai-open-log*/_mapping 查询当前索引下的文档数以及分片信息 _count Get ai-open-log*/_count { "count": 12345, //当前索引下的文档总数 "_shards": { //分片信息 "total&…...
y3编辑器教学5:触发器2 案例演示
文章目录 一、探索1.1 ECA1.1.1 ECA的定义1.1.2 使用触发器实现瞬间移动效果 1.2 变量1.2.1 什么是变量1.2.2 使用变量存储碎片收集数量并展现 1.3 if语句(魔法效果挂接)1.3.1 地形设置1.3.2 编写能量灌注逻辑1.3.3 编写能量灌注后,实现传送逻…...
MVC配置文件及位置
配置文件位置 默认位置 WEB-INF目录下,文件名:<servlet-name>-servlet.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi"http://www.w3.…...
【razor】echo搭配relay功能分析
echo 要搭配relay 实现作者说relay在linux上跑,可以模拟丢包、延迟目前没看到如何模拟。relay监听9200,有俩作用 echopeer1 发relay,replay 把peer1的包给peer2 ,实现p2p能力。 接收端:采集后发送发给relay的 接收端的地址就是自己,的地址就是本地的9200,因此是让relay接…...
C++类的运算符重载
目标 让自定义的类直接使用运算符运算 代码 头文件及类定义 #include <iostream>using namespace std; class Complex {int rel;int vir; public:void show(){cout <<"("<<this->rel<<","<<this->vir<<&quo…...
Motionface RTASR 离线实时语音识别直播字幕使用教程
软件使用场景: 直播、视频会议、课堂教学等需要实时字幕的场景。 1:系统要求 软件运行支持32位/64位windows 10/11系统,其他硬件要求无,无显卡也能实时识别字幕。 2:下载安装 链接:百度网盘 请输入提取码 提取码&#…...
【论文阅读】相似误差订正方法在风电短期风速预报中的应用研究
文章目录 概述:摘要1. 引言2. 相似误差订正算法(核心)3. 订正实验3.1 相似因子选取3.2 相似样本数试验3.3 时间窗时长实验 4. 订正结果分析4.1 评估指标对比4.2 风速曲线对比4.3 分风速段订正效果评估4.4 风速频率统计 5. 结论与讨论 概述&am…...
learn-(Uni-app)输入框u-search父子组件与input输入框(防抖与搜索触发)
1.父子组件u-search (1)父组件 <!-- 父组件 --> <template> <div><searchBar change"change" search"search"></searchBar> </div> </template> <script> // 子组件搜索 import…...
UNIX数据恢复—UNIX系统常见故障问题和数据恢复方案
UNIX系统常见故障表现: 1、存储结构出错; 2、数据删除; 3、文件系统格式化; 4、其他原因数据丢失。 UNIX系统常见故障解决方案: 1、检测UNIX系统故障涉及的设备是否存在硬件故障,如果存在硬件故障…...
c#动态更新替换json节点
需求项目json作为主模板,会应用到多个子模版,当后续项目变更只需要修改主模板中节点,并且能够动态更新到原来的子模版中去。 主模板示例: {"A": {"A1": "","A2": false,"A3"…...
kubernetes的可靠性测试或者故障测试有哪些?
kubernetes的可靠性测试或者故障测试有哪些? 在 Kubernetes (K8s) 集群中,可靠性测试和故障性测试旨在确保系统能够稳定运行并具备应对各种故障的能力。这些测试主要针对集群的组件、应用程序和基础设施。以下是详细的测试内容和方法: 一、可靠性测试 1. 高可用性测试 目…...
datax和datax-web打包成docker运行
概述 datax和datax-web从一台机器迁移到另一台时,要重新搭建一套运行环境,比较麻烦;打包成docker镜像后迁移就方便多了; 因为我的mysql版本是8,需要在datax的read和write中手动添加8的jdbc驱动 所以我先各自下载好了datax和data…...
ThreadLocal原理解析
ThreadLocal原理解析 本篇将带大家了解ThreadLocal的使用方法,并且深度剖析其原理和作用,通过阅读源码的方式,进一步了解其内部原理 ThreadLocal 是 Java 提供的一个工具类,用于为每个线程维护一个独立的变量副本。每个线程可以访…...
Android 分析 Activity 与 Fragment 的区别,部分使用的差异
一、基本概念 Activity:Activity 是应用中单独一个界面的一个组件,通常一个 Activity 对应一个界面(或屏幕)。Activity 控制了一个应用界面的生命周期,并且能够处理用户的输入和交互。 Fragment:Fragment …...
前端(Ajax)
1.客户端请求 向https://jsonplaceholder.typicode.com/users发送get请求 const xhr new XMLHttpRequest();console.log(xhr.readyState);xhr.open(get, https://jsonplaceholder.typicode.com/users)console.log(xhr.readyState);xhr.send();console.log(xhr.readyState);xh…...
【C++】约瑟夫环问题:深度解析与高级优化
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言约瑟夫环问题:深度解析与高级优化💯题目描述💯解决方案详解直接模拟法(基于 C 实现)代码解析示例执行过程 💯高级优…...
总结拓展十七:SAP 采购订单行项目“交货“页签解析
《 SAP采购订单行项目“交货”页签字段解析》 在 SAP 系统的采购流程中,采购订单行项目的“交货”页签承载着关键的信息,其中的字段更是对整个交货环节的精准描述和把控的重要元素。理解和正确解析这些字段,对于确保采购流程的顺利进行、优化…...
作业Day2: 多文件编译; 思维导图
目录 ①文件代码 及其所需头文件分析 main.c文件 1.h文件 1.c文件 ②运行结果: ③代码分析 结构体成员 数据类型的设定: 信息录入函数 信息删除 成绩排序 信息显示 自定义初始化函数 ④思维导图:编辑 ①文件代码 及其所需头文…...
Kioptrix Level 1通关攻略
目录 修改靶机Kioptrix:Level 1 的网络模式 探测靶机IP地址 得到端口信息 扫描TCP端口 扫描UDP端口 脚本扫描 指纹探测 漏洞探测 目录枚举扫描 发现利用脚本 执行exp链接shell 修改靶机Kioptrix:Level 1 的网络模式 Kioptrix: Level 1靶机的默认网络模式是桥接&#x…...
01 下载opencv并配置vs开发环境
01 下载opencv并配置vs开发环境 01 下载windows版本的opencv 下载地址:点击 WIndows版本的是编译好的代码。 当然国外网站下载很慢,可以通过我分享的网盘链接下载 opencv-4.10.0-windows.exe https://www.alipan.com/s/wV7z4YsmXgN 点击链接保…...
Ubuntu22.04 docker如何发布镜像(和用git差不多)
在dockerhub上创建远程仓库:https://hub.docker.com/ 将本地镜像打tag,并修改成可以上传到 dockerhub 的形式 # 查看本地镜像# 修改镜像 ## docker tag 镜像名称:标签 新的镜像名称(要和远程仓库dockerhub上的一致):新的标签pus…...
【Golang】——Gin 框架中的模板渲染详解
Gin 框架支持动态网页开发,能够通过模板渲染结合数据生成动态页面。在这篇文章中,我们将一步步学习如何在 Gin 框架中配置模板、渲染动态数据,并结合静态资源文件创建一个功能完整的动态网站。 文章目录 1. 什么是模板渲染? 1.1 概…...
React的局限性是什么?
性能: 虚拟 DOM 虽然提高了渲染性能,但在某些情况下可能会造成性能瓶颈,尤其是在处理大量数据或复杂更新时。对于非UI任务(如计算密集型操作),React 本身并不擅长。 学习曲线: 对于初学者来说&a…...