【Android】高仿京东三级类型列表Demo

news2024/12/23 0:13:11

本demo基于二级分类双列表联动Demo进行了改进,高仿实现了京东的三级类型列表。
京东的如图:
在这里插入图片描述
本demo的:

改进之处

实现了三级列表联动,二三级列表之间的滑动监听优化了一下,将二级类型选中交予自身的点击事件,不再完全依靠三级列表的滑动回调。

上代码

引入的依赖

    //ShapeView
    implementation 'com.github.getActivity:ShapeView:9.0'
    //Gson解析
    implementation 'com.google.code.gson:gson:2.10.1'

ShapeView主要是美化一下二级条目,Gson是为了解析本地的类型json数据

条目布局

item_type_one

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_main_left_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal"
    android:padding="5dp">
    <TextView
        android:id="@+id/type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:layout_marginVertical="15dp" />
</LinearLayout>

item_type_two

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:background="@color/flow">

    <com.hjq.shape.view.ShapeButton
        android:id="@+id/type"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="10dp"
        android:gravity="center"
        android:paddingHorizontal="10dp"
        android:paddingVertical="5dp"
        android:textSize="18sp"
        app:shape_radius="10dp"
        app:shape_solidColor="@android:color/transparent"
        app:shape_strokeColor="@color/common_accent_color"
        app:shape_strokeSize="1dp"
        app:shape_textColor="@color/common_accent_color"
        app:shape_textPressedColor="@android:color/white"
        app:shape_type="rectangle" />
</LinearLayout>

item_type_three

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="@drawable/radius_white"
    android:layout_margin="10dp"
    android:padding="10dp">

    <TextView
        android:id="@+id/type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/black"
        android:paddingHorizontal="10dp"
        app:drawableEndCompat="@drawable/arrows_right_ic" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

item_type_four(其实这个才是类型三,上面的是类型三的外围包裹,但是不想改了)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/icon"
        android:src="@mipmap/ic_logo"
        android:layout_margin="5dp"
        android:layout_width="60dp"
        android:layout_height="60dp" />
    <TextView
        android:id="@+id/type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:textSize="14sp"
        android:text="男鞋" />
</LinearLayout>

主页面布局

由两个列表变成了三个列表

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

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/one"
        android:layout_weight="7"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <LinearLayout
        android:layout_weight="3"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/two"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/three"
            android:layout_weight="1"
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="0dp"/>
    </LinearLayout>
</LinearLayout>

适配器

OneTypeAdapter

public class OneTypeAdapter extends RecyclerView.Adapter<OneTypeAdapter.OneTypeHolder> {
    private final Context context;
    private final List<GoodsTypeBN> list;
    public int selectedPosition = 0;//当前选择的下标
    private OnItemClickListener onItemClickListener;

    public OneTypeAdapter(Context context, List<GoodsTypeBN> list) {
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public OneTypeHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.item_type_one,parent,false);
        return new OneTypeHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull OneTypeHolder holder, @SuppressLint("RecyclerView") int position) {

        holder.type.setText(list.get(position).getType_name());
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (selectedPosition != holder.getAdapterPosition()) {
                    //点击了新的 item,更新状态
                    selectedPosition = holder.getAdapterPosition();
                }
                if (onItemClickListener!=null){
                    onItemClickListener.onItemClickListener(v,position);
                }
                notifyDataSetChanged();
            }
        });
        if (position==selectedPosition){
            holder.type.setTextColor(context.getColor(R.color.red));
            holder.type.setTextSize(30);
        }
        else {
            holder.type.setTextColor(context.getColor(R.color.black));
            holder.type.setTextSize(18);
        }
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public static class OneTypeHolder extends RecyclerView.ViewHolder{
        TextView type;
        public OneTypeHolder(@NonNull View itemView) {
            super(itemView);
            type = itemView.findViewById(R.id.type);
        }
    }

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

    public interface OnItemClickListener {
        void onItemClickListener(View v, int position);
    }
}

TwoTypeAdapter

public class TwoTypeAdapter extends RecyclerView.Adapter<TwoTypeAdapter.TwoTypeHolder> {
    private Context context;
    private List<GoodsTypeBN> list;
    private OnItemClickListener onItemClickListener;
    public int selectPosition=0;

    public TwoTypeAdapter(Context context, List<GoodsTypeBN> list) {
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public TwoTypeHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.item_type_two,parent,false);
        return new TwoTypeHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull TwoTypeHolder holder, int position) {
        holder.type.setText(list.get(position).getType_name());
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                selectPosition=position;
                notifyDataSetChanged();
                if (onItemClickListener!=null){
                    onItemClickListener.onItemClickListener(view,position);
                }
            }
        });
        if (position==selectPosition){
            holder.type.setTextColor(context.getColor(R.color.common_accent_color));
            holder.type.getShapeDrawableBuilder()
                    .setStrokeColor(context.getColor(R.color.common_accent_color))
                    .intoBackground();
        }
        else {
            holder.type.setTextColor(context.getColor(R.color.grey));
            holder.type.getShapeDrawableBuilder()
                    .setStrokeColor(context.getColor(R.color.grey))
                    .intoBackground();
        }
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public static class TwoTypeHolder extends RecyclerView.ViewHolder{
        ShapeButton type;
        public TwoTypeHolder(@NonNull View itemView) {
            super(itemView);
            type = itemView.findViewById(R.id.type);
        }
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public interface OnItemClickListener {
        void onItemClickListener(View v, int position);
    }
}

注意这里,这里二级条目的点击事件下,会将自身选中,自己来选中自己,然后更新,不再交由列表的滑动来更新。
在这里插入图片描述
在这里插入图片描述

之前的是这样。因为后面的几个条目点击存在一些问题。
在这里插入图片描述

在这里插入图片描述
ThreeTypeAdapter

public class ThreeTypeAdapter extends RecyclerView.Adapter<ThreeTypeAdapter.ThreeTYpeHolder> {
    private final Context context;
    private final List<GoodsTypeBN> list;
    public ThreeTypeAdapter(Context context, List<GoodsTypeBN> list) {
        this.context = context;
        this.list = list;
    }
    @NonNull
    @Override
    public ThreeTYpeHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.item_type_three,parent,false);
        return new ThreeTYpeHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ThreeTYpeHolder holder, int position) {
        holder.type.setText(list.get(position).getType_name());

        holder.recyclerView.setAdapter(new FourAdapter(context,list.get(position).getNextType()));
        holder.recyclerView.setLayoutManager(new GridLayoutManager(context,3));
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public static class ThreeTYpeHolder extends RecyclerView.ViewHolder{
        TextView type;
        RecyclerView recyclerView;
        public ThreeTYpeHolder(@NonNull View itemView) {
            super(itemView);
            type = itemView.findViewById(R.id.type);
            recyclerView = itemView.findViewById(R.id.recycler);
        }
    }
}

FourAdapter

public class FourAdapter extends RecyclerView.Adapter<FourAdapter.FourHolder> {
    private final Context context;
    private final List<GoodsTypeBN> list;

    public FourAdapter( Context context,List<GoodsTypeBN> list) {
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public FourHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.item_type_four,parent,false);
        return new FourHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull FourHolder holder, int position) {
        GoodsTypeBN goodsTypeBN=list.get(position);
        holder.type.setText(goodsTypeBN.getType_name());
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, "点击了"+goodsTypeBN.getType_name(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public static class FourHolder extends RecyclerView.ViewHolder{
        TextView type;
        ImageView icon;
        public FourHolder(@NonNull View itemView) {
            super(itemView);
            type = itemView.findViewById(R.id.type);
            icon = itemView.findViewById(R.id.icon);
        }
    }
}

主要代码

GoodsTypeBN类

public class GoodsTypeBN {
    private String type_id;
    private String type_name;
    private String parent_id;
    private String type_lv;
    private List<GoodsTypeBN> nextType;

    public String getType_id() {
        return type_id;
    }

    public void setType_id(String type_id) {
        this.type_id = type_id;
    }

    public String getType_name() {
        return type_name;
    }

    public void setType_name(String type_name) {
        this.type_name = type_name;
    }

    public String getParent_id() {
        return parent_id;
    }

    public void setParent_id(String parent_id) {
        this.parent_id = parent_id;
    }

    public String getType_lv() {
        return type_lv;
    }

    public void setType_lv(String type_lv) {
        this.type_lv = type_lv;
    }

    public List<GoodsTypeBN> getNextType() {
        return nextType;
    }

    public void setNextType(List<GoodsTypeBN> nextType) {
        this.nextType = nextType;
    }

    @Override
    public String toString() {
        return "GoodsTypeBN{" +
                "type_id='" + type_id + '\'' +
                ", type_name='" + type_name + '\'' +
                ", parent_id='" + parent_id + '\'' +
                ", type_lv='" + type_lv + '\'' +
                ", nextType=" + nextType +
                '}';
    }
}

主页面逻辑

				//一级类型条目点击
                oneTypeAdapter.setOnItemClickListener(new OneTypeAdapter.OnItemClickListener() {
                    @Override
                    public void onItemClickListener(View v, int position) {
                        //更换二级三级类型的数据
                        typeTwo.clear();
                        typeTwo.addAll(typeOne.get(position).getNextType());
                        twoTypeAdapter.selectPosition=0;
                        twoTypeAdapter.notifyDataSetChanged();
                        threeTypeAdapter.notifyDataSetChanged();
                    }
                });
                //二级类型条目点击
                twoTypeAdapter.setOnItemClickListener(new TwoTypeAdapter.OnItemClickListener() {
                    @Override
                    public void onItemClickListener(View v, int position) {
                        //将三级类型滑动到相应位置
                        LinearLayoutManager threeLayoutManager = ((LinearLayoutManager) three.getLayoutManager());
                        if (threeLayoutManager!=null){
                            threeLayoutManager.scrollToPositionWithOffset(position,0);
                        }
                    }
                });
                //添加三级类型滑动监听
                three.addOnScrollListener(onScrollListener);

添加滑动监听

RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {

        /**
         获取第一个可见的item的position
         */
        int currentPosition = 0;
        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            LinearLayoutManager twoLayoutManager = (LinearLayoutManager) two.getLayoutManager();
            LinearLayoutManager threeLayoutManager = ((LinearLayoutManager) three.getLayoutManager());
            if (twoLayoutManager!=null&&threeLayoutManager!=null){
                currentPosition = threeLayoutManager.findFirstCompletelyVisibleItemPosition();
                /**
                 这地方需要进行判断,如果下面的Recycle在移动的时候,上面的RecyclerView也是需要进行移动的
                 上面的recyclerview有可能会不可见,这时候,我们必须去判断一下,上面最后的一个item是不是
                 小于下面滑动的位置,或上面第一个item是不是大于下面滑动的位置
                 */
                if (twoLayoutManager.findFirstCompletelyVisibleItemPosition() > currentPosition) {
                    twoLayoutManager.scrollToPositionWithOffset(currentPosition, 0);
                } else if (twoLayoutManager.findFirstCompletelyVisibleItemPosition() < currentPosition) {
                    twoLayoutManager.scrollToPositionWithOffset(currentPosition, 0);
                }

                // 判断滚动的方向和位置,判断是否触发了回弹效果
                if (dy < 0 && !recyclerView.canScrollVertically(-1)) {
                    // 触发了上拉的回弹效果
                    Log.e("TAG", "onScrolled: 触发了上拉的回弹效果" );
                } else if (dy > 0 && !recyclerView.canScrollVertically(1)) {
                    // 触发了下拉的回弹效果
                    currentPosition = typeTwo.size() - 1;
                    Log.e("TAG", "onScrolled: 触发了下拉的回弹效果" );
                }
                twoTypeAdapter.selectPosition=currentPosition;
                twoTypeAdapter.notifyDataSetChanged();
            }
        }
    };

全部代码

public class MainActivity extends AppCompatActivity {
    private OneTypeAdapter oneTypeAdapter;
    private TwoTypeAdapter twoTypeAdapter;
    private ThreeTypeAdapter threeTypeAdapter;
    private List<GoodsTypeBN> typeOne;
    private List<GoodsTypeBN> typeTwo=new ArrayList<>();
    private List<GoodsTypeBN> typeThree=new ArrayList<>();
    private RecyclerView one,two,three;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        one=findViewById(R.id.one);
        two=findViewById(R.id.two);
        three=findViewById(R.id.three);
        init();
    }

    private void init(){
        String json = getJson(this, "category.json");
        if (!TextUtils.isEmpty(json)){
            //解析数据
            List<GoodsTypeBN> typeBNBaseEN=new Gson().fromJson(json, new TypeToken<List<GoodsTypeBN>>(){}.getType());
            if (typeBNBaseEN!=null){
                typeOne=typeBNBaseEN;
                //设置一级类型
                oneTypeAdapter=new OneTypeAdapter(this,typeOne);
                one.setLayoutManager(new LinearLayoutManager(this));
                one.setAdapter(oneTypeAdapter);

                //设置初始二级类型
                typeTwo.clear();
                typeTwo.addAll(typeOne.get(0).getNextType());
                twoTypeAdapter=new TwoTypeAdapter(this,typeTwo);
                LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
                linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
                two.setLayoutManager(linearLayoutManager);
                two.setAdapter(twoTypeAdapter);

                //设置初始三级类型
                typeThree.clear();
                typeThree.addAll(typeTwo.get(0).getNextType());
                threeTypeAdapter=new ThreeTypeAdapter(this,typeTwo);
                three.setLayoutManager(new LinearLayoutManager(this));
                three.setAdapter(threeTypeAdapter);

                //一级类型条目点击
                oneTypeAdapter.setOnItemClickListener(new OneTypeAdapter.OnItemClickListener() {
                    @Override
                    public void onItemClickListener(View v, int position) {
                        //更换二级三级类型的数据
                        typeTwo.clear();
                        typeTwo.addAll(typeOne.get(position).getNextType());
                        twoTypeAdapter.selectPosition=0;
                        twoTypeAdapter.notifyDataSetChanged();
                        threeTypeAdapter.notifyDataSetChanged();
                    }
                });
                //二级类型条目点击
                twoTypeAdapter.setOnItemClickListener(new TwoTypeAdapter.OnItemClickListener() {
                    @Override
                    public void onItemClickListener(View v, int position) {
                        //将三级类型滑动到相应位置
                        LinearLayoutManager threeLayoutManager = ((LinearLayoutManager) three.getLayoutManager());
                        if (threeLayoutManager!=null){
                            threeLayoutManager.scrollToPositionWithOffset(position,0);
                        }
                    }
                });
                //添加三级类型滑动监听
                three.addOnScrollListener(onScrollListener);
            }
        }
    }
    RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {

        /**
         获取第一个可见的item的position
         */
        int currentPosition = 0;
        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            LinearLayoutManager twoLayoutManager = (LinearLayoutManager) two.getLayoutManager();
            LinearLayoutManager threeLayoutManager = ((LinearLayoutManager) three.getLayoutManager());
            if (twoLayoutManager!=null&&threeLayoutManager!=null){
                currentPosition = threeLayoutManager.findFirstCompletelyVisibleItemPosition();
                /**
                 这地方需要进行判断,如果下面的Recycle在移动的时候,上面的RecyclerView也是需要进行移动的
                 上面的recyclerview有可能会不可见,这时候,我们必须去判断一下,上面最后的一个item是不是
                 小于下面滑动的位置,或上面第一个item是不是大于下面滑动的位置
                 */
                if (twoLayoutManager.findFirstCompletelyVisibleItemPosition() > currentPosition) {
                    twoLayoutManager.scrollToPositionWithOffset(currentPosition, 0);
                } else if (twoLayoutManager.findFirstCompletelyVisibleItemPosition() < currentPosition) {
                    twoLayoutManager.scrollToPositionWithOffset(currentPosition, 0);
                }

                // 判断滚动的方向和位置,判断是否触发了回弹效果
                if (dy < 0 && !recyclerView.canScrollVertically(-1)) {
                    // 触发了上拉的回弹效果
                    Log.e("TAG", "onScrolled: 触发了上拉的回弹效果" );
                } else if (dy > 0 && !recyclerView.canScrollVertically(1)) {
                    // 触发了下拉的回弹效果
                    currentPosition = typeTwo.size() - 1;
                    Log.e("TAG", "onScrolled: 触发了下拉的回弹效果" );
                }
                twoTypeAdapter.selectPosition=currentPosition;
                twoTypeAdapter.notifyDataSetChanged();
            }
        }
    };


    public static String getJson(Context context, String fileName) {
        StringBuilder stringBuilder = new StringBuilder();
        //获得assets资源管理器
        AssetManager assetManager = context.getAssets();
        //使用IO流读取json文件内容
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
                    assetManager.open(fileName), StandardCharsets.UTF_8));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }
}

源码

github:https://github.com/panzhusheng/JDCategorydemo
gitee:https://gitee.com/pan-zs/JDCategorydemo

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

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

相关文章

【采购指南】国产芯片产业现状及采购建议

随着全球技术的飞速发展&#xff0c;芯片成为现代电子设备不可或缺的核心部分。中国作为全球最大的电子产品制造国&#xff0c;其芯片制造业也在经历快速的发展。近年来&#xff0c;国产芯片因技术进步、支持政策和市场需求不断提升&#xff0c;其在国内外市场的份额和影响力也…

C#小结:ScottPlot 5.0在VS2022桌面开发的应用(以winform为例)

目录 一、官网文档地址 二、在VS2022中安装Scottplot 三、拖动Scottplot 四、使用Scottplot 五、效果图 一、官网文档地址 官网地址&#xff1a;ScottPlot 5.0 食谱 本文内容来自于官网&#xff0c;选取了官网的一些比较好用的功能展示&#xff0c;如需学习更多功能&a…

【安装记录】Proxmox VE 8.0 安装

PVE(Proxmox VE) 下载地址&#xff1a;https://www.proxmox.com/en/downloads 2、安装 rufus &#xff08;1&#xff09;官网下载&#xff1a;https://rufus.ie/zh/ &#xff08;2&#xff09;打开即可使用&#xff1a; 3、使用 rufus 制作启动盘 (1)如果你的u盘之前被制作为…

Nginx 本地部署vue项目

1、 下载 Nginx 稳定版本 2、下载安装后&#xff0c;打开 nginx.conf配置文件 3、找到打包好的文件&#xff0c;并配置运行文件 文件的位置 root C:/server/build location /{root C:/server/build;index index.html index.htm;#解决刷新后nginx报404问题try_files $uri …

HarmonyOS-UIAbility组件概述及生命周期

UIAbility组件概述 概述 UIAbility组件是一种包含UI界面的应用组件&#xff0c;主要用于和用户交互。 UIAbility组件是系统调度的基本单元&#xff0c;为应用提供绘制界面的窗口&#xff1b;一个UIAbility组件中可以通过多个页面来实现一个功能模块。每一个UIAbility组件实例…

【数据结构】链表(单链表实现+测试+原码)

1.链表 1.1 链表的概念及结构 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表 中的指针链接次序实现的 。 现实中&#xff1a;链表就像是一列动车&#xff0c;一节连着一节 数据结构中的链表 注意: 1.从上图可看出…

微信小程序(二十五)条件判断语句与结构隐藏

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.条件判断语句的演示 2.隐藏结构的演示 源码&#xff1a; index.wxml <view><!-- wx:if和wx:else为条件判断语句 --><text wx:if"{{isLogin}}">已登入的用户</text><tex…

Maven基本使用

Maven简介: Apache Maven 是一个项目管理和构建工具&#xff0c;它基于项目模型(POM)的概念&#xff0c;通过一小段描述信息来管理项目的构建&#xff0c;报告和文档 Maven的作用: (1&#xff09;项目搭建&#xff1b; &#xff08;2&#xff09;依赖管理&#xff1b; &#xf…

7000字详解Spring Boot项目集成RabbitMQ实战以及坑点分析

本文给大家介绍一下在 Spring Boot 项目中如何集成消息队列 RabbitMQ&#xff0c;包含对 RibbitMQ 的架构介绍、应用场景、坑点解析以及代码实战。 我将使用 waynboot-mall 项目作为代码讲解&#xff0c;项目地址&#xff1a;https://github.com/wayn111/waynboot-mall。本文大…

Unity之做一个最简单的FPS游戏demo

目录 &#x1f60b;FPS游戏Demo &#x1f4a4;1.新建FPS模板项目 ⚒️2.装备枪 &#x1f4a3;3.设置射击功能 &#x1f4fa;4.制造一个子弹预制体 &#x1f3ae;5.发射子弹 说起来小编学Unity差不多一个月了&#xff0c;都是利用上班摸鱼时间学的&#xff08;doge.jpg&…

【3万块指令免费送】Evol-Instruct 应用:扩充大模型数据多样性

Evol-Instruct 应用&#xff1a;扩充大模型数据多样性 提出背景流程步骤总结Evol-Instruct 代码复现Evol-Instruct 应用&#xff1a;扩充大模型数据多样性 提出背景 论文&#xff1a;https://arxiv.org/pdf/2304.12244.pdf 代码&#xff1a;https://github.com/nlpxucan/Wiza…

如何提高思维能力,洞悉事物本质?(二)

在上一篇文章里&#xff0c;我们分享了几个简单、有效的思维模型。 这一篇&#xff0c;会继续探讨这个话题&#xff0c;向大家介绍几个常用的思维模型。 今天的主题是「找本质」。 大多数问题&#xff0c;当我们思考和讨论的时候&#xff0c;许多人常犯的错误&#xff0c;其实是…

【Redis】实现购物秒杀及分布式锁

Redis实现购物秒杀及分布式锁 全局唯一ID Redis自增ID策略 ID构造是:时间戳 + 计数器 每天一个key,方便统计订单量 业务实现 获取指定时间的秒数 LocalDateTime timeBegin = LocalDateTime.of(2024, 1, 1, 0, 0, 0); long second = timeBegin.toEpochSecond(ZoneOffset…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之DatePicker组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之DatePicker组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、DatePicker组件 日期选择器组件&#xff0c;用于根据指定日期范围创建日期滑…

前端工程\模块化

前端工程\模块化&#x1f3ed; 本篇文章&#xff0c;学习记录于&#xff1a;尚硅谷&#x1f3a2;&#xff0c;紧接前文&#xff1a;邂逅Node.JS的那一夜→博客 无论是前端、后端、甚至非编程领域都有模块化的概念&#xff0c;只是不同的领域叫法不同&#xff0c;不过&#xf…

n-皇后-dfs

import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.Scanner;public class Main {static int n,N 20; //这里只会用到2 * n - 1的格子,开大点保险static char[][] g new c…

编曲学习:功能和声 歌曲结构 和弦编配(上)

34届三和弦 功能和声 歌曲结构 和弦编配&#xff08;上&#xff09;https://app8epdhy0u9502.pc.xiaoe-tech.com/live_pc/l_65b4e014e4b064a83b8f44fd?course_idcourse_2XLKtQnQx9GrQHac7OPmHD9tqbv 34届独立音乐人编曲训练营https://app8epdhy0u9502.pc.xiaoe-tech.com/p/t_…

【Java程序设计】【C00219】基于SSM的大学生课程管理系统(论文+PPT)

基于SSM的大学生课程管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这个一个基于SSM的大学生课程管理系统&#xff0c;本系统共分为三种权限&#xff1a;管理员、教师和学生 管理员&#xff1a;查看个人中心、学生管理、公告信…

CTF-WEB的知识体系

CTF概念 CTF是Capture The Flag的缩写&#xff0c;中文一般译作夺旗赛 CTF起源于1996年DEFCON全球黑客大会 DEFCONCTF是全球技术水平和影响力最高的CTF竞赛 竞赛模式 解题模式:解决网络安全技术挑战(即找到flag)&#xff0c;提交后获取相应分值。 攻防赛模式:要求找到其他队…

计算机基础知识讲解(原码反码补码)(以及在C语言里面是如何计算和运用的)

补码反码掩码以及原理 补码、反码和掩码是计算机科学中用于表示和处理数值的三种编码方式。 原码 原码是最直观的数值表示方法&#xff0c;它将数值的二进制表示与其符号位结合起来。在原码表示中&#xff0c;正数的符号位为0&#xff0c;而负数的符号位为1。原码的缺点在于…