117.Android 简单的拖拽列表+防止越界拖动(BaseRecyclerViewAdapterHelper) 两种方式实现

news2025/7/25 10:11:05

 //一.第一种方式 通过BaseItemDraggableAdapter类和其提供的的拖拽监听实现:

//1.第一步 导入依赖库和权限:

//依赖库:

//RecyclerView
implementation 'com.android.support:recyclerview-v7:28.0.0'

//RecyclerAdapter
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.28'

//用到的权限:

<!--振动-->
<uses-permission android:name="android.permission.VIBRATE" />

 //2.第二步 新建ItemDraggableActivity页面:

//manifest注册:

<activity
    android:name=".phone.activity.ItemDraggableActivity"
    android:launchMode="singleTop"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateHidden"
    tools:ignore="LockedOrientationActivity" />

//activity代码:

/**
 * @author CJF
 */
public class ItemDraggableActivity extends AppCompatActivity implements BaseQuickAdapter.OnItemChildClickListener, View.OnClickListener {
    private final GridLayoutManager manager = new GridLayoutManager(this, 3);
    private final ItemDraggableAdapter adapter = new ItemDraggableAdapter(R.layout.item_draggable_item, new ArrayList<>());

    /**
     * 震动时长(毫秒)
     */
    private final int milliseconds = 50;
    private Vibrator vibrator;
    private RecyclerView mTreeListRecy;
    private TextView mEdit;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tree_list);

        //点击音效
        vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        mTreeListRecy = findViewById(R.id.mTreeListRecy);
        mEdit = findViewById(R.id.mEdit);
        mEdit.setOnClickListener(this);

        mTreeListRecy.setLayoutManager(manager);
        mTreeListRecy.setAdapter(adapter);

        DragAndSwipeCallback itemDragAndSwipeCallback = new DragAndSwipeCallback(adapter);
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemDragAndSwipeCallback);
        itemTouchHelper.attachToRecyclerView(mTreeListRecy);
        //可以不用设置,可以拖拽的方向,默认上下左右
        itemDragAndSwipeCallback.setDragMoveFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);

//         开启拖拽 设置可拖拽item的根布局id
        adapter.enableDragItem(itemTouchHelper, R.id.mItemDraggableItemLin, true);
        adapter.setOnItemDragListener(onItemDragListener);


        // 开启滑动删除
//        adapter.enableSwipeItem();
//        adapter.setOnItemSwipeListener(onItemSwipeListener);

        adapter.setOnItemChildClickListener(this);

        List<ItemDraggableBean> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            ItemDraggableBean bean = new ItemDraggableBean();
            bean.setName("数据" + i);
            list.add(bean);
        }
        adapter.addData(list);
    }

    /**
     * 拖拽监听
     */
    private OnItemDragListener onItemDragListener = new OnItemDragListener() {
        @Override
        public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos) {
            Log.e("TAG1231", "onItemDragStart" + "你在拖拽第" + (pos + 1) + "个位置的item哦!");
            //震动
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                vibrator.vibrate(VibrationEffect.createOneShot(milliseconds, VibrationEffect.DEFAULT_AMPLITUDE));
            } else {
                vibrator.vibrate(milliseconds);
            }

            //按住变大
            viewHolder.itemView.setScaleX(1.2f);
            viewHolder.itemView.setScaleY(1.2f);
            viewHolder.itemView.setAlpha(0.5f);

            //改变数据状态
            ItemDraggableBean draggableBean = adapter.getData().get(pos);
            if (!draggableBean.isShow()) {
                List<ItemDraggableBean> data = adapter.getData();
                for (ItemDraggableBean bean : data) {
                    bean.setShow(true);
                }

                //循环遍历出所有的item布局 并显示图片
                //注意不可以直接使用 adapter.notifyDataSetChanged();数据刷新会导致直接调用onItemDragEnd()方法
                for (int i = 0; i < mTreeListRecy.getChildCount(); i++) {
                    View childAt = mTreeListRecy.getChildAt(i);
                    TextView textView = childAt.findViewById(R.id.mItemDraggableItemText);
                    View view = childAt.findViewById(R.id.mItemDraggableItemImg);
                    view.setVisibility(View.VISIBLE);
                    Log.e("TAG1231", "textView:" + textView.getText().toString());
                }

                mEdit.setText("完成");
            }

        }

        @Override
        public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) {
            Log.e("TAG1231", "onItemDragMoving");
        }

        @Override
        public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) {
            Log.e("TAG1231", "onItemDragEnd" + "拖拽到了第" + (pos + 1) + "个位置哦!");
            //变回原来大小
            viewHolder.itemView.setScaleX(1.0f);
            viewHolder.itemView.setScaleY(1.0f);
            viewHolder.itemView.setAlpha(1.0f);
        }
    };

    OnItemSwipeListener onItemSwipeListener = new OnItemSwipeListener() {
        @Override
        public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos) {
            ToastUtil.getInstance().showToast("继续向左滑动即可删除第" + (pos + 1) + "个位置的item");
        }

        @Override
        public void clearView(RecyclerView.ViewHolder viewHolder, int pos) {

        }

        @Override
        public void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos) {
            ToastUtil.getInstance().showToast("删除了第" + (pos + 1) + "个位置的item哦");
        }

        @Override
        public void onItemSwipeMoving(Canvas canvas, RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) {

        }
    };

    @Override
    public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
        adapter.remove(position);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.mEdit:
                boolean isEdit = "编辑".equals(mEdit.getText().toString());
                List<ItemDraggableBean> data = adapter.getData();
                for (ItemDraggableBean bean : data) {
                    bean.setShow(isEdit);
                }
                adapter.notifyDataSetChanged();
                mEdit.setText(isEdit ? "完成" : "编辑");
                break;
            default:
                break;
        }
    }

}

//3.第三步 新建DragAndSwipeCallback类继承ItemDragAndSwipeCallback,重写onChildDraw 防止越界拖动:

/**
 * @author CJF
 * 重写onChildDraw 防止越界拖动
 */
public class DragAndSwipeCallback extends ItemDragAndSwipeCallback {

    public DragAndSwipeCallback(BaseItemDraggableAdapter adapter) {
        super(adapter);
    }

    /**
     * 重写onChildDraw 防止越界拖动
     *
     * @param c
     * @param recyclerView
     * @param viewHolder
     * @param dX
     * @param dY
     * @param actionState
     * @param isCurrentlyActive
     */
    @Override
    public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        float topY = viewHolder.itemView.getTop() + dY;
        float bottomY = topY + viewHolder.itemView.getHeight();

        float leftX = viewHolder.itemView.getLeft() + dX;
        float rightX = leftX + viewHolder.itemView.getWidth();

        if (topY < 0) {
            dY = 0;
        } else if (bottomY > recyclerView.getHeight()) {
            dY = recyclerView.getHeight() - viewHolder.itemView.getHeight() - viewHolder.itemView.getTop();
        }

        if (leftX < 0) {
            dX = viewHolder.itemView.getWidth() - viewHolder.itemView.getRight();
        } else if (rightX > recyclerView.getWidth()) {
            dX = recyclerView.getWidth() - viewHolder.itemView.getWidth() - viewHolder.itemView.getLeft();
        }

        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

}

//4.第四步 新建ItemDraggableAdapter适配器类:

/**
 * @author CJF
 */
public class ItemDraggableAdapter extends BaseItemDraggableAdapter<ItemDraggableBean, BaseViewHolder> {

    public ItemDraggableAdapter(List<ItemDraggableBean> data) {
        super(data);
    }

    public ItemDraggableAdapter(int layoutResId, List<ItemDraggableBean> data) {
        super(layoutResId, data);

    }

    @Override
    protected void convert(BaseViewHolder helper, ItemDraggableBean item) {
        helper.setText(R.id.mItemDraggableItemText, item.getName());
        helper.setGone(R.id.mItemDraggableItemImg, item.isShow());
        helper.addOnClickListener(R.id.mItemDraggableItemImg);
    }

}

//5.第五步 新建ItemDraggableBean类:

/**
 * @author CJF
 */
public class ItemDraggableBean {
    private String name;
    private boolean isShow = false;

    public ItemDraggableBean() {
    }

    public ItemDraggableBean(String name, boolean isShow) {
        this.name = name;
        this.isShow = isShow;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isShow() {
        return isShow;
    }

    public void setShow(boolean show) {
        isShow = show;
    }

}

//6.第六步 各个xml布局文件以及svg图片文件:

//activity_tree_list:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/color_white"
    android:orientation="vertical">

    <TextView
        android:id="@+id/mEdit"
        android:background="@drawable/selector_common_item"
        android:textColor="@color/colorAccent"
        android:textStyle="bold"
        android:textSize="18sp"
        android:gravity="center"
        android:text="编辑"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/mTreeListRecy"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

//item_draggable_item:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/bg_search"
    android:layout_margin="@dimen/dp_5"
    android:id="@+id/mItemDraggableItemLin"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/mItemDraggableItemText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="left|center_vertical"
        android:minHeight="@dimen/dp_50"
        android:padding="@dimen/dp_10"
        android:text="text"
        android:textColor="@color/black"
        android:textSize="@dimen/sp_15" />

    <ImageView
        android:scaleType="center"
        android:id="@+id/mItemDraggableItemImg"
        android:src="@drawable/crm_close"
        android:layout_width="@dimen/dp_50"
        android:layout_height="match_parent"/>

</LinearLayout>

//svg图片文件  crm_close:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

//二.第二种方式 通过继承ItemTouchHelper.Callback类重写几个方法实现:

//1.第一步 导入依赖库:

//RecyclerView
implementation 'com.android.support:recyclerview-v7:28.0.0'

//RecyclerAdapter
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.28'

//2.第二步 新建ItemDraggableActivity页面:

//manifest注册:

<activity
    android:name=".phone.activity.ItemDraggableActivity"
    android:launchMode="singleTop"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateHidden"
    tools:ignore="LockedOrientationActivity" />

//activity代码:

/**
 * @author CJF
 */
public class ItemDraggableActivity extends AppCompatActivity implements BaseQuickAdapter.OnItemChildClickListener, BaseQuickAdapter.OnItemLongClickListener {
    private final GridLayoutManager manager = new GridLayoutManager(this, 3);
    private final ItemDraggableAdapter adapter = new ItemDraggableAdapter(R.layout.item_draggable_item);

    private RecyclerView mTreeListRecy;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tree_list);

        mTreeListRecy = findViewById(R.id.mTreeListRecy);

        mTreeListRecy.setLayoutManager(manager);
        mTreeListRecy.setAdapter(adapter);

        adapter.setOnItemChildClickListener(this);
        adapter.setOnItemLongClickListener(this);

        //列表上下左右拖拽滑动
        AdapterTouchHelper adapterTouchHelper = new AdapterTouchHelper(mTreeListRecy, adapter);


        List<ItemDraggableBean> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            ItemDraggableBean bean = new ItemDraggableBean();
            bean.setName("数据" + i);
            list.add(bean);
        }
        adapter.addData(list);

    }


    @Override
    public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
        adapter.remove(position);
    }

    @Override
    public boolean onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
        //改变数据状态
        ItemDraggableBean draggableBean = (ItemDraggableBean) adapter.getData().get(position);
        if (!draggableBean.isShow()) {
            List<ItemDraggableBean> data = adapter.getData();
            for (ItemDraggableBean bean : data) {
                bean.setShow(true);
            }

            //循环遍历出所有的item布局 并显示图片
            //注意不可以直接使用 adapter.notifyDataSetChanged();数据刷新会导致直接结束滑动
            for (int i = 0; i < mTreeListRecy.getChildCount(); i++) {
                View childAt = mTreeListRecy.getChildAt(i);
                TextView textView = childAt.findViewById(R.id.mItemDraggableItemText);
                View mItemDraggableItemImg = childAt.findViewById(R.id.mItemDraggableItemImg);
                mItemDraggableItemImg.setVisibility(View.VISIBLE);
                Log.e("TAG1231", "textView:" + textView.getText().toString());
            }

        }
        return false;
    }

}

//3.第三步 新建ItemDraggableAdapter适配器:

/**
 * @author CJF
 */
public class ItemDraggableAdapter extends BaseQuickAdapter<ItemDraggableBean, BaseViewHolder> {

    public ItemDraggableAdapter(int layoutResId) {
        super(layoutResId);
    }

    @Override
    protected void convert(BaseViewHolder helper, ItemDraggableBean item) {
        helper.setText(R.id.mItemDraggableItemText, item.getName());
        helper.setGone(R.id.mItemDraggableItemImg, item.isShow());
        helper.addOnClickListener(R.id.mItemDraggableItemImg);
    }

}

//4.第四步 新建AdapterTouchHelper类继承ItemTouchHelper.Callback实现核心功能:

/**
 * @author CJF
 * 列表上下左右拖拽滑动
 */
public class AdapterTouchHelper extends ItemTouchHelper.Callback {
    private BaseQuickAdapter adapter;

    public AdapterTouchHelper(RecyclerView recyclerView, BaseQuickAdapter adapter) {
        this.adapter = adapter;
        //用Callback构造ItemtouchHelper
        ItemTouchHelper touchHelper = new ItemTouchHelper(this);
        //调用ItemTouchHelper的attachToRecyclerView方法建立联系
        touchHelper.attachToRecyclerView(recyclerView);
    }

    @Override
    public int getMovementFlags(@NotNull RecyclerView recyclerView, @NotNull RecyclerView.ViewHolder viewHolder) {
        //允许上下拖动
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
        return makeMovementFlags(dragFlags, 0);
    }

    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

    /**
     * Item进行上下移动从旧的位置到新的位置的时候会调用该方法
     *
     * @param recyclerView
     * @param viewHolder   旧位置
     * @param target       目标位置
     * @return
     */
    @Override
    public boolean onMove(@NotNull RecyclerView recyclerView, @NotNull RecyclerView.ViewHolder viewHolder, @NotNull RecyclerView.ViewHolder target) {
        //交换位置
        Collections.swap(adapter.getData(), viewHolder.getAdapterPosition(), target.getAdapterPosition());
        adapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

    /**
     * Item左右移动达到条件时时,会调用该方法
     *
     * @param viewHolder
     * @param direction
     */
    @Override
    public void onSwiped(@NotNull RecyclerView.ViewHolder viewHolder, int direction) {

    }

    /**
     * 重写onChildDraw 防止越界拖动
     *
     * @param c
     * @param recyclerView
     * @param viewHolder
     * @param dX
     * @param dY
     * @param actionState
     * @param isCurrentlyActive
     */
    @Override
    public void onChildDraw(@NotNull Canvas c, @NotNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        float topY = viewHolder.itemView.getTop() + dY;
        float bottomY = topY + viewHolder.itemView.getHeight();

        float leftX = viewHolder.itemView.getLeft() + dX;
        float rightX = leftX + viewHolder.itemView.getWidth();

        if (topY < 0) {
            dY = 0;
        } else if (bottomY > recyclerView.getHeight()) {
            dY = recyclerView.getHeight() - viewHolder.itemView.getHeight() - viewHolder.itemView.getTop();
        }

        if (leftX < 0) {
            dX = viewHolder.itemView.getWidth() - viewHolder.itemView.getRight();
        } else if (rightX > recyclerView.getWidth()) {
            dX = recyclerView.getWidth() - viewHolder.itemView.getWidth() - viewHolder.itemView.getLeft();
        }

        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {

        //开始按住滑动
        if (actionState == ItemTouchHelper.ACTION_STATE_DRAG && !isViewCreateByAdapter(viewHolder)) {
            //按住变大
            viewHolder.itemView.setScaleX(1.2f);
            viewHolder.itemView.setScaleY(1.2f);
            viewHolder.itemView.setAlpha(0.5f);
        }
        super.onSelectedChanged(viewHolder, actionState);
    }

    @Override
    public void clearView(@NotNull RecyclerView recyclerView, @NotNull RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        if (isViewCreateByAdapter(viewHolder)) {
            return;
        }

        //结束按住滑动 变回原来大小
        viewHolder.itemView.setScaleX(1.0f);
        viewHolder.itemView.setScaleY(1.0f);
        viewHolder.itemView.setAlpha(1.0f);
    }

    private boolean isViewCreateByAdapter(RecyclerView.ViewHolder viewHolder) {
        int type = viewHolder.getItemViewType();
        return type == BaseQuickAdapter.HEADER_VIEW || type == BaseQuickAdapter.LOADING_VIEW
                || type == BaseQuickAdapter.FOOTER_VIEW || type == BaseQuickAdapter.EMPTY_VIEW;
    }

}

//5.第五步 新建ItemDraggableBean类:

/**
 * @author CJF
 */
public class ItemDraggableBean {
    private String name;
    private boolean isShow = false;

    public ItemDraggableBean() {
    }

    public ItemDraggableBean(String name, boolean isShow) {
        this.name = name;
        this.isShow = isShow;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isShow() {
        return isShow;
    }

    public void setShow(boolean show) {
        isShow = show;
    }

}

//6.第六步 各个xml布局以及svg图片:

//activity_tree_list:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/color_white"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/mTreeListRecy"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

//item_draggable_item:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/bg_search"
    android:layout_margin="@dimen/dp_5"
    android:id="@+id/mItemDraggableItemLin"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/mItemDraggableItemText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="left|center_vertical"
        android:minHeight="@dimen/dp_50"
        android:padding="@dimen/dp_10"
        android:text="text"
        android:textColor="@color/black"
        android:textSize="@dimen/sp_15" />

    <ImageView
        android:scaleType="center"
        android:id="@+id/mItemDraggableItemImg"
        android:src="@drawable/crm_close"
        android:layout_width="@dimen/dp_50"
        android:layout_height="match_parent"/>

</LinearLayout>

//svg图片 crm_close:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

//------------------------------------------------------END---------------------------------------------------------------

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

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

相关文章

WAF:ModSecurity on Nginx(15)

预备知识 Nginx概述 Nginx ("engine x") 是一个高性能的HTTP和 反向代理 服务器&#xff0c;也是一个 IMAP/POP3/SMTP服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的&#xff0c;第一个公开版本0.1.0发布于2004年10月4日。其将源代…

Mysql的函数GROUP_CONCAT和FIND_IN_SET

业务场景&#xff1a; 表A&#xff1a;存在 customer_phone&#xff1b;bac_id主键 表B&#xff1a;存在 主键id&#xff1b;bac_id字段 customer_phone:用户手机号&#xff1b; bac_id:主键 表A &#xff1a;每个手机号可能会对应多个主键&#xff1b;要查询每个客户手机号包…

我该怎么选择IB课程?

IB用6大学科组及3大课程核心构建知识体系&#xff0c;涵盖广博、注重知行合一&#xff0c;对学生的综合素质的提升以及综合竞争力的打造都十分有益。IB选课建议 六大学科组中的每个课程分为HL&#xff08;高难度&#xff09;和SL&#xff08;标准水平&#xff09; HLIB课程&…

「RISC-V Arch」SBI 规范解读(上)

术语 SBI&#xff0c;Supervisor Binary Interface&#xff0c;管理二进制接口 U-Mode&#xff0c;User mode&#xff0c;用户模式 S-Mode&#xff0c;Supervisor mode&#xff0c;监督模式 VS-Mode&#xff0c;Virtualization Supervisor mode&#xff0c;虚拟机监督模式 …

三菱FX3U与威纶MT8071IP走RS422通讯

一、准备工作 1.需要工具&#xff1a; 电脑一台、PLC&#xff1a;三菱FX3U一个、触摸屏&#xff1a;威纶MT8071一个、 &#xff08;三菱圆形编程口转USB&#xff09;一根、触摸屏与电脑通讯线一根&#xff08;T型口数据线&#xff09;、PLC与触摸屏通讯线&#xff1a;电烙…

谷歌搜索留痕的技术公式【2023年新版】

本文主要分享谷歌搜索留痕的技术公式&#xff0c;让你更简单的去学习谷歌留痕的技术原理 本文由光算创作&#xff0c;有可能会被修改和剽窃&#xff0c;我们佛系对待这样的行为吧。 谷歌搜索留痕的技术公式是什么&#xff1f; 答案是&#xff1a;需要做排名的关键词海量能搜…

Apache Hadoop生态部署-hadoop单机安装

目录 查看服务架构图-服务分布、版本信息 1&#xff1a;安装包下载 2&#xff1a;配置环境变量 3&#xff1a;服务配置 &#xff08;1&#xff09;core-site.xml &#xff08;2&#xff09;配置 hadoop-env.sh &#xff08;3&#xff09;HDFS 配置文件hdfs-site.xml &a…

【Redis】数据库和缓存如何保证一致性?

【Redis】数据库和缓存如何保证一致性&#xff1f; 文章目录【Redis】数据库和缓存如何保证一致性&#xff1f;常见方案先更新缓存&#xff0c;再更新数据库先更新数据库&#xff0c;再更新缓存并发情况下的思考先删除缓存&#xff0c;再更新数据库先更新数据库&#xff0c;再删…

StopWatch计时器

前言 开发中&#xff0c;为了评估性能&#xff0c;我们通常会使用System.currentTimeMillis() 去计算程序运行耗时 long startTimeSystem.currentTimeMillis();//业务代码... long endTimeSystem.currentTimeMillis(); System.out.println("耗时:" (endTime-startT…

Java多线程(三)---synchronized、Lock和volatile

Java内存模型&#xff08;非JVM&#xff09;Java内存模型(Java Memory Model简称JMM)&#xff0c;是一种共享内存模型&#xff0c;是多线程的东西&#xff0c;并不是JVM&#xff08;Java Virtual Machine(Java虚拟机)的缩写&#xff09;&#xff0c;这是俩玩意儿&#xff01;&a…

Ubuntu 22.04.2 发布,可更新至 Linux Kernel 5.19

Ubuntu 22.04 LTS (Jammy Jellyfish) Ubuntu 22.04.2 发布&#xff0c;可更新至 Linux Kernel 5.19 请访问原文链接&#xff1a;Ubuntu 22.04 LTS (Jammy Jellyfish)&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;www.sysin.org 发行说…

ssh远程登录报错:kex_exchange_identification: Connection closed by remote host

基本信息系统&#xff1a;MacOS Catalina 10.15.7报错信息&#xff1a;终端登录远程服务器时报错&#xff1a;kex_exchange_identification: Connection closed by remote host复制然而服务商的一键登录或VNC登录正常。解决方案首先使用以下命令debug登录过程&#xff0c;以便定…

这可能是Spring Boot Starter 讲的最清楚的一次了

前面我们简单介绍了如何使用消息中间件Apache Pulsar&#xff0c;但是在项目中那样使用&#xff0c;显然是不太好的&#xff0c;不管从易用性和扩展性来看&#xff0c;都是远远不够&#xff0c; 为了和springboot项目集成&#xff0c;写一个pulsar-spring-boot-starter是非常有…

Linux核心技能:2023主流监控Prometheus详解,附官方可复制中文文档教程

Prometheus既是一个时序数据库&#xff0c;又是一个监控系统&#xff0c;更是一套完备的监控生态解决方案。作为时序数据库&#xff0c;目前Prometheus已超越了老牌的时序数据库OpenTSDB、Graphite、RRDtool、KairosDB等&#xff0c;如图所示。 &#xff08;来源网络&#xff0…

QT+OpenGL鼠标操作和模型控制

文章目录QTOpenGL鼠标操作和模型控制鼠标拾取理论有点小复杂从鼠标计算射线第 0 步&#xff1a;2D 视口坐标第 1 步&#xff1a;3d归一化设备坐标第 2 步&#xff1a;4d齐次剪辑坐标第 3 步&#xff1a;4d眼(相机)坐标第 4 步&#xff1a;4d 世界坐标代码展示模型控制多模型加载…

自动执行自动化测试用例

phpunit 接口自动化测试系列 所有自动化测试用例最终的目的都是一样的&#xff0c;实现无人值守的自动化运行。而目前最常用的就是Jenkins来实现这个功能&#xff0c;在前面的WebdriverPython页面自动化的教程中我们已经详细讲解了如何将自动化测试用例接入到Jenkins中。本章我…

RK系列(RK3568) i2s 音频输入 麦克风驱动

平台&#xff1a;Android12SOC&#xff1a;RK3568外围芯片&#xff1a;XS9922i2s简介&#xff1a;从上图看I2s主要的线有&#xff1a;SDO SCLK LRCK MCLK I2S协议只定义三根信号线&#xff1a;串行时钟信号SCLK(BCLK)、数据信号SD和左右声道选择信号WS。&#xff08;1&#xff…

QT入门Containers之QStackedWidget

目录 一、QStackedWidget界面相关 1、布局介绍 2、插入界面 3、插入类界面 二、Demo展示 此文为作者原创&#xff0c;创作不易&#xff0c;转载请标明出处&#xff01; 一、QStackedWidget界面相关 1、布局介绍 QStackedWidget这个控件在界面布局时&#xff0c;使用还…

JVM整体分析篇

这里写目录标题JVM的组成部分1.类装载子系统1.1一个类加载到JVM的过程1.2类加载机制1.3为什么设计双亲委派机制1.4怎么打破双亲委派机制2.运行时数据区2.1线程私有及共享2.2JVM内存区结构2.3JVM参数设置经验3.Java对象的生命周期3.1.对象的创建3.2.对象大小的计算&#xff08;6…

六、程序计数器(PC寄存器)

JVM中的程序计数寄存器&#xff08;Program Counter Register&#xff09;中&#xff0c;Register 的命名源于CPU的寄存器&#xff0c;寄存器存储指令相关的现场信息。CPU只有把数据装载到寄存器才能够运行。 这里&#xff0c;并非是广义上所指的物理寄存器&#xff0c;或许将其…