【Android】ListView和RecyclerView知识总结

news2024/11/22 15:53:59

文章目录

  • ListView
    • 步骤
    • 适配器Adpter
    • ArrayAdapter
    • SimpleAdapter
    • BaseAdpter
    • 效率问题
  • RecyclerView
    • 具体实现
    • 不同布局形式的设置
      • 横向滚动
      • 瀑布流
      • 网格
    • 点击事件

ListView

ListView 是 Android 中的一种视图组件,用于显示可滚动的垂直列表。每个列表项都是一个视图对象,ListView 会通过适配器(Adapter)将数据绑定到这些视图对象上。它通常用于显示一组相似的数据,比如联系人列表、消息列表等。

步骤

  1. 准备数据:这是数据源,通常是一个数组或一个List
  2. 构建适配器:适配器用于将数据映射到ListView的每一项。你可以使用系统提供的适配器(如ArrayAdapter)或者自定义适配器。
  3. 绑定适配器到ListView:将适配器设置到ListView上。
  4. 处理ListView项的点击事件:添加点击事件监听器来处理每一项的点击事件。

适配器Adpter

作用:充当 ListView 和数据源之间的桥梁,将数据源转换为可以显示在 ListView 中的视图项。

image-20240723093657352

常用适配器类型

  1. ArrayAdapter:适用于简单的数据源,如数组或列表。它将每个数据项转换为一个 TextView 或其他简单视图。
  2. SimpleAdapter:用于将复杂的数据源(如 List<Map<String, Object>>)绑定到多个视图。
  3. Custom Adapter:通过继承 BaseAdapter 或其他适配器类,可以创建自定义适配器以实现复杂的需求。

ArrayAdapter

新建一个ArrayListActivity类及其布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

添加入一个ListView控件

public class ArrayListActivity extends AppCompatActivity {
    private ListView mListView;
    private List<String> mStringList;
    private ArrayAdapter<String> mArrayAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_array_list);
       
        // 初始化 ListView。
        mListView = findViewById(R.id.lv);
        
        // 初始化字符串列表并填充数据。
        mStringList = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            mStringList.add("这是条目" + i);
        }
        
        // 使用 ArrayAdapter 绑定数据到 ListView。
        mArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mStringList);
        mListView.setAdapter(mArrayAdapter);
        
        // 设置 ListView 的点击事件。
        mListView.setOnItemClickListener((parent, view, position, id) -> {
            Toast.makeText(ArrayListActivity.this, "你点击了" + position, Toast.LENGTH_SHORT).show();
        });
        // 设置 ListView 的长按事件。
        mListView.setOnItemLongClickListener((parent, view, position, id) -> {
            Toast.makeText(ArrayListActivity.this, "你长按了" + position, Toast.LENGTH_SHORT).show();
            return true;
        });
    }
}
  • mListView = findViewById(R.id.lv);

    获得ListView组件

  • mStringList = new ArrayList<>();

    创建一个list储存信息

  • mArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mStringList);

    1. 创建了一个ArrayAdapter对象,命名为mArrayAdapter。
    2. 通过构造函数传入了三个参数:
      • this:表示当前的上下文对象,即这个ArrayAdapter将被用于当前的Activity或Fragment中。
      • android.R.layout.simple_list_item_1:表示列表项的布局文件,这里使用了Android系统提供的简单列表项布局,该布局只有一个文本视图。
      • mStringList:表示要显示的数据集合,即一个字符串列表。

    通过这个ArrayAdapter对象,可以将mStringList中的字符串显示在列表视图中。

  • mListView.setAdapter(mArrayAdapter);

    mArrayAdapter对象设置为mListView的适配器

实现效果:

Screenshot_2024-07-23-10-28-26-233_com.example.la

SimpleAdapter

SimpleAdapter是Android中用于将数据模型转换成ListView或其他视图组件的适配器。它简化了数据绑定过程,通过映射数据集中的字段到布局文件中的视图

同样新建一个ArrayListActivity类及其布局文件

<?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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

xml和刚才一致

public class SimpleListActivity extends AppCompatActivity {
    
    private ListView mListView;
    private SimpleAdapter msimpleAdapter;
    private List<Map<String, Object>> mList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple_list);
        
        // 初始化ListView
        mListView = findViewById(R.id.lv);
        // 初始化并填充列表数据
        mList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Map<String, Object> map1 = new HashMap<>();
            map1.put("image", R.drawable.apple);
            map1.put("text", "苹果");
            mList.add(map1);
            Map<String, Object> map2 = new HashMap<>();
            map2.put("image", R.drawable.banana);
            map2.put("text", "香蕉");
            mList.add(map2);
            Map<String, Object> map3 = new HashMap<>();
            map3.put("image", R.drawable.litchi);
            map3.put("text", "荔枝");
            mList.add(map3);
        }
        
        // 使用SimpleAdapter绑定数据到ListView
        msimpleAdapter = new SimpleAdapter(this, mList, R.layout.list_item_layout,
                new String[]{"image", "text"}, new int[]{R.id.image, R.id.tv});
        mListView.setAdapter(msimpleAdapter);
    } 
}
  • msimpleAdapter = new SimpleAdapter(this, mList, R.layout.list_item_layout,

    new String[]{"image", "text"}, new int[]{R.id.image, R.id.tv});

    1. 创建了一个SimpleAdapter对象,用于将数据绑定到ListView上。
    2. this:上下文对象,表示当前的Activity或Fragment。
    3. mList:数据源,通常是一个List集合,包含了要展示的数据。
    4. R.layout.list_item_layout:不同于刚才安卓自带的,这里我们使用自己创建的布局,下面的两个参数String[]是刚才map数组中的键,int[]是自定义布局中对应的视图id
    5. new String[]{"image", "text"}:数据源中要展示的字段名数组,这里表示要展示名为"image"和"text"的字段。
    6. new int[]{R.id.image, R.id.tv}:对应字段在布局文件中的控件ID数组,这里表示字段"image"对应ID为R.id.image的ImageView控件,字段"text"对应ID为R.id.tv的TextView控件
  • mListView.setAdapter(msimpleAdapter);

R.layout.list_item_layout:自定义的布局

<?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"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/image"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_weight="1" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="3" />

</LinearLayout>

实际效果:
在这里插入图片描述

BaseAdpter

新建一个ItemBean类来存储数据

public class ItemBean {
    private String name;
    private int imageId;

    public ItemBean(String name, int imageId) {
        this.name = name;
        this.imageId = imageId;
    }

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

    public void setImageId(int imageId) {
        this.imageId = imageId;
    }

    public String getName() {
        return name;
    }

    public int getImageId() {
        return imageId;
    }
}

接下来为这个类构造适配器

继承BaseAdapter类,自动生成四个重写方法

/**
 * 自定义适配器,用于在ListView中显示物品列表。
 * 该适配器负责将数据集中的每个项目绑定到相应的视图上。
 */
public class MyAdapter extends BaseAdapter {
    // 存储物品数据的列表
    private List<ItemBean> mlist;
    // LayoutInflater用于从XML文件中加载布局
    private LayoutInflater mLayoutInflater;
    // 上下文对象,用于获取资源和进行其他上下文相关的操作
    private Context mcontext;

    /**
     * 构造函数初始化适配器。
     * 
     * @param mlist 物品数据的列表
     * @param mcontext 上下文对象,用于初始化LayoutInflater
     */
    public MyAdapter(List<ItemBean> mlist, Context mcontext) {
        this.mlist = mlist;
        this.mcontext = mcontext;
        this.mLayoutInflater = LayoutInflater.from(mcontext);
    }

    //返回数据集的大小
    @Override
    public int getCount() {
        return mlist.size();
    }

    //根据位置获取数据集中的物品。
    @Override
    public Object getItem(int position) {
        return mlist.get(position);
    }

    // 获取物品在ListView中的唯一标识符
    @Override
    public long getItemId(int position) {
        return position;
    }

    /**
     * 为ListView的每个项目创建并返回一个视图。
     * 
     * @param position 物品的位置
     * @param convertView 当前被重用的视图
     * @param parent 视图的父容器
     * @return 绑定到数据集中的视图
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // 使用LayoutInflater加载列表项的布局
        convertView = mLayoutInflater.inflate(R.layout.list_item_layout, parent, false);
        
        // 查找并初始化列表项中的ImageView和TextView
        ImageView img = convertView.findViewById(R.id.image);
        TextView tv = convertView.findViewById(R.id.tv);
        
        // 获取当前位置的物品数据,设置ImageView的图片资源
        ItemBean itemBean = mlist.get(position);
        img.setImageResource(itemBean.getImageId());
        tv.setText(itemBean.getName());
        
        return convertView;
    }
}
  • convertView = mLayoutInflater.inflate(R.layout.list_item_layout, parent, false);

    mLayoutInflater通过构造方法处的LayoutInflater.from(mcontext)赋值

    调用其inflate方法:

    1. convertView: 这个变量通常用来存储从布局文件转换而来的View对象。在ListViewRecyclerViewgetView()方法中,它会被检查是否为空。如果非空,那么会直接使用这个View对象来展示数据,以避免频繁创建新的View,从而提高性能。
    2. mLayoutInflater: 这是一个LayoutInflater实例,它是Android框架提供的一个类,用于将XML布局文件转换为对应的View对象。
    3. R.layout.list_item_layout: 这是一个资源ID,指向了XML布局文件list_item_layout.xml。这个布局文件定义了一个ListViewRecyclerView中单个item的外观和结构,包括控件的类型、大小、位置以及样式等。
    4. parent: 这是一个ViewGroup类型的参数,代表了新创建的View最终将被添加到的父容器。在ListViewRecyclerView的情况下,parent就是ListViewRecyclerView本身。虽然在这个调用中,我们并没有立即把新创建的View添加到parent中(因为false参数),但这个参数还是需要的,因为它会影响LayoutInflater如何计算View的尺寸和位置。
    5. false: 这个布尔值参数告诉LayoutInflater不要将生成的View添加到parent中。这是因为ListViewRecyclerView有自己的逻辑来管理子View的添加和移除,它们会在适当的时候将View添加到自己内部的ViewGroup中。

    下面是BaseAdpterActivity类,和前两个步骤相似

    public class BaseAdpterActivity extends AppCompatActivity {
        
        private ListView mListView;
        private BaseAdapter mBaseAdapter;
        private List<ItemBean> mlist;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_base_adpter);
    
            // 初始化数据列表,这里使用了循环来添加多个数据项。
            mlist = new ArrayList<>();
            for (int i = 0; i < 20; i++) {
                ItemBean itemBean1 = new ItemBean("apple", R.drawable.apple);
                ItemBean itemBean2 = new ItemBean("banana", R.drawable.banana);
                ItemBean itemBean3 = new ItemBean("litchi", R.drawable.litchi);
                mlist.add(itemBean1);
                mlist.add(itemBean2);
                mlist.add(itemBean3);
            }
    
            // 初始化ListView和其适配器
            mListView = findViewById(R.id.lv);
            mBaseAdapter = new MyAdapter(mlist, this);
            mListView.setAdapter(mBaseAdapter);
        }
    }
    

    效果:

    Screenshot_2024-07-23-12-24-11-021_com.example.la

效率问题

列表中信息的出现需要频繁调用getView方法,效率很低。

public class MyAdapter extends BaseAdapter {
    //省略这里代码.......
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        
        ViewHolder viewHolder;
        
        if (convertView == null) {
            // 如果convertView为空,说明该视图是第一次被创建
            convertView = mLayoutInflater.inflate(R.layout.list_item_layout, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.img = convertView.findViewById(R.id.image);
            viewHolder.tv = convertView.findViewById(R.id.tv);
            convertView.setTag(viewHolder);
        } else {
            // 如果convertView不为空,说明该视图可以被复用,直接从标签中获取ViewHolder对象
            viewHolder = (ViewHolder) convertView.getTag();
        }
        // 获取当前位置的物品数据
        ItemBean itemBean = mlist.get(position);
        // 绑定数据到视图
        viewHolder.img.setImageResource(itemBean.getImageId());
        viewHolder.tv.setText(itemBean.getName());

        return convertView;
    }

    /**
     * ViewHolder类用于缓存ListView项的视图引用,
     * 以减少在getView方法中每次都需要通过findViewById查找视图的开销。
     */
    class ViewHolder {
        ImageView img;
        TextView tv;
    }
}
  1. convertView为空:创建一个新的视图并初始化它,然后使用 setTag() 方法将一个包含子控件引用的对象与 convertView 关联起来。
  2. convertView不为null,则调用 getTag() 方法来获取之前存储的 ViewHolder 对象,这样就可以直接访问子控件而不需要再次查找它们。
  3. 使用setTag()getTag()方法来缓存这些子控件的引用
  4. ViewHolder:每次getView()方法被调用时,如果直接在视图中使用findViewById()方法来获取子视图,这会导致性能下降,因为findViewById()是一个耗时的操作。ViewHolder模式通过在视图首次创建时保存对所有子视图的引用,避免了后续滚动时的多次查找

RecyclerView

RecyclerView 是 Android 提供的一个更高级和灵活的列表视图控件,相对于 ListViewRecyclerView 提供了更多的功能和更好的性能。它引入了一些新的概念,如 ViewHolder 模式,更高效的滚动和动画支持,以及更灵活的布局管理器(LayoutManager)。

具体实现

可以实现和ListView一致的效果

Screenshot_2024-07-23-12-24-11-021_com.example.la

示例目录:

image-20240723154019488

  1. 主布局文件 activity_main.xml

加入RecyclerView控件,宽高设置match_parent占满布局。

<?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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rlv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textAllCaps="false"/>

</LinearLayout>
  1. 数据模型 FruitBean.java,和刚刚的一致
public class FruitBean implements Serializable {
    private String name;
    private int imageId;

    public FruitBean() {
    }
    public FruitBean(String name, int imageId) {
        this.name = name;
        this.imageId = imageId;
    }

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

    public void setImageId(int imageId) {
        this.imageId = imageId;
    }

    public String getName() {
        return name;
    }

    public int getImageId() {
        return imageId;
    }
}
  1. 自定义适配器MyAdapter
// RecyclerView的适配器类,用于将数据集中的数据绑定到RecyclerView的各个Item上。
//继承RecyclerView.Adapter,这里的泛型是下面的内部类
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    
    // 数据源列表
    private List<FruitBean> mList;
    // 布局填充器,用于将XML布局文件转换为View对象
    private LayoutInflater mLayoutInflater;
    // 上下文对象
    private Context mContext;

    //构造函数,初始化适配器。
    public MyAdapter(List<FruitBean> mList, Context mContext) {
        this.mList = mList;
        this.mContext = mContext;
        this.mLayoutInflater = LayoutInflater.from(mContext);
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // 将布局文件转换为View对象
        View view = mLayoutInflater.inflate(R.layout.list_item_layout, parent, false);
        // 创建并返回ViewHolder实例
        MyViewHolder myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

     // 将数据绑定到ViewHolder,在RecyclerView滚动时会不断调用
    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
       // 获取当前项的数据
        FruitBean fruitBean = mList.get(position);

        // 将数据绑定到ViewHolder中的TextView和ImageView
        holder.tv.setText(fruitBean.getName());
        holder.img.setImageResource(fruitBean.getImageId());
    }

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

     // ViewHolder类,用于持有每个列表项的视图
    class MyViewHolder extends RecyclerView.ViewHolder {
		// 列表项中的ImageView和TextView
        private ImageView img;
        private TextView tv;

        public MyViewHolder(View view) {
            super(view);

            // 通过itemView获取布局中的控件,并设置参数
            this.img = view.findViewById(R.id.image);
            this.tv = view.findViewById(R.id.tv);
        }
    }
}
  1. MainActivity
public class MainActivity extends AppCompatActivity {
    // 声明RecyclerView、数据列表和适配器
    private RecyclerView mrecyclerView;
    private List<FruitBean> mlist;
    private MyAdapter myAdapter;

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

        // 初始化数据
        initData();

        // 绑定RecyclerView,设置适配器
        mrecyclerView = findViewById(R.id.rlv);
        myAdapter = new MyAdapter(mlist, this);
        mrecyclerView.setAdapter(myAdapter);
        // 设置布局管理器,这里是竖向滚动
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        mrecyclerView.setLayoutManager(layoutManager);
    }

    // 初始化数据列表,添加多个水果项
    private void initData() {
        mlist = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            FruitBean itemBean1 = new FruitBean("apple", R.drawable.apple);
            FruitBean itemBean2 = new FruitBean("banana", R.drawable.banana);
            FruitBean itemBean3 = new FruitBean("litchi", R.drawable.litchi);
            mlist.add(itemBean1);
            mlist.add(itemBean2);
            mlist.add(itemBean3);
        }
    }
}

不同布局形式的设置

横向滚动

只用改一行代码

 RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
        mrecyclerView.setLayoutManager(layoutManager);

new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)

  • 这里创建了一个LinearLayoutManager实例
  • this:传入的是当前Activity的上下文(Context)。
  • LinearLayoutManager.HORIZONTAL:表示RecyclerView的布局方向为水平(HORIZONTAL),即列表项将水平排列。
  • false:表示不反转布局。false意味着列表项从起点到终点正常排列,如果设置为true,列表项将从终点到起点反向排列。

瀑布流

RecyclerView.LayoutManager layoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);

new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.HORIZONTAL)

  • 2:表示布局中有2个跨度(列或行,取决于方向)。在水平布局中,这表示有2行。
  • StaggeredGridLayoutManager.HORIZONTAL:表示RecyclerView的布局方向为垂直,即列表项将垂直排列,并且每一列包含多个项目。

网格

RecyclerView.LayoutManager layoutManager = new GridLayoutManager(this,2);

new GridLayoutManager(this, 2)

  • this:传入的是当前Activity的上下文(Context)。
  • 2:表示布局中有2个跨度(列)。这意味着RecyclerView的每一行将包含2个项目。

点击事件

ViewHolder中添加rlContainer变量来保存最外层布局的实例,再在onBindViewHolder方法中为他注册点击事件

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
//省略
    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        FruitBean fruitBean = mList.get(position);

        holder.tv.setText(fruitBean.getName());
        holder.img.setImageResource(fruitBean.getImageId());

        // 设置容器布局的点击事件
        holder.rlContainer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext, "你点击了" + position, Toast.LENGTH_SHORT).show();
            }
        });
    }


    class MyViewHolder extends RecyclerView.ViewHolder {

        private ImageView img;
        private TextView tv;
        //添加最外层的布局属性
        RelativeLayout rlContainer;

        public MyViewHolder(View view) {
            super(view);

            this.img = view.findViewById(R.id.image);
            this.tv = view.findViewById(R.id.tv);
            this.rlContainer = view.findViewById(R.id.rl_item_container);
        }
    }
}


感谢您的阅读
如有错误烦请指正


参考:

  1. 26-Android中的列表-RecyclerView_哔哩哔哩_bilibili
  2. 【Android】Fragment的静态动态创建以及两种创建方式的生命周期-CSDN博客
  3. 《第一行代码》

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

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

相关文章

spring IOC DI --DI详解

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 今天你敲代码了吗 文章目录 4.3 DI详解4.3.1属性注入4.3.2 构造方法注入4.3.3 Setter注入4.3.4 三种注入优缺点 4.4 Autowired 存在问题PrimaryQualifier 4.3 DI详解 依赖注入是一个过程,是指Ioc容器在创建Bean…

在 Android 上实现语音命令识别:详细指南

在 Android 上实现语音命令识别:详细指南 语音命令识别在现代 Android 应用中变得越来越普遍。它允许用户通过自然语言与设备进行交互,从而提升用户体验。本文将详细介绍如何在 Android 上实现语音命令识别,包括基本实现、带有占位槽位的命令处理,以及相关的配置和调试步骤…

C++:模板(函数模板,类模板)

目录 泛型编程 函数模板 函数模板格式 函数模板的原理 函数模板的实例化 类模板 类模板格式 类模板实例化 模板分为函数模板和类模板 在C中使用模板可以让我们实现泛型编程 泛型编程 如果我们需要实现一个加法add函数&#xff0c;那么会怎么实现呢&#xff1f; int…

AI学习记录 - 规范化输出对接现有系统的实例

假设我们有一个学生管理系统&#xff0c;通过prompt提示&#xff0c;格式化输出然后对接现有系统&#xff0c;也是通过react实现&#xff0c;因为这只是一个知识分享&#xff0c;没弄太复杂&#xff08;使用react实现&#xff09;。 学生管理系统 1、设计好prompt getMemory()…

大屏数据看板一般是用什么技术实现的?

我们看到过很多企业都会使用数据看板&#xff0c;那么大屏看板的真正意义是什么呢&#xff1f;难道只是为了好看&#xff1f;答案当然不仅仅是。 大屏看板不仅可以提升公司形象&#xff0c;还可以提升企业的管理层次。对于客户&#xff0c;体现公司实力和品牌形象&#xff0c;…

Linux shell编程学习笔记66:ping命令 超详细的选项说明

0 前言 网络信息是电脑网络信息安全检查中的一块重要内容&#xff0c;Linux和基于Linux的操作系统&#xff0c;提供了很多的网络命令&#xff0c;今天我们研究最常用的ping命令。 1 ping命令 的功能、格式和选项说明 1.1 ping命令 的功能 简单来说&#xff0c; ping 命令 会…

编写SpringBoot的自定义starter包

starter项目 先来看一下Starter的官方解释&#xff1a; Spring Boot Starter 是一种方便的依赖管理方式&#xff0c;它封装了特定功能或技术栈的所有必要依赖项和配置&#xff0c;使得开发者可以快速地将这些功能集成到Spring Boot项目中。Spring Boot官方提供了一系列的Star…

首次 Cloudberry Database 社区聚会 · 北京站,8月3日,诚邀

近期 Greenplum 源码归档及走向闭源在圈内讨论火热&#xff0c;原有开源用户面临断档风险。作为 Greenplum 衍生版和开源替代&#xff0c;Cloudberry Database 由原厂核心开发者打造&#xff0c;与其保持兼容&#xff0c;并且具备更新内核和更丰富功能。Cloudberry Database 逐…

代理协议解析:如何根据需求选择HTTP、HTTPS或SOCKS5?

代理IP协议是一种网络代理技术&#xff0c;可以实现隐藏客户端IP地址、加速网站访问、过滤网络内容、访问内网资源等功能。常用的IP代理协议主要有Socks5代理、HTTP代理、HTTPS代理这三种。代理IP协议主要用于分组交换计算机通信网络的互联系统中使用&#xff0c;只负责数据的路…

【MATLAB实战】基于UNet的肺结节的检测

数据&#xff1a; 训练过程图 算法简介&#xff1a; UNet网络是分割任务中的一个经典模型,因其整体形状与"U"相似而得名,"U"形结构有助于捕获多尺度信息,并促进了特征的精确重建&#xff0c;该网络整体由编码器,解码器以及跳跃连接三部分组成。 编码器由…

UE4/5 对话系统

参考教程&#xff1a;UE4甜筒教艺术生学蓝图#21.UE4对话系统(1)--唠嗑案例展示_哔哩哔哩_bilibili 说来惭愧两年前看的教程&#xff0c;现在才记录一下&#xff0c;很好的教程推荐大家观看 1.首先创建两个枚举&#xff0c;内容如下 2.创建三个结构体&#xff0c;内容如下 3.再…

SSRF:服务端请求伪造

SSRF漏洞原理 SSRF漏洞通常是因为服务端应用程序提供了从其他服务器获取数据的功能&#xff0c;但未对目标地址或协议进行适当的过滤和限制。攻击者可以通过这个漏洞发送构造好的恶意请求&#xff0c;让服务器以自己的身份去访问其他资源&#xff0c;与文件包含漏洞有些许相似…

遍历dom元素下面的子元素的方法,vue中原始标签的ref得到是该元素的dom及下面包含的子dom,与组件ref是引用不同

研究到这个的目的来源是 想用div 遍历方式 替代之前的table tr td 那种框选功能&#xff0c;觉得div灵活&#xff0c;可以随便在外面套层&#xff0c;td与tr之间就不能加div加了布局就乱&#xff0c;然后使用之前的原理&#xff08; const cellList tableIdR.value.querySelec…

Caché 数据库摘要与手册索引

因为设置了 VIP 可见,对于无法直接阅读该篇博客的,建议直接阅读官方博客,链接如下: Cach & Ensemble 2018.1.4 – 2018.1.9 | Documentation Home Page (intersystems.com)https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls 目录 一、简介 0、…

【Socket 编程】应用层自定义协议与序列化

文章目录 再谈协议序列化和反序列化理解 read、write、recv、send 和 tcp 为什么支持全双工自定义协议网络计算器序列化和反序列化 再谈协议 协议就是约定&#xff0c;协议的内容就是约定好的某种结构化数据。比如&#xff0c;我们要实现一个网络版的计算器&#xff0c;客户端…

掌握互联网路由选择协议:从基础入门到实战

文章目录 路由选择协议的基本概念路由选择算法的分类分层次的路由选择协议路由信息协议&#xff08;RIP&#xff09;内部网关协议&#xff1a;OSPF外部网关协议&#xff1a;BGP互联网中的实际应用总结 互联网的路由选择协议是网络通信的核心&#xff0c;它决定了数据包如何在网…

Artix7系列FPGA实现SDI视频编解码+图像缩放+多路视频拼接,基于GTP高速接口,提供4套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本博已有的FPGA图像缩放方案本博已有的已有的FPGA视频拼接叠加融合方案本方案的无缩放应用本方案在Xilinx--Kintex系列FPGA上的应用本方案在Xilinx--Zynq系列FPGA上的应用 3、详细设计方案设计原理框图S…

nodejs编译报错 集合

目录 一、使用命令编译typescript时报错&#xff0c;报错文件tsconfig.json 二、npm start运行后报错&#xff0c;could not find module 一、使用命令编译typescript时报错&#xff0c;报错文件tsconfig.json npx tsc 报错&#xff1a; Specified include paths were [&…

Layer2区块链扩容方案(1)——总述

写在前面 这篇文章作为一个简单介绍&#xff0c;很多技术只是大致提及或者引用&#xff0c;之后会在详细学习后逐项解释。 补充知识 在了解扩容方案之前&#xff0c;我们最好了解一些相关的知识概念 EVM “EVM” 是“Ethereum Virtual Machine”&#xff08;以太坊虚拟机&…

SSRF学习笔记

1.NAT学习 Nat&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;是 一种网络通信技术主要用于将私有网络中的内部IP地址转换成公共网络中的公共IP地址&#xff0c;以实现局域网内部设备访问互联网的功能。具体来说&#xff0c;Nat有以下几个主要…