UI自动刷新大法:DataBinding数据绑定

2024-02-12 22:36

本文主要是介绍UI自动刷新大法:DataBinding数据绑定,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

之前我们讲了DataBinding在Activity、Fragment、RecyclerView中的基础使用,而那些常规使用方法里,每当绑定的变量发生数据变化时,都需要ViewDataBinding重新设值才会刷新对应UI。而DataBinding通过内部实现的观察者模式来进行自动刷新UI,这块内容是DataBinding的重要部分。在观察者模式的角度下,DataBinding库,允许我们使用对象、字段,或者集合来进行观察,当其中的一个可观察者数据对象绑定到了视图当中,并且数据对象的属性发生更改变化的时候,视图将会自动更新。而根据绑定的方式不同,又可分为 单向绑定双向绑定

单向绑定,实现数据变化自动驱动UI刷新,方式有三种:BaseObservable,ObservableField、ObservableCollection。在此之前,先让我们来了解下事件绑定。

前言 事件绑定

为了更好的了解单向绑定和后续的双向绑定,我们先来看下DataBinding中事件绑定的方式。严格来说,事件绑定也是一种变量绑定,只不过设置的绑定不再是单纯的变量,还是回调接口,事件绑定可设置的回调事件有以下:

android:onClick
android:onLongClick
android:onTextChanged
android:afterTextChanged
...

对应使用步骤也较为简单:

第一步 声明内部类

在要使用的activity类里新建一个内部类来声明对应的回调方法,这里我们接着用上篇文章中的工程来继续修改。我们在MainActivity中新建一个内部类,里面声明onClick()和afterTextChanged()事件:

public class MainActivity extends AppCompatActivity {UserInfo userInfo;DemoBinding viewDataBinding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);userInfo = new UserInfo("亚历山大", 66);viewDataBinding.setUserInfoExample(userInfo);viewDataBinding.setUserEventListener(new EventListener());}public class EventListener{public void changedUserName(){userInfo.setName("鸭梨山大二世");viewDataBinding.setUserInfoExample(userInfo);}public void changedUserInfo(){userInfo.setName("鸭力山大三世");userInfo.setAge(81);viewDataBinding.setUserInfoExample(userInfo);}}
}

第二步 修改布局标签内容

同时还要在相应布局文件中的< data>标签里声明此内部类路径,在对应设置此点击事件回调的控件里通过内嵌表达式 @{} 来设置引用。

<?xml version="1.0" encoding="utf-8"?>
<layout 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"><data><import type="com.example.dbjavatest.MainActivity.EventListener"/><import type="com.example.dbjavatest.bean.UserInfo"/><variablename="UserInfoExample"type="UserInfo" /><variablename="UserEventListener"type="EventListener" /></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/tv_user_first"android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="@{()->UserEventListener.changedUserName()}"android:text="@{UserInfoExample.name,default=defaultValue}"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"/><TextViewandroid:id="@+id/tv_user_second"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{String.valueOf(UserInfoExample.age),default=defaultValue}"app:layout_constraintTop_toBottomOf="@+id/tv_user_first"app:layout_constraintStart_toStartOf="parent"/><Buttonandroid:id="@+id/btn_change"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_constraintTop_toBottomOf="@+id/tv_user_second"app:layout_constraintStart_toStartOf="parent"android:text="改变属性"android:onClick="@{()->UserEventListener.changedUserInfo()}"/></androidx.constraintlayout.widget.ConstraintLayout>
</layout>

在这布局文件中,android:onClick="@{()->UserEventListener.changedUserName()}"属性含义即为点击事件响应方法为指定的UserEventListener中的changedUserName(),运行后,可查看效果如下:

DataBinding点击事件.gif

单向数据绑定之Base Observable

众所周知,一个单纯的ViewModel类被更新后,并不会让UI自动更新。Observable存在的目的就是为了数据变更后UI会自动刷新。

在此方面,Observable提供了两个方法:

· notifyChange()
· notifyPropertyChanged()

方法一notifyChange()会刷新所有的UI。

方法二notifyPropertyChanged()只会刷新属于它的UI,需要绑定属性(通过注解 @Bindable来绑定)。

使用方式也较为简单:

第一步 修改实体bean类

使实体bean类继承自BaseObservable:

public class UserInfo extends BaseObservable {public UserInfo(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;notifyPropertyChanged(BR.name);}public void setNameAndAge(String name,int age){this.name = name;this.age = age;notifyChange();}@Bindablepublic int getAge() {return age;}public void setAge(int age) {this.age = age;}@Bindablepublic String name; //public属性成员可直接在成员变量上方加上@Bindableprivate int age; //private属性成员需要在其get方法上添加@Bindable
}

第二步、修改对应Activity

为了凸显出区别,我们继续沿用上面点击事件中例子的布局,不做修改,但是Activity中代码要修改:

public class MainActivity extends AppCompatActivity {UserInfo userInfo;ActivityMainBinding viewDataBinding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);userInfo = new UserInfo("亚历山大", 66);viewDataBinding.setUserInfoExample(userInfo);viewDataBinding.setUserEventListener(new EventListener());}public class EventListener{public void changedUserName(){userInfo.setName("鸭梨山大二世");userInfo.setAge(999);//无效}public void changedUserInfo(){userInfo.setNameAndAge("鸭力山大X世",new Random().nextInt(100));}}
}

可以看到,相比于普通的点击事件代码中明显少了viewDataBinding.setUserInfoExample…等操作,可能一两个点击事件看不出明显差别,但事件一多,你会发现Activity的代码会省略很多,非常利于代码解耦和整洁性。这也不影响相应效果,运行效果如下:

DataBinding中的Observable点击事件.gif

可见,在点击用户名时,userInfo.setAge(999)执行无效的,因为在原实体bean类中,只设置了改变name属性(notifyPropertyChanged(BR.name)):

image.gif
所以在点击name属性的时候,只有名字在变化,而点击事件里setNameAndAge()中因为声明了notifyChange();改变所有元素,因此可看到点击按钮时,全局属性跟着改变了(name属性一致固定写死,所以你可能觉得名字没变化)。

二、单项数据绑定之ObservableField

有的时候相应工程里,实体Bean类需要继承其他类,这样就无法使用Observable了。这时有另外一个方案,即ObservableField。PS:ObservableField不需要进行notify操作。

在ObservableField中,官方提供了对基本数据类型的封装,如ObservableInt、ObservableLong、ObservableFloat、ObservableDouble ObservableShort、ObservableBoolean、ObservableByte、ObservableChar以及 ObservableParcelable 。当然也可通过泛型来申明其他类型,可以说这是官方对Observable中字段的注解和刷新等操作等封装。

其使用方式与Observable还是有点区别的:

第一步 修改实体bean类

public class UserInfo{public final ObservableField<String> name;public final ObservableField<Integer> age;public ObservableField<String> getName() {return name;}public ObservableField<Integer> getAge() {return age;}public UserInfo(String name,Integer age){this.name=new ObservableField<>(name);this.age= new ObservableField<Integer>(age);}
}

可见Bean文件在这里取消了继承,对变量进行了public final修饰,重写对应的get()(final修饰的变量无法写set())。其set()属性的方式则有些许不一样。

第二步 修改对应逻辑

在对应需要进行set逻辑的地方,可以通过ObservableField提供的get、set方法,去拿到值和设置值来达到更新UI效果。如下:

public class MainActivity extends AppCompatActivity {UserInfo userInfo;ActivityMainBinding viewDataBinding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);userInfo = new UserInfo("亚历山大", 66);viewDataBinding.setUserInfoExample(userInfo);viewDataBinding.setUserEventListener(new EventListener());}public class EventListener{public void changedUserName(){userInfo.getName().set("鸭梨山大二世");}public void changedUserInfo(){userInfo.getName().set("鸭梨山大一世");userInfo.getAge().set(new Random().nextInt(101));}}
}

对应的效果为:

DataBinding-Field点击事件.gif

三、单项数据绑定之ObservableCollection

ObservableCollection中最常用的是ObservableList 和 ObservableMap,即dataBinding 提供的包装类用于替代原生的 List 和 Map。其使用方式与前两者差别也不大。

第一步 修改Collection布局

这里我们不再使用实体bean类,而是dataBinding 包装的ObservableMap和ObservableList元素,因此需要修改< data>标签。如下:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"><data><import type="androidx.databinding.ObservableMap"/><import type="androidx.databinding.ObservableList"/><!--注意这里,只能用 "&lt;"和 "&gt;"--><variablename="list"type="ObservableList&lt;String&gt;"/><variablename="map"type="ObservableMap&lt;String,Integer&gt;"/><variablename="sing"type="String"/><variablename="num"type="int"/></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/tv_user_first"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{list[num],default=syt}"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"/><TextViewandroid:id="@+id/tv_user_second"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{String.valueOf(map[sing]),default=sys}"app:layout_constraintTop_toBottomOf="@+id/tv_user_first"app:layout_constraintStart_toStartOf="parent"/><Buttonandroid:id="@+id/btn_change"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_constraintTop_toBottomOf="@+id/tv_user_second"app:layout_constraintStart_toStartOf="parent"android:text="改变属性"android:onClick="onButtonClick"/></androidx.constraintlayout.widget.ConstraintLayout>
</layout>

这里的ObservableMap和ObservableList归属的databinding在androidX包里,如果你的工程还没有适配安卓X,最好请尽快适配。最后一个Button里的android:onClick="onButtonClick"可能会让你感到疑惑,但其实这也是dataBinding里的控件的点击事件写法之一。

第二步 修改Activity中对应逻辑

其Activity中代码就如下:

public class MainActivity extends AppCompatActivity{ActivityMainBinding viewDataBinding;private ObservableMap<String, Integer> map;ObservableArrayList<String> obList;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);map = new ObservableArrayMap<>();map.put("test_num",1 );map.put("test_biger_num", 100);viewDataBinding.setMap(map);obList = new ObservableArrayList<>();obList.add("ObservableArrayList");obList.add("observablelist");obList.add("observablelist more");viewDataBinding.setList(obList);viewDataBinding.setNum(0);viewDataBinding.setSing("test_biger_num");}public void onButtonClick(View v) {map.put("test_biger_num",new Random().nextInt(99));}}

对应效果如下:

DataBinding_ObservableCollection点击事件.gif

当然,设置点击事件还有一种方法引用,直接用 :: 即可,
如: android:onClick=“@{listener::onClick}” 就是方法引用绑定!

四、双向数据绑定

双向绑定含义就是 在数据更新时使得View也能更新,而View更新的时候也同时更改数据

此法不适合所有的应用场景,但也有相应的应用场景,比如用户注册登录场景,在输入账号和密码同时,UI刷新同时数据也更新,这里就适合双向绑定。可以说,双向绑定时安卓MVVM架构的基础。
这次简单实例我们用ObservableField方式,先写一个bean实体类:

public class DataBean {public final ObservableField<String> dataInfo;public DataBean(ObservableField<String> dataInfo) {this.dataInfo = dataInfo;}public ObservableField<String> getDataInfo() {return dataInfo;}
}

对应也要修改布局文件和引入,如下:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"><data><import type="com.example.dbjavatest.bean.DataBean"/><variablename="dataInfoBean"type="DataBean" /></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/tv_data"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="26sp"android:textColor="@color/purple_200"android:text="@{dataInfoBean.dataInfo}"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"android:layout_marginLeft="50dp"/><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入数据"android:text="@={dataInfoBean.dataInfo}"app:layout_constraintTop_toBottomOf="@+id/tv_data"android:textSize="25sp"android:layout_marginTop="30dp"android:paddingLeft="20dp"/></androidx.constraintlayout.widget.ConstraintLayout>
</layout>

这里要注意,在EditText中更新数据时会同步到上面的TextView,绑定方式跟单向绑定方式相比,要在内嵌表达式中多用一个“=”,即android:text=“@={dataInfoBean.dataInfo}”。

对应Activity中代码如下:

public class MainActivity extends AppCompatActivity{ActivityMainBinding viewDataBinding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);DataBean dataBean = new DataBean(new ObservableField<String>(""));viewDataBinding.setDataInfoBean(dataBean);}
}

效果也能猜到:

DataBinding双向绑定.gif

五、List Set Map等数据结构

除了ObservableCollection,DataBinding也支持原生Java数据结构(数组、List、Set和Map)在布局文件中使用,且在布局文件中都可以通过list[index]的形式来获取元素。

官方为了和< variable>标签元素区分开,在声明具有多个泛型的数据类型时,需要使用"& lt;"和 " >"用以区分。如下:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><data><import type="java.util.List" /><import type="java.util.Set" /><import type="java.util.Map" /><variablename="array"type="String[]" /><variablename="list"type="List&lt;String&gt;" /><variablename="map"type="Map&lt;String, String&gt;" /><variablename="set"type="Set&lt;String&gt;" /><variablename="num"type="int" /><variablename="sing"type="String" /></data><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><TextView···android:text="@{array[1]}" /><TextView···android:text="@{list[num]}" /><TextView···android:text="@{map[sing]}" /><TextView···android:text='@{map["test"]}' /></LinearLayout>
</layout>

六、使用相应类方法

在DataBinding中,使用相应类方法,可现在< data>标签中导入该类不需要写<vari…>标签,然后在布局中像对待一般方法来调用就行。

例如,先写个没啥用的静态类:

public class UIUtils {public static String showTheDemo(String str) {return str.toString();}}

在< data>中引入该类:

<import type="com.example.dbjavatest.UIUtils" />

然后在对应控件里调用:

<TextViewandroid:id="@+id/tv_data"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="26sp"android:textColor="@color/purple_200"android:text="@{UIUtils.showTheDemo(dataInfoBean.dataInfo)}"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"android:layout_marginLeft="50dp"/>

PS : DataBinding中布局里的控件通过嵌入表达式不仅可以引用对应方法,也可以使用三元运算符等运算符。

七、include和viewStub

DataBinding也支持include的布局文件,一样通过dataBinding来进行数据绑定,一样需要使用< layout>标签和声明需要使用的变量,然后在主布局中将对应的变量传递给include布局,使两个布局共享的数据变量相同。

例如:view_insert.xml中

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><data><import type="com.example.dbjavatest.bean.DataBean"/><variablename="dataInfoBean"type="DataBean" /></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入数据"android:text="@={dataInfoBean.dataInfo}"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"android:textSize="25sp"android:layout_marginTop="30dp"android:paddingLeft="20dp"/></androidx.constraintlayout.widget.ConstraintLayout>
</layout>

对应主布局则直接include,同时通过bind:变量名来将同一变量传过去。你可能发现这里会报错,在布局头文件声明xmlns:bind=“http://schemas.android.com/apk/res-auto” 即可。对应布局文件为:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:bind="http://schemas.android.com/apk/res-auto"><data><import type="com.example.dbjavatest.bean.DataBean"/><variablename="dataInfoBean"type="DataBean" /></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/tv_data"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="26sp"android:textColor="@color/purple_200"android:text="@{dataInfoBean.dataInfo}"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"android:layout_marginLeft="50dp"/><includelayout="@layout/view_insert"app:layout_constraintTop_toBottomOf="@+id/tv_data"bind:dataInfoBean = "@{dataInfoBean}"/></androidx.constraintlayout.widget.ConstraintLayout>
</layout>

ViewStub绑定变量和将变量传递给ViewStub的方式与此一致。例如:

<ViewStubandroid:id="@+id/view_stub"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout="@layout/view_insert"bind:dataInfoBean="@{dataInfoBean}" />

当然,ViewStub 文件一样要使用 layout 等标签进行布局。相应的在Activity中也是通过ViewBinding获取对象实例:

View viewStub = viewDataBinding.viewStub.getViewStub().inflate();

通过此实例,可以控制viewStub的可见性。如果在xml中,没用使用bind:dataInfoBean=“@{dataInfoBean}”,但又想对ViewStub进行数据绑定。则可以在ViewStub 设置 setOnInflateListener回调函数时进行数据绑定,如下:

viewDataBinding.viewStub.setOnInflateListener(new ViewStub.OnInflateListener() {@Overridepublic void onInflate(ViewStub stub, View inflated) {ViewDataBinding viewStubBinding = DataBindingUtil.bind(inflated);viewStubBinding.setDataInfoBean(dataBean);}
});

对DataBinding的数据绑定就介绍到这里了,如果后续发现有遗漏的要点,会即使补充。另外,如果看这篇文字有点吃力,说明你对DataBinding的基础操作还不熟悉,请翻阅我的上一片文章。

这篇关于UI自动刷新大法:DataBinding数据绑定的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/703778

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

烟火目标检测数据集 7800张 烟火检测 带标注 voc yolo

一个包含7800张带标注图像的数据集,专门用于烟火目标检测,是一个非常有价值的资源,尤其对于那些致力于公共安全、事件管理和烟花表演监控等领域的人士而言。下面是对此数据集的一个详细介绍: 数据集名称:烟火目标检测数据集 数据集规模: 图片数量:7800张类别:主要包含烟火类目标,可能还包括其他相关类别,如烟火发射装置、背景等。格式:图像文件通常为JPEG或PNG格式;标注文件可能为X

pandas数据过滤

Pandas 数据过滤方法 Pandas 提供了多种方法来过滤数据,可以根据不同的条件进行筛选。以下是一些常见的 Pandas 数据过滤方法,结合实例进行讲解,希望能帮你快速理解。 1. 基于条件筛选行 可以使用布尔索引来根据条件过滤行。 import pandas as pd# 创建示例数据data = {'Name': ['Alice', 'Bob', 'Charlie', 'Dav