【Android】碎片—动态添加、创建Fragment生命周期、通信
简单用法
在一个活动中添加两个碎片,并让这两个碎片平分活动空间
先新建一个左侧碎片布局和一个右侧碎片布局
左侧碎片
<?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="vertical"><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="Button"/></LinearLayout>
右侧碎片
<?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="vertical"android:background="#00ff00"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:textSize="20sp"android:text="这是文本"/></LinearLayout>
然后新建一个LeftFragment类和一个RightFragment类继承Fragment
package com.example.fragmentpractice;import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;public class LeftFragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view = inflater.inflate(R.layout.left_fragment, container, false);return view;}
}
package com.example.fragmentpractice;import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;public class RightFragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view = inflater.inflate(R.layout.right_fragment, container, false);return view;}
}
修改activity_main
<?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="horizontal"><fragmentandroid:id="@+id/left_fragment"android:name="com.example.fragmentpractice.LeftFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"/><fragmentandroid:id="@+id/right_fragmgent"android:name="com.example.fragmentpractice.RightFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1" /></LinearLayout>
使用了<fragment>添加碎片,需要用android:name
属性来显示指明要添加的碎片类名
动态添加碎片
步骤
- 创建待添加的碎片实例
- 获取FragmentManager,在活动中可直接通过调用getSupportFragmentManager()方法得到
- 开启一个事务,通过调用beginTransaction()方法开启
- 向容器内添加或替换碎片,一般使用replace()方法实现,需要传入容器的id和待添加的碎片实例
- 提交事务,调用commit()方法来完成
代码
新建another_rigth_fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:background="#ffff00"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:textSize="20sp"android:text="这是另一个文本"/></LinearLayout>
创建AnotherRightFragment(和之前的操作一样)
package com.example.fragmentpractice;import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;public class AnotherRightFragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view = inflater.inflate(R.layout.another_right_fragment, container, false);return view;}
}
修改activity_main代码
<?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="horizontal"><fragmentandroid:id="@+id/left_fragment"android:name="com.example.fragmentpractice.LeftFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"/><FrameLayoutandroid:id="@+id/right_layout"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"></FrameLayout></LinearLayout>
修改MainActivity中的代码
package com.example.fragmentpractice;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;// 主活动类,继承自 AppCompatActivity,并实现 View.OnClickListener 接口
public class MainActivity extends AppCompatActivity implements View.OnClickListener {// 活动创建时调用@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 启用 Edge-to-Edge 模式EdgeToEdge.enable(this);// 设置活动的布局setContentView(R.layout.activity_main);// 找到布局中的按钮Button button = (Button) findViewById(R.id.button);// 为按钮设置点击监听器button.setOnClickListener(this);// 初始化时替换碎片replaceFragment(new RightFragment());}// 点击事件处理@Overridepublic void onClick(View v) {if (v.getId() == R.id.button) {// 当按钮被点击时,替换碎片replaceFragment(new AnotherRightFragment());}}// 替换碎片的方法private void replaceFragment(Fragment fragment) {// 获取 FragmentManagerFragmentManager fragmentManager = getSupportFragmentManager();// 开始一个新的事务FragmentTransaction transaction = fragmentManager.beginTransaction();// 替换指定布局中的碎片transaction.replace(R.id.right_layout, fragment);// 提交事务transaction.commit();}
}
在碎片中模拟返回栈
在上面的例子中,点击按钮后返回会直接退出,如果想让他返回到上一个界面得模仿类似于栈的效果
只需要给MainActivity中的replaceFragment中添加:
transaction.replace(R.id.right_layout, fragment);
就行了。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);Button button = (Button) findViewById(R.id.button);button.setOnClickListener(this);replaceFragment(new RightFragment());}@Overridepublic void onClick(View v) {if (v.getId() == R.id.button) {replaceFragment(new AnotherRightFragment());}}private void replaceFragment(Fragment fragment) {FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.right_layout, fragment);transaction.addToBackStack(null);transaction.commit();}
}
碎片与活动之间的通信
FragmentManager提供了一个类似于findViewById()的方法,用于从布局文件中获取碎片的实例:
RightFragment rightFragment = (RightFragment) getSupportFragmentManager().findFragmentById(R.id.right_layout);
碎片的生命周期
onAttach():
- 用法:当 Fragment 与 Activity 关联时调用。
- 常用操作:初始化需要与 Activity 交互的组件或回调,确保 Fragment 与其宿主 Activity 之间的通信。
onCreate():
- 用法:Fragment 被创建时调用。
- 常用操作:初始化不与 UI 相关的资源,如创建或恢复数据、启动后台线程等。
onCreateView():
- 用法:为 Fragment 创建视图层次结构时调用。
- 常用操作:通过
LayoutInflater
填充 Fragment 的布局,初始化与视图相关的资源。
onActivityCreated():
- 用法:确保与 Activity 相关的工作已经完成时调用。
- 常用操作:在 Activity 的
onCreate()
方法执行完成后调用,可以在这里与 Activity 交互。
onStart():
- 用法:Fragment 可见时调用。
- 常用操作:注册任何需要在 Fragment 可见时工作的广播接收器或其他组件。
onResume():
- 用法:Fragment 准备与用户交互时调用。
- 常用操作:恢复暂停的 UI 更新或交互。
onPause():
- 用法:Fragment 不再与用户交互时调用。
- 常用操作:暂停与 UI 相关的操作,保存重要数据或状态。
onStop():
- 用法:Fragment 不再可见时调用。
- 常用操作:停止耗时的操作,如动画或播放视频,注销在
onStart()
中注册的广播接收器。
onDestroyView():
- 用法:销毁 Fragment 的视图层次结构时调用。
- 常用操作:清理与视图相关的资源,避免内存泄漏。
onDestroy():
- 用法:销毁 Fragment 时调用。
- 常用操作:清理所有资源,包括后台线程、数据和其他持有的资源。
onDetach():
- 用法:Fragment 与 Activity 解除关联时调用。
- 常用操作:清理与 Activity 相关的资源或回调,确保 Fragment 可以正确地与新的 Activity 关联。
动态加载布局
使用限定符
修改activity_main文件
<?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="horizontal"><fragmentandroid:id="@+id/left_fragment"android:name="com.example.fragmentpractice.LeftFragment"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>
只留下一个左侧碎片
在res目录下新建layout-large文件夹,在这个文件夹下新建一个布局,也叫做activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><fragmentandroid:id="@+id/left_fragment"android:name="com.example.fragmentpractice.LeftFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"/><fragmentandroid:id="@+id/right_fragment"android:name="com.example.fragmentpractice.RightFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="3"/></LinearLayout>
添加方法如下:
使用最小宽度限定符
在res目录下新建layout-sw600dp文件夹,新建activity_main布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><fragmentandroid:id="@+id/left_fragment"android:name="com.example.fragmentpractice.LeftFragm25ent"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"/><fragmentandroid:id="@+id/right_fragment"android:name="com.example.fragmentpractice.RightFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="3"/>
</LinearLayout>
当程序运行在屏幕宽度大于等于600dp的设备上,会加载layout-sw600dp/activity_main布局,小于600dp加载默认的layout/activity_main布局
创建Fragment的生命周期
静态创建
- Fragment Constructor、onInflate、onCreate
- Fragment Constructor
- 当Fragment实例化时,调用其构造函数。此时可以进行一些初始设置,但不应涉及视图创建或其他可能耗时的操作。
- onInflate
- 当Fragment需要从布局文件中加载视图时调用。此时可以进行视图的初步配置。该方法在Fragment被附加到Activity之前调用。
- onCreate
- Fragment在创建时调用。此时可以进行非视图相关的初始化工作,比如初始化变量、设置配置等。
- Activity onCreate
- 当Activity首次创建时调用。在这个方法中,通常会进行视图的初始化、设置事件监听器、初始化数据等操作。这是Activity生命周期中非常重要的一个方法。
动态创建
- Activity onCreate
- 同静态创建中描述的一样,Activity在首次创建时调用
onCreate
方法。动态创建Fragment的步骤一般在这里进行,比如通过FragmentManager添加、替换Fragment。
- Fragment Constructor、onCreate
- Fragment Constructor
- 与静态创建类似,动态创建时Fragment实例化时也会调用构造函数进行初始设置。
- onCreate
- Fragment在创建时调用。动态创建时,可以在这里进行Fragment的初始化工作,比如从Activity传递过来的数据进行处理。与静态创建不同的是,这里通常会涉及到从Activity获取数据或传递数据给Activity。
工具
Fragment Transaction
Fragment Transaction是管理和操作Fragments的关键工具。
常用方法
-
add():添加一个Fragment到Activity中。
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.fragment_container, new ExampleFragment()); transaction.commit();
-
replace():替换当前的Fragment。
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container, new ExampleFragment()); transaction.addToBackStack(null); // 可选,将事务添加到返回栈 transaction.commit();
-
remove():从Activity中移除一个Fragment。
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container); if (fragment != null) {FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();transaction.remove(fragment);transaction.commit(); }
-
hide():隐藏一个Fragment。
-
show():显示一个隐藏的Fragment。
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.hide(existingFragment); transaction.show(newFragment); transaction.commit();
-
attach():重新附加一个Fragment到UI。
-
detach():从UI中分离一个Fragment。
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.detach(existingFragment); transaction.attach(existingFragment); transaction.commit();
-
addToBackStack():将事务添加到返回栈中,以便用户可以按返回键撤销该事务。
-
commit():提交事务。
// 获取FragmentManager
FragmentManager fragmentManager = getSupportFragmentManager();// 开始一个事务
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();// 创建一个新的Fragment实例
Fragment fragment = new ExampleFragment();// 添加Fragment到容器
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.addToBackStack(null); // 可选,将事务添加到返回栈
fragmentTransaction.commit(); // 提交事务
Fragment Manager
常用方法
-
findFragmentById(int id):通过Fragment的容器视图ID来查找Fragment。
FragmentManager fragmentManager = getSupportFragmentManager(); Fragment fragment = fragmentManager.findFragmentById(R.id.fragment_container);if (fragment != null) {// 找到的Fragment实例 }
-
findFragmentByTag(String tag):通过Fragment的标签(tag)来查找Fragment。
FragmentManager fragmentManager = getSupportFragmentManager(); Fragment fragment = fragmentManager.findFragmentById(R.id.fragment_container);if (fragment != null) {// 找到的Fragment实例 }
-
getFragments():获取当前
FragmentManager
中所有的Fragment(API Level 26及以上可用)。FragmentManager fragmentManager = getSupportFragmentManager(); List<Fragment> fragments = fragmentManager.getFragments();for (Fragment fragment : fragments) {// 处理每个Fragment实例 }
增删查替
Fragment的增删查替是通过FragmentManager
和FragmentTransaction
来实现的
增加
添加一个Fragment到Activity中
-
获取FragmentManager:
FragmentManager fragmentManager = getSupportFragmentManager();
-
开启一个事务:
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
-
添加Fragment:
MyFragment myFragment = new MyFragment(); fragmentTransaction.add(R.id.fragment_container, myFragment);
-
提交事务:
fragmentTransaction.commit();
删除
从Activity中移除一个Fragment
-
获取FragmentManager:
FragmentManager fragmentManager = getSupportFragmentManager();
-
找到要移除的Fragment:
MyFragment myFragment = (MyFragment) fragmentManager.findFragmentById(R.id.fragment_container);
-
开启一个事务:
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
-
移除Fragment:
if (myFragment != null) {fragmentTransaction.remove(myFragment); }
-
提交事务:
fragmentTransaction.commit();
查找
根据ID或标签查找Fragment
-
获取FragmentManager:
FragmentManager fragmentManager = getSupportFragmentManager();
-
根据ID查找:
MyFragment myFragment = (MyFragment) fragmentManager.findFragmentById(R.id.fragment_container);
-
根据标签查找:
MyFragment myFragment = (MyFragment) fragmentManager.findFragmentByTag("MY_FRAGMENT_TAG");
替换
替换Activity中的一个Fragment
-
获取FragmentManager:
FragmentManager fragmentManager = getSupportFragmentManager();
-
开启一个事务:
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
-
替换Fragment:
MyNewFragment newFragment = new MyNewFragment(); fragmentTransaction.replace(R.id.fragment_container, newFragment);
-
提交事务:
fragmentTransaction.commit();
Fragment与Activity之间的通信
Activity向Fragment
-
在Activity中设置数据:
使用Fragment的
setArguments
方法来传递数据。在创建Fragment实例时,可以通过Bundle
将数据传递给Fragment。
// 在Activity中
Bundle bundle = new Bundle();
bundle.putString("key", "value");MyFragment myFragment = new MyFragment();
myFragment.setArguments(bundle);getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, myFragment).commit();
-
在Fragment中接收数据:
在Fragment的
onCreate
方法中获取传递过来的数据。
// 在Fragment中
@Override
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (getArguments() != null) {String value = getArguments().getString("key");// 使用获取到的数据}
}
Fragment向Activity
-
定义一个接口:
在Fragment中定义一个接口,Activity实现该接口来接收数据。
// 在Fragment中定义接口
public interface OnFragmentInteractionListener {void onFragmentInteraction(String data);
}private OnFragmentInteractionListener mListener;@Override
public void onAttach(Context context) {super.onAttach(context);if (context instanceof OnFragmentInteractionListener) {mListener = (OnFragmentInteractionListener) context;} else {throw new RuntimeException(context.toString()+ " must implement OnFragmentInteractionListener");}
}// 使用接口传递数据
public void sendDataToActivity(String data) {if (mListener != null) {mListener.onFragmentInteraction(data);}
}
-
在Activity中实现接口:
实现Fragment定义的接口,在接口方法中处理接收到的数据。
// 在Activity中实现接口
public class MyActivity extends AppCompatActivity implements MyFragment.OnFragmentInteractionListener {@Overridepublic void onFragmentInteraction(String data) {// 处理从Fragment接收到的数据}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);MyFragment myFragment = new MyFragment();getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, myFragment).commit();}
}
Fragment之间的数据传递
Fragment之间的通信可以通过它们共同的Activity来实现。一个Fragment将数据传递给Activity,然后Activity将数据传递给另一个Fragment。
1.Fragment A 向 Activity 传递数据
使用上面描述的Fragment向Activity传递数据的方法。
2.Activity 接收数据并传递给 Fragment B
在Activity中接收数据:
@Override
public void onFragmentInteraction(String data) {FragmentB fragmentB = (FragmentB) getSupportFragmentManager().findFragmentById(R.id.fragment_b_container);if (fragmentB != null) {fragmentB.updateData(data);}
}
在Fragment B中定义方法来接收数据:
// 在Fragment B中
public void updateData(String data) {// 更新Fragment B中的数据
}
已经到底啦!
相关文章:
【Android】碎片—动态添加、创建Fragment生命周期、通信
简单用法 在一个活动中添加两个碎片,并让这两个碎片平分活动空间 先新建一个左侧碎片布局和一个右侧碎片布局 左侧碎片 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/…...
前端 SSE 长连接
使用 const options {withCredentials: true, // 默认 false}const eventSource new EventSource(/api, options);eventSource.addEventListener(open, () > {});eventSource.onmessage (event) > {}; // 或addEventListener(message,callback)eventSource.addEvent…...
.mp4格式的视频为何不能通过video标签在chrome浏览器中播放?
chrome浏览器目前只支持编解码格式为H264格式的视频,如果某个.mp4后缀的视频不能在chrome浏览器中播放,多半是这个视频的编码格式不是H264的! 1、可以通过ffmpeg工具查看当前视频的编码格式: ffprobe -v error -select_streams v…...
Python酷库之旅-第三方库Pandas(051)
目录 一、用法精讲 186、pandas.Series.is_monotonic_increasing属性 186-1、语法 186-2、参数 186-3、功能 186-4、返回值 186-5、说明 186-6、用法 186-6-1、数据准备 186-6-2、代码示例 186-6-3、结果输出 187、pandas.Series.is_monotonic_decreasing属性 187…...
linux timestamp
驱动或应用中获取时间戳的接口。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <sys/time.h> #if 0 #include <linux/ktime.h> /* 内核驱动中获取时间戳 */ static ktime_t get_kernel_time…...
Vue.js 搭建大屏可视化项目
引言 在数字化转型的时代背景下,大屏可视化项目因其直观的数据展示和实时的业务监控能力而变得日益重要。Vue.js,以其简洁的语法、高效的虚拟DOM和强大的组件化能力,成为了构建大屏可视化应用的首选框架之一。本文将从零开始,引导…...
Linux:进程信号(二.信号的保存与处理、递达、volatile关键字、SIGCHLD信号)
上次介绍了:(Linux:进程信号(一.认识信号、信号的产生及深层理解、Term与Core))[https://blog.csdn.net/qq_74415153/article/details/140624810] 文章目录 1.信号保存1.1递达、未决、阻塞等概念1.2再次理解信号产生与保存1.3信号…...
最值得推荐的5个AI大模型API
在这个以人工智能为主导的新时代,选择一个卓越的AI模型API接口,对于企业和个人在AI驱动的商业和技术革新中取得成功至关重要。 在人工智能的浪潮中,大型AI模型API接口正成为推动技术创新和业务发展的重要力量。随着2024年技术的持续进步和应用…...
PyTest+Allure生成测试报告
一、官网文档(权威) 1. Allure Report 官网:Allure Report Docs — Introduction 2. Allure GitHub地址:GitHub - allure-framework/allure2: Allure Report is a flexible, lightweight multi-language test reporting tool. It …...
ROS2教程(10) - 编写接收程序、添加frame - Linux
注意 : 本篇文章接上节 (点击此处跳转到上节) 编写接收程序 cpp <the_work_ws>/src/learning_tf2_cpp/src/turtle_tf2_listener.cpp #include <chrono> #include <functional> #include <memory> #include <string>#include "geometry_…...
Arraylist与LinkedList的区别
Arraylist 概念 Arraylist非线程安全Arraylist 底层使用的是Object数组ArrayList 采用数组存储,插入和删除元素的时间复杂度受元素位置的影响ArrayList 支持快速随机访问,就是通过元素的序号快速获取元素对象ArrayList的空间浪费主要体现在列表的结尾会预留一定的容…...
Nestjs使用Redis的最佳实践
前几天在项目中有用到Redis JWT实现服务端对token的主动删除(退出登录功能)。故此介绍下如何在Nestjs中使用Redis,并做下总结。 知识准备 了解Redis - 网上很多简介。了解Nestjs如何使用jwt生成token - 可移步看下我之前的文章 效果展示 一、mac安装与使用 示…...
Cadence23学习笔记(十四)
ARC就是圆弧走线的意思: 仅打开网络的话可以只针对net进行修改走线的属性: 然后现在鼠标左键点那个走线,那个走线就会变为弧形: 添加差分对: 之后,分别点击两条线即可分配差分对: 选完差分对之后…...
socket 编程
1. socket 套接字 Socket 是一个用于网络通信的技术。Socket 通信允许客户端——服务器之间进行双向通信。它可以使任何客户端机器连接到任何服务器,安装在客户端和服务器两侧的程序就可以实现双向的通信。Socket的作用就是把连接两个计算机的通信软件“中间接”起来…...
如何使用 HTTPie 进行高效的 HTTP 请求
如何使用 HTTPie 进行高效的 HTTP 请求 引言 HTTPie 是一个命令行 HTTP 客户端,它以其简洁的语法和人性化的输出格式赢得了广大开发者的喜爱。与 curl 相比,HTTPie 提供了更加直观和用户友好的接口,使得执行 HTTP 请求变得轻松愉快。本文将…...
Lingo求解器百度云下载 ling 8.0/lingo 18安装包资源分享
如大家所熟悉的,Lingo是Linear Interaction and General Optimizer的缩写,中文名称为“交互式线性和通用优化求解器”,是一套专门用于求解最优化问题的软件包。 在大部分人认知里,Lingo可用于求解线性规划、二次规划、整数规划、…...
文献综述如何为研究的理论框架做出贡献
VersaBot一键生成文献综述 文献综述在几个关键方面对塑造和巩固研究的理论框架起着至关重要的作用; 1. 识别相关理论和概念: 通过对现有研究的探索,您将遇到与您的主题相关的突出理论和概念。这些可以作为您自己的理论框架的构建块。 2. 理…...
FastAPI(七十九)实战开发《在线课程学习系统》接口开发-- 加入课程和退出课程
源码见:"fastapi_study_road-learning_system_online_courses: fastapi框架实战之--在线课程学习系统" 加入课程 我们先看下加入课程 1.是否登录 2.课程是否存在 3.是否已经存在 4.添加 首先实现逻辑 def get_student_course(db: Session, course: int…...
【赛事推荐】2024中国高校计算机大赛人工智能创意赛
“中国高校计算机大赛”(China Collegiate Computing Contest,简称C4)是面向全国高校各专业在校学生的科技类竞赛活动,于2016年由教育部高等学校计算机类专业教学指导委员会、教育部高等学校大学软件工程专业教学指导委员会、教育…...
C++沉思:预处理和编译
预处理和编译 条件编译源代码使用方式典型示例原理 使用static_assert执行编译时断言检查使用方式原理 在C中,编译是将源代码转换为机器代码并组织在目标文件中,然后将目标文件链接在一起生成可执行文件的过程。编译器实际上一次只处理一个文件ÿ…...
交通数据处理-计算途径某些路段的车辆数
根据车辆的运行轨迹,计算先经过某些路段,再经过某些路段的车辆数。 欢迎关注本人公众号--交通数据探索师 如下表, 其中:vehicle: 车辆编号;route: 车辆轨迹。 以第一行为例,车辆car1按顺序经过了路段123…...
从0到1入门系列 | 崖山公开课再加码,三小时带你入门崖山数据库!
对不断更新的技术心生迷茫 不知如何正确的提升自己? 对新兴的国产数据库领域充满好奇 却不知从何入手? 崖山专家团队精心筹备 《从0到1入门》系列直播课 6节课 三小时 助力数据库小白变身技术高手 掌握最前沿的数据库技术 现在开始 开启职场“金…...
Powershell自定义带参数的别名
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、函数二、使用步骤总结 前言 之前写了一篇文章定义别名让powershell尽可能接近Unix风格,增强两者的互操作性,今天给出方法可以定义带…...
文件操作相关的精讲
目录: 思维导图 一. 文件定义 二. 文件的打开和关闭 三. 文件的顺序读写操作 四. 文件的随机读写操作 五. 文本文件和二进制文件 六. 文件读取结束的判断 七.文件缓冲区 思维导图: 一. 文件定义 1.文件定义 C语言中,文件是指一组相…...
05 循环神经网络
目录 1. 基本概念 2. 简单循环网络 2.1 简单循环网络 2.2 长程依赖问题 3. 循环神经网络的模式与参数学习 3.1 循环神经网络的模式 3.2 参数学习 4. 基于门控的循环神经网络 4.1 长短期记忆网络 4.2 LSTM网络的变体网络 4.3 门控循环单元网络 5. 深层循环神经网络…...
C#初级——条件判断语句、循环语句和运算符
条件判断语句 简单的条件判断语句,if()里面进行条件判断,如果条件判断正确就执行语句块1,如果不符合就执行语句块2。 if (条件判断) { 语句块1 } else { 语句块2 } int age 18;if (age < 18){Console.WriteLine("未…...
Laravel路由模型绑定:简化依赖注入的艺术
Laravel路由模型绑定:简化依赖注入的艺术 引言 在现代Web应用开发中,Laravel框架以其优雅和简洁的代码而闻名。Laravel的路由模型绑定(Route Model Binding)是框架提供的一项强大功能,它允许开发者在路由处理中自动注…...
【vue前端项目实战案例】之Vue仿饿了么App
本文将介绍一款仿“饿了么”商家页面的App。该案例是基于 Vue2.0 Vue Router webpack ES6 等技术栈实现的一款外卖类App,适合初学者进行学习。 项目源码下载链接在文章末尾 1 项目概述 该项目是一款仿“饿了么”商家页面的外卖类App,主要有以下功能…...
冷热分离——Java全栈知识(36)
之前在面试的时候有老师问: 我看你使用了水平分表,但是如果有些 1%的数据占了访问量的 90%,而剩下 99%的数据只占了访问量的 10%。这种情况怎么处理。 1 、冷热分离 1.1、什么是冷热分离 冷热分离指的是在处理数据时将数据库分为冷库和热库…...
了解Selenium中的WebElement
Selenium中到处都使用WebElement来执行各种操作。什么是WebElement?这篇文章将详细讨论WebElement。 Selenium中的WebElement是一个表示网站HTML元素的Java接口。HTML元素包含一个开始标记和一个结束标记,内容位于这两个标记之间。 HTML元素的重命名 …...
OpenCV facedetect 人脸检测官方示例项目配置
运行程序。该程序会自动打开摄像头,识别并定位摄像头前的人脸以及眼睛部位。 输入q或者Q,退出程序。 或进行文本中所包含的图片路径 或 单个图片进行检测,自行修改代码即可 配置环境项目,debug 解决error C4996: ‘fopen’: This…...
自定义Laravel Artisan风格:打造个性化命令行体验
自定义Laravel Artisan风格:打造个性化命令行体验 引言 Laravel的Artisan命令行工具是开发过程中不可或缺的一部分,它提供了一个强大的接口来执行各种开发、维护、测试等任务。除了执行命令,Artisan还允许开发者自定义命令行输出的风格&…...
CTF之网站被黑
简单看一下网页和源码没发现什么明显漏洞 那就扫描一下目录 发现了/shell.php文件,访问一下,发现是一个后台管理登录页面 别无他法只能爆破喽,爆破后发现密码是hack flag{25891d9e9d377f006eda3ca7d4c34c4d}...
Electron学习笔记(一)基础环境
目录 前言 基础环境准备 安装 Node.js 配置项目文件 通过代理服务安装 通过国内仓库安装 一些常见问题: 前言 一个新手学习Electron的笔记,记录为主,仅供参考。 其他文章见专栏目录。 基础环境准备 开发之前先将基础环境搭建好。 …...
【C语言】栈的实现(数据结构)
前言: 还是举一个生活中的例子,大家都玩过积木,当我们把积木叠起来的时候,如果要拿到最底部的积木,我们必须从顶端一个一个打出,最后才能拿到底部的积木,也就是后进先出(先进后出&a…...
前端三大主流框架对比
在现代前端开发中,React、Vue和Angular是三大流行的框架/库。它们各自有独特的优缺点,适用于不同的开发需求和项目规模。下面是对这三者的详细比较: 一、 React 简介: 由Facebook开发和维护,是一个用于构建用户界面…...
AOP~面向切面编程介绍
AOP基础 概述 AOP:Aspect Oriented Programming(面向切面编程、面向方面编程),面向特定方法的编程。 动态代理是面向切面编程最主流的实现。 SpringAOP是Spring框架的高级技术,旨在管理bean对象的过程中,…...
Android SurfaceFlinger——GraphicBuffer的提交(三十三)
在 SurfaceFlinger 中,我们 dequeueBuffer 和 queueBuffer 是 Surface 控制接口中非常重要的两个函数,分别用于从 Surface 的 BufferQueue 中取出缓冲区和向 BufferQueue 提交(队列)缓冲区。这两个函数在生产者和消费者模型中扮演着核心角色,确保了图像数据的高效和有序传…...
创维汽车滁州永通体验中心开业仪式暨超充车型区域上市会圆满成功
2024年7月20日,创维汽车滁州永通体验中心盛大开业,当日,创维汽车市场部经理周世鹏、安徽大区总监王大明等领导参加本次开业盛典,共同见证创维汽车滁州永通体验中心成功落地。 2021年,新能源乘用车高速发展,…...
【PHP】系统的登录和注册
一、为什么要学习系统的登录和注册 系统的登录和注册可能存在多种漏洞,这些漏洞可能被恶意攻击者利用,从而对用户的安全和隐私构成威胁。通过学习系统的登录和注册理解整个登录和注册的逻辑方便后续更好站在开发的角度思考问题发现漏洞。以下是一些常见…...
2024.7.29 刷题总结
2024.7.29 **每日一题** 682.棒球比赛,这道题是一道简单的模拟题,用栈模拟题中的四个操作就可以了,操作一是将x加到列表末尾,操作二是将列表的后两项之和加到列表末尾,操作三是把列表最后一项的两倍加到列表末尾&#…...
WebSocket程序设计
协议说明 WebSocket 是一种在单个TCP连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。Websocket主要用在B/S架构的应用程序中,在 WebSocket API 中,浏览器和服务器只…...
ES(ElasticSearch)倒排索引
目录 正排与倒排索引 1.正排索引 作用: 优点: 缺点: 2.倒排索引 原理: 倒排索引的构建流程: 倒排索引的搜索流程: 优点: 缺点: 3. 应用场景 倒排索引中有几个非常重要的概念…...
Android Studio Build窗口出现中文乱码问题
刚安装成功的android studio软件打开工程,编译时下方build窗口中中文是乱码。 解决: 可点击studio状态栏的Help—>Edit Custom VM Options ,在打开的studio64.exe.vmoptions文件后面添加:(要注意不能有空格,否则st…...
java生成随机数
代码 startValue 开始值 endValue 结束值 per生成的位数也就是精度 /*** 随机数的生成* param startValue* param endValue* return*/private BigDecimal randomBigDecimal(String startValue, String endValue,int per) {BigDecimal min new BigDecimal(startValue);BigDeci…...
动态定制深度学习:Mojo模型与自定义训练算法的无缝切换
动态定制深度学习:Mojo模型与自定义训练算法的无缝切换 引言 在机器学习领域,算法的选择对模型的性能有着决定性的影响。随着研究的深入和技术的发展,开发者可能需要根据不同的数据特性和业务需求,动态地切换或自定义训练算法。…...
昇思25天学习打卡营第19天|DCGAN生成漫画头像
DCGAN生成漫画头像总结 实验概述 本实验旨在利用深度卷积生成对抗网络(DCGAN)生成动漫头像,通过设置网络、优化器以及损失函数,使用MindSpore进行实现。 实验目的 学习和掌握DCGAN的基本原理和应用。熟悉使用MindSpore进行图像…...
排序题目:按照频率将数组升序排序
文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题:按照频率将数组升序排序 出处:1636. 按照频率将数组升序排序 难度 3 级 题目描述 要求 给定一个整数数组 nums \texttt{nums} nums&a…...
实分析与测度论问题的分类
实分析主要研究实数、实数序列、实数极限以及实值函数的分析,而度量空间则是一个具有距离函数的集合,其分类可以从多个角度进行。 实分析 实分析主要关注实数、实数序列、实数极限以及实值函数的分析。它涉及到多个重要的概念和理论,包括但…...
动态代理更改Java方法的返回参数(可用于优化feign调用后R对象的统一处理)
动态代理更改Java方法的返回参数(可用于优化feign调用后R对象的统一处理) 需求原始解决方案优化后方案1.首先创建AfterInterface.java2.创建InvocationHandler处理代理方法3. 调用 实际运行场景拓展 需求 某些场景,调用别人的方法࿰…...