Android之 日历单选多选控件

news2024/11/23 1:20:51

一,效果图

1.1 单选

 2.2 多选

二 实现思路

2.1 数据来源,利用原生日历Calendar,获取从本月开始的往后一年的日期,遍历月数添加全部天数据

private void initCalendarData() {
        Calendar calendar = Calendar.getInstance();
        year = calendar.get(Calendar.YEAR);
        month = calendar.get(Calendar.MONTH);
        day = calendar.get(Calendar.DAY_OF_MONTH);
        nowDay = day;
        calendar.set(year, month, 1);

        for (int i = 0; i < 12; i++) {
            List<DateEntity> deList = new ArrayList<>();
            MonthEntity monthEntity = new MonthEntity();
            int maxDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            int empty = calendar.get(Calendar.DAY_OF_WEEK);
            empty = empty == 1 ? 6 : empty - 2;
            for (int j = 0; j < empty; j++) {
                DateEntity de = new DateEntity();
                de.setType(1);
                deList.add(de);
            }
            for (int j = 1; j <= maxDayOfMonth; j++) {
                DateEntity de = new DateEntity();
                if (i == 0) {
                    de.setType(j < nowDay ? 4 : 0);
                } else {
                    de.setType(0);
                }

                de.setDate(j);
                if (i == 0 && nowDay == j) {
                    de.setToday(true);
                } else {
                    de.setToday(false);
                }
                de.setParentPos(i);
                String[] result=DatePickerUtils.getLunarDate(year, month + 1, j);
                de.setDesType(result[0]);
                de.setDesc(result[1]);
                deList.add(de);
            }

            year = calendar.get(Calendar.YEAR);
            month = calendar.get(Calendar.MONTH) + 1;
            monthEntity.setTitle(year + "年" + month + "月");
            monthEntity.setYear(year);
            monthEntity.setMonth(month);
            monthEntity.setList(deList);
            monthList.add(monthEntity);

            calendar.add(Calendar.MONTH, 1);
        }
    }

2.2 添加公立,农历,节气数据。下面只是节假日的判断。

 private static String getChinaCalendarMsg(int year, int month, int day) {
        String message = "";
        if (((month) == 1) && day == 1) {
            message = "春节";
        } else if (((month) == 1) && day == 15) {
            message = "元宵";
        } else if (((month) == 5) && day == 5) {
            message = "端午";
        } else if ((month == 7) && day == 7) {
            message = "七夕";
        } else if (((month) == 8) && day == 15) {
            message = "中秋";
        } else if ((month == 9) && day == 9) {
            message = "重阳";
        } else if ((month == 12) && day == 8) {
            message = "腊八";
        } else {
            if (month == 12) {
                if ((((monthDays(year, month) == 29) && day == 29))
                        || ((((monthDays(year, month) == 30) && day == 30)))) {
                    message = "除夕";
                }
            }
        }
        return message;
    }

2.3 控件,可以用两层Recycleview,但最好不要这样做,嵌套体验是非常差的,明显的卡顿。所以尽量用一个Recycleview,利用getItemViewType来避免嵌套。

@Override
    public int getItemViewType(int position) {
        if (isEmptyPosition(position)) {
            // 空布局
            return TYPE_EMPTY;
        }
        mTempPosition = position;
        int groupPosition = getGroupPositionForPosition(position);
        int type = judgeType(position);
        if (type == TYPE_HEADER) {
            return getHeaderViewType(groupPosition);
        } else if (type == TYPE_FOOTER) {
            return getFooterViewType(groupPosition);
        } else if (type == TYPE_CHILD) {
            int childPosition = getChildPositionForPosition(groupPosition, position);
            return getChildViewType(groupPosition, childPosition);
        }
        return super.getItemViewType(position);
    }

三, 核心源码

3.1 项目结构

3.2 CalendarSelectDialog.java

public class CalendarSelectDialog extends Dialog {
    private ImageView icClose;
    private RecyclerView rvCalendar;
    private TextView tvSure;


    private Activity context;

    private CalendarGroupedListAdapter groupedListAdapter;
    private List<MonthEntity> monthList = new ArrayList<>();

    private int year, month, day;
    private int nowDay;
    private int lastDateSelect = -1, lastMonthSelect = -1;

    public interface OnViewClickLiatener {
        void sureClick(String selectTime);

        void cancelClick();
    }

    public OnViewClickLiatener onViewClickLiatener;

    public void setOnViewClickLiatener(OnViewClickLiatener onViewClickLiatener) {
        this.onViewClickLiatener = onViewClickLiatener;
    }


    public CalendarSelectDialog(Activity context) {
        super(context, R.style.custom_dialog2);
        this.context = context;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_caledar_select);
        setCanceledOnTouchOutside(true);
        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.width = ScreenUtils.getScreenWidth(context);
        params.height = (int) (ScreenUtils.getTotalScreenHeight(context)*0.85f);
        getWindow().setGravity(Gravity.BOTTOM);
        getWindow().setAttributes(params);
        getWindow().setBackgroundDrawableResource(R.color.transparent);
        getWindow().setWindowAnimations(R.style.pop_animation_bottom);
        initView();
        setData();

    }

    public void initView() {
        icClose = (ImageView) findViewById(R.id.ic_close);
        rvCalendar = (RecyclerView) findViewById(R.id.rv_calendar);
        tvSure = (TextView) findViewById(R.id.tv_sure);

    }

    public void setData() {
        icClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dismiss();
                if (onViewClickLiatener != null) {
                    onViewClickLiatener.cancelClick();
                }
            }
        });
        tvSure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(lastMonthSelect<0){
                    ToastHelp.showToast("请选择日期");
                    return;
                }
                dismiss();
                MonthEntity monthEntity=monthList.get(lastMonthSelect);
                DateEntity dateEntity=monthEntity.getList().get(lastDateSelect);
                int year=monthEntity.getYear();
                int month=monthEntity.getMonth();
                int date=dateEntity.getDate();

                String monthString;
                if(month<10){
                    monthString="0"+month;
                }else {
                    monthString=String.valueOf(month);
                }

                String dataString;
                if(date<10){
                    dataString="0"+date;
                }else {
                    dataString=String.valueOf(date);
                }

                String selectTime=year+"-"+monthString+"-"+dataString;
                if (onViewClickLiatener != null) {
                    onViewClickLiatener.sureClick(selectTime);
                }
            }
        });
        CalendarUtils.init(context);
        initCalendarData();
        initCalendarRv();
    }



    @Override
    public void dismiss() {
        if (context == null || ((Activity) context).isDestroyed() || ((Activity) context).isFinishing()) {
            return;
        }
        super.dismiss();
    }

    @Override
    public void show() {
        if (context == null || ((Activity) context).isDestroyed() || ((Activity) context).isFinishing()) {
            return;
        }
        super.show();
    }


    private void initCalendarData() {
        Calendar calendar = Calendar.getInstance();
        year = calendar.get(Calendar.YEAR);
        month = calendar.get(Calendar.MONTH);
        day = calendar.get(Calendar.DAY_OF_MONTH);
        nowDay = day;
        calendar.set(year, month, 1);

        for (int i = 0; i < 12; i++) {
            List<DateEntity> deList = new ArrayList<>();
            MonthEntity monthEntity = new MonthEntity();
            int maxDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            int empty = calendar.get(Calendar.DAY_OF_WEEK);
            empty = empty == 1 ? 6 : empty - 2;
            for (int j = 0; j < empty; j++) {
                DateEntity de = new DateEntity();
                de.setType(1);
                deList.add(de);
            }
            for (int j = 1; j <= maxDayOfMonth; j++) {
                DateEntity de = new DateEntity();
                if (i == 0) {
                    de.setType(j < nowDay ? 4 : 0);
                } else {
                    de.setType(0);
                }

                de.setDate(j);
                if (i == 0 && nowDay == j) {
                    de.setToday(true);
                } else {
                    de.setToday(false);
                }
                de.setParentPos(i);
                String[] result=DatePickerUtils.getLunarDate(year, month + 1, j);
                de.setDesType(result[0]);
                de.setDesc(result[1]);
                deList.add(de);
            }

            year = calendar.get(Calendar.YEAR);
            month = calendar.get(Calendar.MONTH) + 1;
            monthEntity.setTitle(year + "年" + month + "月");
            monthEntity.setYear(year);
            monthEntity.setMonth(month);
            monthEntity.setList(deList);
            monthList.add(monthEntity);

            calendar.add(Calendar.MONTH, 1);
        }

    }

    private void initCalendarRv() {
        groupedListAdapter =new CalendarGroupedListAdapter(context,monthList);
        GroupedGridLayoutManager gridLayoutManager = new GroupedGridLayoutManager(context, 7, groupedListAdapter);
        rvCalendar.setLayoutManager(gridLayoutManager);
        rvCalendar.getItemAnimator().setChangeDuration(0);
        rvCalendar.setAdapter(groupedListAdapter);
        groupedListAdapter.setOnItemClickListener(new CalendarGroupedListAdapter.OnItemClickListener() {
            @Override
            public void itemClick(int groupPosition, int childPosition) {
                //setRangeClick(groupPosition,childPosition);
                setSingleClick(groupPosition,childPosition);
            }
        });
    }

    private void getViews() {
        rvCalendar = (RecyclerView) findViewById(R.id.rv_calendar);
    }

    /**
     *
     * @param groupPosition
     * @param childPosition
     */
    private void setSingleClick(int groupPosition, int childPosition){
        if (groupPosition == lastMonthSelect && childPosition == lastDateSelect) {
            return;
        }

        monthList.get(groupPosition).getList().get(childPosition).setType(8);

        groupedListAdapter.notifyChildChanged(groupPosition, childPosition);
        if (lastDateSelect != -1) {
            monthList.get(lastMonthSelect).getList().get(lastDateSelect).setType(0);
            groupedListAdapter.notifyChildChanged(lastMonthSelect, lastDateSelect);
        }
        lastMonthSelect = groupPosition;
        lastDateSelect = childPosition;
    }

    /**
     * 范围选择
     */
    private boolean selectComplete;
    private List<Integer> selectMonth = new ArrayList<>();
    private List<Integer> selectDate = new ArrayList<>();
    private void setRangeClick(int parentPos, int pos){
        if (parentPos != lastMonthSelect || pos != lastDateSelect) {

            //1、第二次选择;2、选择的月份相等日期比之前选择的大或者选择的月份比之前的大;3、选择未完成
            boolean haveMiddle = lastMonthSelect != -1 && ((lastMonthSelect == parentPos && pos > lastDateSelect) || (parentPos > lastMonthSelect))
                    && !selectComplete;
            if (haveMiddle) {
                monthList.get(parentPos).getList().get(pos).setType(6);
                selectDate.add(1);
                monthList.get(lastMonthSelect).getList().get(lastDateSelect).setType(7);
                selectDate.add(1);

                int monthLen = parentPos - lastMonthSelect;
                List<DateEntity> list;
                int dateLen;
                if (monthLen == 0) {
                    dateLen = pos - lastDateSelect;
                    for (int i = 1; i < dateLen; i++) {
                        monthList.get(parentPos).getList().get(i + lastDateSelect).setType(5);
                        selectDate.add(1);
                    }
                    groupedListAdapter.notifyGroupChanged(lastMonthSelect);
                    //选择了这个月
                    selectMonth.add(parentPos);
                } else {
                    //第一个月
                    int lastMonthSize = monthList.get(lastMonthSelect).getList().size();
                    dateLen = lastMonthSize - lastDateSelect;
                    for (int i = 1; i < dateLen; i++) {
                        monthList.get(lastMonthSelect).getList().get(i + lastDateSelect).setType(5);
                        selectDate.add(1);
                    }
                    groupedListAdapter.notifyGroupChanged(lastMonthSelect);
                    //选择了这个月
                    selectMonth.add(lastMonthSelect);

                    //中间月份
                    int month;
                    int middleMonthLen = parentPos - lastMonthSelect;
                    for (int i = 1; i < middleMonthLen; i++) {
                        month = lastMonthSelect + i;
                        list = monthList.get(month).getList();
                        dateLen = list.size();
                        for (int j = 0; j < dateLen; j++) {
                            if (list.get(j).getType() != 1) {
                                list.get(j).setType(5);
                                selectDate.add(1);
                            }
                        }
                        groupedListAdapter.notifyGroupChanged(month);
                        //选择了这个月
                        selectMonth.add(month);
                    }

                    //最后那个月
                    dateLen = pos;
                    for (int i = 0; i < dateLen; i++) {
                        DateEntity de = monthList.get(parentPos).getList().get(i);
                        if (de.getType() != 1) {
                            de.setType(5);
                            selectDate.add(1);
                        }
                    }
                    groupedListAdapter.notifyGroupChanged(parentPos);
                    //选择了这个月
                    selectMonth.add(parentPos);
                }
                Log.d("mita", "选择的天数:" + selectDate.size());
                selectComplete = true;
                lastMonthSelect = -1;
                lastDateSelect = -1;
            } else {
                selectDate.clear();

                //清除已选
                if (selectComplete) {
                    List<DateEntity> list;
                    DateEntity de;
                    int len = selectMonth.size();
                    for (int i = 0; i < len; i++) {
                        list = monthList.get(selectMonth.get(i)).getList();
                        int size = list.size();
                        for (int j = 0; j < size; j++) {
                            de = list.get(j);
                            if (de.getType() == 5 || de.getType() == 6 || de.getType() == 7) {
                                de.setType(0);
                            }
                        }
                        groupedListAdapter.notifyGroupChanged(selectMonth.get(i));
                    }
                    selectMonth.clear();
                }

                monthList.get(parentPos).getList().get(pos).setType(3);
                groupedListAdapter.notifyGroupChanged(parentPos);
                if (lastDateSelect != -1) {
                    monthList.get(lastMonthSelect).getList().get(lastDateSelect).setType(0);
                    groupedListAdapter.notifyGroupChanged(lastMonthSelect);
                }
                lastMonthSelect = parentPos;
                lastDateSelect = pos;
                selectComplete = false;
            }
        }
    }
}

3.2 CalendarGroupedListAdapter.java

public class CalendarGroupedListAdapter extends GroupedRecyclerViewAdapter {


    private List<MonthEntity> groupList;
    private Context context;

    public CalendarGroupedListAdapter(Context context, List<MonthEntity> groupList) {
        super(context);
        this.context = context;
        this.groupList = groupList;
    }

    @Override
    public int getGroupCount() {
        return groupList.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return groupList.get(groupPosition).getList().size();
    }

    @Override
    public boolean hasHeader(int groupPosition) {
        return true;
    }

    @Override
    public boolean hasFooter(int groupPosition) {
        return false;
    }

    @Override
    public int getHeaderLayout(int viewType) {
        return R.layout.item_calendar;
    }

    @Override
    public int getFooterLayout(int viewType) {
        return 0;
    }

    @Override
    public int getChildLayout(int viewType) {
        return R.layout.item_date;
    }

    @Override
    public void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition) {
        MonthEntity monthEntity = groupList.get(groupPosition);
        holder.setText(R.id.tv_cal_title, monthEntity.getTitle());

    }

    @Override
    public void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition) {

    }

    @Override
    public void onBindChildViewHolder(BaseViewHolder holder, final int groupPosition, final int childPosition) {
        DateEntity dateEntity = groupList.get(groupPosition).getList().get(childPosition);


        LinearLayout llDate = holder.get(R.id.ll_date);
        TextView mTvDate = holder.get(R.id.tv_date);
        TextView mTvDesc = holder.get(R.id.tv_desc);
        TextView mTvToday = holder.get(R.id.tv_today);
        mTvToday.setText("今日");

        int date = dateEntity.getDate();
        int type = dateEntity.getType();
        boolean isToday = dateEntity.isToday();
        if (type == 1) {//留白
            mTvToday.setVisibility(isToday ? View.VISIBLE : View.INVISIBLE);
            mTvToday.setTextColor(Color.TRANSPARENT);
            mTvDate.setText("");
            mTvDesc.setText("");
            mTvDate.setTextColor(Color.TRANSPARENT);
            mTvDesc.setTextColor(Color.TRANSPARENT);
            llDate.setBackgroundColor(Color.TRANSPARENT);
            llDate.setEnabled(false);
        } else if (type == 0) {//日常
            mTvToday.setVisibility(isToday ? View.VISIBLE : View.INVISIBLE);
            mTvDate.setText(String.valueOf(dateEntity.getDate()));
            mTvDesc.setText(dateEntity.getDesc());
            mTvToday.setTextColor(ContextCompat.getColor(context, R.color.color_red));
            mTvDate.setTextColor(ContextCompat.getColor(context, R.color.color_333333));
            mTvDesc.setTextColor(TextUtils.isEmpty(dateEntity.getDesType()) ? ContextCompat.getColor(context, R.color.color_333333) : ContextCompat.getColor(context, R.color.color_red));
            llDate.setBackgroundColor(Color.TRANSPARENT);
            llDate.setEnabled(true);
        } else if (type == 3) {//日常选中
            mTvToday.setVisibility(isToday ? View.VISIBLE : View.INVISIBLE);
            mTvDate.setText(String.valueOf(dateEntity.getDate()));
            mTvDesc.setText(dateEntity.getDesc());
            mTvToday.setTextColor(ContextCompat.getColor(context, R.color.white));
            mTvDate.setTextColor(ContextCompat.getColor(context, R.color.white));
            mTvDesc.setTextColor(ContextCompat.getColor(context, R.color.white));
            llDate.setBackgroundResource(R.drawable.state_selected);
            llDate.setClickable(true);
        } else if (type == 4) {//今天之前的日期
            mTvToday.setVisibility(isToday ? View.VISIBLE : View.INVISIBLE);
            mTvDate.setText(String.valueOf(dateEntity.getDate()));
            mTvDesc.setText(dateEntity.getDesc());
            mTvToday.setTextColor(ContextCompat.getColor(context, R.color.color_cccccc));
            mTvDate.setTextColor(ContextCompat.getColor(context, R.color.color_cccccc));
            mTvDesc.setTextColor(ContextCompat.getColor(context, R.color.color_cccccc));
            llDate.setBackgroundColor(Color.TRANSPARENT);
            llDate.setEnabled(false);
        } else if (type == 5) {//中间
            mTvToday.setVisibility(isToday ? View.VISIBLE : View.INVISIBLE);
            mTvDate.setText(String.valueOf(dateEntity.getDate()));
            mTvDesc.setText(dateEntity.getDesc());
            mTvToday.setTextColor(ContextCompat.getColor(context, R.color.white));
            mTvDate.setTextColor(ContextCompat.getColor(context, R.color.white));
            mTvDesc.setTextColor(ContextCompat.getColor(context, R.color.white));
            llDate.setBackgroundResource(R.drawable.state_middle_range);
            llDate.setEnabled(true);
        } else if (type == 6) {//终点
            mTvToday.setVisibility(isToday ? View.VISIBLE : View.INVISIBLE);
            mTvDate.setText(String.valueOf(dateEntity.getDate()));
            mTvDesc.setText("结束");
            mTvToday.setTextColor(ContextCompat.getColor(context, R.color.white));
            mTvDate.setTextColor(ContextCompat.getColor(context, R.color.white));
            mTvDesc.setTextColor(ContextCompat.getColor(context, R.color.white));
            llDate.setBackgroundResource(R.drawable.state_end_range);
            llDate.setEnabled(true);
        } else if (type == 7) {//起点
            mTvToday.setVisibility(isToday ? View.VISIBLE : View.INVISIBLE);
            mTvDate.setText(String.valueOf(dateEntity.getDate()));
            mTvDesc.setText("开始");
            mTvToday.setTextColor(ContextCompat.getColor(context, R.color.white));
            mTvDate.setTextColor(ContextCompat.getColor(context, R.color.white));
            mTvDesc.setTextColor(ContextCompat.getColor(context, R.color.white));
            llDate.setBackgroundResource(R.drawable.state_first_range);
            llDate.setEnabled(true);
        } else if (type == 8) {//单选
            mTvToday.setVisibility(isToday ? View.VISIBLE : View.INVISIBLE);
            mTvDate.setText(String.valueOf(dateEntity.getDate()));
            mTvDesc.setText(dateEntity.getDesc());
            mTvToday.setTextColor(ContextCompat.getColor(context, R.color.white));
            mTvDate.setTextColor(ContextCompat.getColor(context, R.color.white));
            mTvDesc.setTextColor(ContextCompat.getColor(context, R.color.white));
            llDate.setBackgroundResource(R.drawable.state_selected);
            llDate.setEnabled(true);
        }

        llDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onItemClickListener != null) {
                    onItemClickListener.itemClick(groupPosition, childPosition);
                }
            }
        });
    }

    public interface OnItemClickListener {
        void itemClick(int groupPosition, int childPosition);
    }

    public OnItemClickListener onItemClickListener;

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }
}

四,注意

4.1 由于左右留白,父控件Recycleview做了外边距margin,会导致子控件左右也有边距。但UI要求是无边距的,这个时候就需要特殊处理控件。

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rv_calendar"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="12dp"
    android:layout_marginRight="12dp"
    android:overScrollMode="never"/>

 

4.2 方法,可以用裁剪属性clipChildren,来控制他的子控件是否要在他应有的边界内进行绘制

android:clipChildren=“false” 就是不限制他子控件在其边界内进行绘制
android:clipChildren=“true” 限制他子控件在其边界内进行绘制

 4.3 clipChildren需要特别注意,加在RecyclerView父控件是没用的,只能加载RecyclerView的父控件,即需要需要裁剪的view的爷辈控件。如下:添加属性android:clipChildren="false"

  <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:clipChildren="false">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_calendar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginLeft="12dp"
            android:layout_marginRight="12dp"
            android:overScrollMode="never"/>

    </FrameLayout>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/673507.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Chrome(Manifest Version 3) 浏览器扩展插件基础教程

文章目录 一、简介二、核心介绍三、自定义页面背景色三、设置页面背景图&#xff08;web_accessible_resources&#xff09;四、设置徽章&#xff08;Badge&#xff09;五、桌面通知六、消息通信七、自定义右键菜单&#xff08;添加、更新、删除&#xff09;八、Omnibox九、浏览…

网安笔记--整合

文章目录 1 intro威胁因素 2 加密密码体制分类安全性 3 DESDES工作模式多重DES和安全性加密策略 4 RSA PKCS保密系统体制分类单向函数用处 RSAElgamal 5 SHAHASHSHA-1SHA-2 6 数字签名基本概念签名体系MAC 消息认证码 7 密码协议协议距离协议分类密钥建立协议认证建立协议认证的…

云原生监控平台 Prometheus 的相关概念及部署

1 Prometheus简介 Prometheus 是一个开源的系统监控和报警系统&#xff0c;在 2012 年由 SoundCloud 公司创建&#xff0c;并于 2015 年正式发布。2016 年&#xff0c;Prometheus 正式加入 CNCF (Cloud Native Computing Foundation)&#xff0c;成为继kubernetes之后第二个在C…

Redis---集群

目录 一、集群的介绍 1.1 为什么需要集群呢&#xff1f; 1.2 什么是集群&#xff1f; 1.2 集群能干什么呢&#xff1f; 二、集群的算法之分片&槽位slot 2.1 什么是槽位slot&#xff1f; 2.2 分片 2.3 使用槽位和分片的优势 2.4 slot 槽位映射的三种算法 1、哈…

postgresql 从应用角度看快照snapshot使用,事务隔离控制不再神密

​专栏内容&#xff1a;postgresql内核源码分析 个人主页&#xff1a;我的主页 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 快照使用 快照是事务中使用&#xff0c;配合事务的隔离级别&#xff0c;体现出不同的可见性。…

端午节粽子(python)

目录 前言 正文 粽叶绘制 粽叶绳绘制 祝福语绘制 源代码 总结 前言 今天端午节&#xff0c;然后昨天也学习一下绘图的相关知识&#xff0c;然后就想看一下能不能画一下&#xff0c;结果还是有点困难的&#xff0c;用CharAI生成简直一言难尽了。后面是找了一个改了一下。 …

MicroBlaze Processor hello world实验

MicroBlaze Processor hello world实验 实验目的 搭建microblaze工程&#xff0c;通过串口打印hello world&#xff0c;了解microblaze的使用&#xff0c;加深对FPGA硬件和软件开发的理解。 实验原理 MicroBlaze Processor是xilinx提供的一个软核处理器&#xff08;使用FPGA…

Delta型腿机器狗全动作展示

1. 功能说明 本文示例将实现R322样机Delta型腿机器狗维持身体平衡、原地圆形摆动、原地踏步、蹲起、站立、前进、后退、转向、横向移动、斜向移动等功能。 2. 电子硬件 本实验中采用了以下硬件&#xff1a; 主控板 Basra主控板&#xff08;兼容Arduino Uno&#xff09;‍ 扩展…

追寻技术巅峰:开发者的端午征途

近年来&#xff0c;随着信息技术的飞速发展&#xff0c;开发者们以前所未有的速度和规模推动着技术的进步。而正如端午节的文化内涵所体现的那样&#xff0c;我们以屈原名言为指引&#xff0c;勉励着广大开发者在技术征途上不断追求极致&#xff0c;勇往直前。 一、端午节与技术…

macOS Sonoma 14 beta 2 (23A5276g) Boot ISO 原版可引导镜像

macOS Sonoma 14 beta 2 (23A5276g) Boot ISO 原版可引导镜像 本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持在 Windows 和 …

【Flume】高级组件之Sink Processors及项目实践(Sink负载均衡和故障转移)

文章目录 1. 组件简介2. 项目实践2.1 负载均衡2.1.1 需求2.1.2 配置2.1.3 运行 2.2 故障转移2.2.1 需求2.2.2 配置2.2.3 运行 1. 组件简介 Sink Processors类型包括这三种&#xff1a;Default Sink Processor、Load balancing Sink Processor和Failover Sink Processor。 Defa…

AIGC连续内容生成几种方案

背景 从AI可以画图到现在各家都在功课的连续性内容的输出&#xff0c;正在AI画图进入到大众圈其实也不过1年左右时间。对于单图的研究已经逐渐完善&#xff0c;单图理论上讲&#xff0c;只要你能按要求做promt的设计出图率应该是比较高的。但是对于要生成连续的图或者要生成连…

推荐 5 个 火火火 的 GitHub 项目

推荐 5 个开源项目&#xff0c;前两个是 AI 相关&#xff0c;后面 3 个为逛逛GitHub 的读者推荐&#xff0c;如果你挖掘到了很棒的开源项目&#xff0c;可以给老逛投稿。 本期推荐开源项目目录&#xff1a; 1. SuperAGI&#xff08;AI&#xff09; 2. 一键换脸&#xff08;AI&a…

macOS Monterey 12.6.7 (21G651) Boot ISO 原版可引导镜像

macOS Monterey 12.6.7 (21G651) Boot ISO 原版可引导镜像 本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持在 Windows 和 Lin…

计算机实习自我鉴定范文5篇

精选计算机实习鉴定 (一) 时间过的真快&#xff0c;在这过去一个3个月时间里&#xff0c;我在**科技有限公司实习从事运维工作。 在公司实习的这段时间&#xff0c;我主要和其他的实习生一起负责公司刚开发的**系统的部署、更新以及维护。 这三月的时间&#xff0c;在同事和项目…

【并发知识点】CAS的实现原理及应用

系列文章目录 AQS的实现原理及应用 CAS的实现原理及应用 文章目录 系列文章目录前言1、CAS的概念2、CAS的实现原理3、单JVM内锁CAS实现3.1、效果 4、模拟赛龙舟比赛 前言 本章节介绍CAS概念、实现原理&#xff0c;并通过java代码应用&#xff0c;最终模拟赛龙舟比赛。 1、CA…

设计模式之适配器模式笔记

设计模式之适配器模式笔记 说明Adapter(适配器)目录类适配器模式示例类图适配者类的接口适配者类目标接口具体的SD卡类计算机类适配器类测试类 对象适配器模式适配者类的接口适配者类目标接口具体的SD卡类计算机类适配器类测试类 说明 记录下学习设计模式-适配器模式的写法。J…

力扣高频SQL50题(基础版)——第十天

力扣高频SQL50题(基础版)——第十天 1 只出现过一次的最大数字 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出1 1.1.3 示例输入输出2 1.2 示例sql语句 # 查不到时的结果自然就为Null SELECT MAX(t.num) num FROM (SELECT numFROM MyNumbersGROUP By numHAVING count…

窥探系列之Mybatis-plus BaseMapper实现

我们知道&#xff0c;mybatisplus的BaseMapper接口中提供了一些如updateById的方法&#xff0c;框架本身已经实现了这些CRUD功能&#xff0c;基本的CRUD我们就没必要写sql&#xff0c;直接使用java语法就能对数据进行操控&#xff0c;很方便。那么这些功能是如何被实现的呢&…

【并发知识点】AQS的实现原理及应用

系列文章目录 AQS的实现原理及应用 CAS的实现原理及应用 文章目录 系列文章目录前言一、AQS是什么&#xff1f;1、应用场景2、优缺点 二、案例应用1.使用AQS来实现一个简单的互斥锁2.模拟赛龙舟程序 总结 前言 在Java技术方面&#xff0c;AQS指的是AbstractQueuedSynchronize…