文章目录

  • 【Android】用 ViewPager2 + Fragment + TabLayout 实现标签页切换
    • 一、引入:什么是 ViewPager2 ?
    • 二、ViewPager2 的基础使用
      • 1. 在布局文件 (activity_main.xml)中添加 ViewPager2
      • 2. 制作一个 Fragment
        • 2.1 创建一个布局文件
        • 2.2 创建一个 Fragment 类绑定这个布局
      • 3. 创建适配器 (MyAdapter.java)
      • 4. 在活动中使用
    • 三、ViewPager2 + Fragment + TabLayout
      • 1. 在布局文件 (activity_main.xml)中添加 ViewPager2 和 TabLayout
      • 2. 使用 TabLayoutMediator 将两者关联
      • 3. ViewPager2 的页面切换监听
      • 4. 动态添加标签
      • 5. 标签选择监听
      • 6. 禁用 ViewPager2 左右滑动翻页
      • 7. 效果展示

【Android】用 ViewPager2 + Fragment + TabLayout 实现标签页切换

一、引入:什么是 ViewPager2 ?

在我们日常使用的应用中,常常会遇到可以左右滑动切换内容的界面,比如知乎首页的推荐/热榜/关注标签页、微博的频道分类、相册中的多图浏览,甚至首次打开 App 时的欢迎引导页。这类界面背后的滑动切换机制,通常就是通过 Android 提供的 ViewPager 或其升级版 ViewPager2 实现的。ViewPager2 是 Android 提供的现代化分页滑动组件,支持横向与纵向滑动,具备高效的页面管理能力,是实现多页切换、Tab 联动与内容滑动浏览等功能的首选方案。

:ViewPager2 已全面替代 ViewPager,是官方推荐的新项目默认使用的分页滑动组件。

概述:ViewPager2 是基于 RecyclerView 实现的页面切换控件,继承了其高效的视图复用机制和灵活布局能力,支持水平与垂直滑动,通过设置 offscreenPageLimit 控制缓存策略,提供更高性能和更低内存开销。使用 FragmentStateAdapter 或 RecyclerView.Adapter 作为适配器,适配灵活,支持页面生命周期自动管理,同时还支持 PageTransformer 实现炫酷的切换动画,是替代旧版 ViewPager 的推荐方案。

二、ViewPager2 的基础使用

使用前先添加依赖 (build.gradle):

dependencies {// ...implementation 'androidx.viewpager2:viewpager2:1.1.0'implementation 'com.google.android.material:material:1.12.0'
}

注: 检查并使用最新稳定版本号(ViewPager2|Google 的 Maven 存储库)

1. 在布局文件 (activity_main.xml)中添加 ViewPager2

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

2. 制作一个 Fragment

2.1 创建一个布局文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#19CFBE"><TextViewandroid:id="@+id/textview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="泥嚎"android:layout_gravity="center"android:textSize="45sp"/></FrameLayout>
2.2 创建一个 Fragment 类绑定这个布局
public class HomeFragment extends Fragment {private FragmentBinding binding;@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {binding = FragmentBinding.inflate(inflater, container, false);return binding.getRoot();}public void onDestroyView() {super.onDestroyView();binding = null;}
}

3. 创建适配器 (MyAdapter.java)

public class MyAdapter extends FragmentStateAdapter {private final List<Fragment> fragmentList;public MyAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> fragmentList) {super(fragmentActivity);this.fragmentList = fragmentList;}@NonNull@Overridepublic Fragment createFragment(int position) {// 用于返回指定的fragment界面return fragmentList.get(position);}@Overridepublic int getItemCount() {// 用于加载容器大小return fragmentList != null ? fragmentList.size() : 0;}
}

自定义 Adapter 并继承 FragmentStateAdapter

ViewPager2 的两种适配器类型

RecyclerView.Adapter

  • 这是一个基础类,需要你自己创建 ViewHolder、绑定 View。
  • 适合每个页面是简单的布局 View,不需要 Fragment。
  • 可以直接继承 RecyclerView.Adapter<MyViewHolder> 来实现。
  • 优点:轻量,适合纯视图页面,不用管理 Fragment 复杂生命周期。
  • 缺点:没有 Fragment 的独立生命周期,不能使用 Fragment 特性。

FragmentStateAdapter

  • 继承自 RecyclerView.Adapter,但专门为 ViewPager2 管理 Fragment 做了封装。
  • 内部会自动帮你管理 Fragment 的添加、显示、销毁和状态保存。
  • 适合每页是 Fragment 的场景,比如每页一个独立的界面。
  • 需要实现 createFragment(int position) 来返回对应位置的 Fragment 实例。

4. 在活动中使用

        List<Fragment> fragmentList = new ArrayList<>();fragmentList.add(new HomeFragment());fragmentList.add(new HomeFragment());fragmentList.add(new HomeFragment());fragmentList.add(new HomeFragment());fragmentList.add(new HomeFragment());fragmentList.add(new HomeFragment());fragmentList.add(new HomeFragment());fragmentList.add(new HomeFragment());// 设置适配器MyAdapter adapter = new MyAdapter(this, fragmentList);binding.viewPager.setAdapter(adapter);

效果如下:
请添加图片描述

三、ViewPager2 + Fragment + TabLayout

TabLayout 是 Android 中用于实现选项卡导航的控件,常与 ViewPager2 搭配使用,它可以在界面顶部展示一排可切换的标签页,每个标签通常对应一个页面内容(如 Fragment),用户点击或滑动即可在各页面之间切换。

1. 在布局文件 (activity_main.xml)中添加 ViewPager2 和 TabLayout

<?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:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><com.google.android.material.tabs.TabLayoutandroid:id="@+id/tab_layout"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@android:color/transparent"android:elevation="0dp"app:tabMode="scrollable"app:tabIndicatorColor="@color/pink"/><androidx.viewpager2.widget.ViewPager2android:id="@+id/view_pager"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/></LinearLayout>
XML 属性方法取值说明
app:tabModesetTabMode()fixed scrollable标签显示模式:固定宽度/可滚动
app:tabGravitysetTabGravity()center fill标签对齐方式:居中/填充
app:tabContentStartsetPadding()尺寸值 (如 16dp)第一个标签的起始边距
app:tabInlineLabelsetInlineLabel()true false图标与文本是否同行显示
app:tabIndicatorColorsetSelectedTabIndicatorColor()颜色值指示器颜色
app:tabIndicatorHeightsetSelectedTabIndicatorHeight()尺寸值指示器高度
app:tabIndicatorFullWidthsetTabIndicatorFullWidth()true false指示器是否与标签等宽
app:tabIndicatorsetSelectedTabIndicator()Drawable 资源自定义指示器 Drawable
app:tabIndicatorGravitysetTabIndicatorGravity()bottom top center stretch指示器位置:底部/顶部/居中/拉伸
app:tabIndicatorAnimationDuration毫秒值 (如 300)指示器动画时长
app:tabIndicatorAnimationModelinear elastic指示器动画模式:线性/弹性
app:tabTextAppearancesetTabTextAppearance()样式资源 (如 @style/MyTab)文本外观样式
app:tabTextColorsetTabTextColors()ColorStateList文本颜色(支持选择器)
app:tabIconTintsetTabIconTint()ColorStateList图标着色(支持选择器)
app:tabBackgroundsetTabBackground()Drawable 资源标签背景(支持选择器)
app:tabRippleColorsetTabRippleColor()ColorStateList点击波纹效果颜色
app:tabMinWidthsetTabMinWidth()尺寸值标签最小宽度
app:tabMaxWidthsetTabMaxWidth()尺寸值标签最大宽度
app:tabPaddingStartsetTabPadding()尺寸值标签起始内边距

2. 使用 TabLayoutMediator 将两者关联

new TabLayoutMediator(binding.tabLayout, binding.viewPager,new TabLayoutMediator.TabConfigurationStrategy() {@Overridepublic void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {//自定义TabViewTextView tabView = new TextView(MainActivity.this);tabView.setText("Fragment " + position);//将tabbView绑定到tabtab.setCustomView(tabView);}}).attach();

创建一个 TabLayoutMediator 实例,传入三个参数:

  • binding.tabLayout:要联动的 TabLayout。
  • binding.viewPager:要联动的 ViewPager2。
  • TabConfigurationStrategy:回调接口,用于配置每一个 Tab(比如设置标题、图标等)。

onConfigureTab(...)

每个 Tab 初始化时,这个方法都会被调用一次,对应 ViewPager2 的每一页。

tab.setCustomView(tabView);

设置 Tab 的视图,可以完全控制 Tab 的外观,而不再受默认样式限制。也可以用自己写的 layout 文件,比如:

View customTab = LayoutInflater.from(context).inflate(R.layout.my_tab_layout, null);
tab.setCustomView(customTab);

3. ViewPager2 的页面切换监听

binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {@Overridepublic void onPageSelected(int position) {super.onPageSelected(position);// 这里可以处理页面切换时的逻辑}});

这是给 ViewPager2 注册一个 页面变更回调监听器(PageChangeCallback),当用户手动或编程切换页面时,可以在对应的方法中执行你想要的逻辑。

registerOnPageChangeCallback(...)

向 ViewPager2 注册一个页面变化的监听器,类型是 ViewPager2.OnPageChangeCallback,可以监听 当前页面的状态变化(比如选中、滑动、滚动状态变化等)

new ViewPager2.OnPageChangeCallback()

这是创建一个监听器对象,并重写其回调方法。该监听器包含以下常用方法:

  • onPageSelected(int position)
    • 调用时机:页面切换完成后(即滑动结束,页面完全展示出来时)。
    • 适合场景
      • 更新 TabLayout 高亮
      • 改变底部按钮状态
      • 动态加载数据(懒加载)
  • onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
    • 当页面正在滑动中不断回调。
    • 可用于页面间动画联动、Tab 动画跟随效果等。
  • onPageScrollStateChanged(int state)
    • 页面滑动状态变化时回调。
    • state 可能的值:
      • SCROLL_STATE_IDLE(0): 空闲状态,页面滑动停止。
      • SCROLL_STATE_DRAGGING(1): 用户正在滑动。
      • SCROLL_STATE_SETTLING(2): 页面正在自动滑动到最终位置。

4. 动态添加标签

TabLayout tabLayout = findViewById(binding.tabLayout);// 添加文本标签
tabLayout.addTab(tabLayout.newTab().setText("首页"));// 添加图标标签
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_home));// 添加自定义视图标签
TabLayout.Tab tab = tabLayout.newTab();
tab.setCustomView(R.layout.custom_tab_view);
tabLayout.addTab(tab);
类型方法适用场景
文本标签setText("标题")简洁的标题导航
图标标签setIcon(R.drawable.xxx)图标导航栏(常见于底部)
自定义标签setCustomView(R.layout.xxx)图文结合、动画、徽章等复杂样式

5. 标签选择监听

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {@Overridepublic void onTabSelected(TabLayout.Tab tab) {// 标签被选中时触发int position = tab.getPosition();viewPager2.setCurrentItem(position);}@Overridepublic void onTabUnselected(TabLayout.Tab tab) {// 标签取消选中时触发}@Overridepublic void onTabReselected(TabLayout.Tab tab) {// 已选中标签再次点击时触发}
});

6. 禁用 ViewPager2 左右滑动翻页

//false表示禁止,true表示允许
binding.viewPager.setUserInputEnabled(false);

ViewPager2 内部是通过 RecyclerView 实现滑动的。setUserInputEnabled(false) 会禁用一切手势滑动,但不会影响通过 setCurrentItem() 代码设置页面切换。

7. 效果展示

请添加图片描述

代码如下:

public class MainActivity extends AppCompatActivity {private ActivityMainBinding binding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());EdgeToEdge.enable(this);ViewCompat.setOnApplyWindowInsetsListener(binding.getRoot(), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});List<Fragment> fragmentList = List.of(new LiveStreamingFragment(),new RecommendFragment(),new HotFragment(),new AnimationFragment(),new FilmFragment(),new RedFragment());MyAdapter adapter = new MyAdapter(this, fragmentList);binding.viewPager.setAdapter(adapter);new TabLayoutMediator(binding.tabLayout, binding.viewPager,new TabLayoutMediator.TabConfigurationStrategy() {@Overridepublic void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {switch (position) {case 0:tab.setText("直播");break;case 1:tab.setText("推荐");break;case 2:tab.setText("热门");break;case 3:tab.setText("动画");break;case 4:tab.setText("影视");break;case 5:tab.setText("新征程");break;default:tab.setText("未知");break;}}}).attach();binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {@Overridepublic void onPageSelected(int position) {super.onPageSelected(position);}});}
}public class MyAdapter extends FragmentStateAdapter {private final List<Fragment> fragmentList;public MyAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> fragmentList) {super(fragmentActivity);this.fragmentList = fragmentList;}@NonNull@Overridepublic Fragment createFragment(int position) {return fragmentList.get(position);}@Overridepublic int getItemCount() {return fragmentList != null ? fragmentList.size() : 0;}
}public class LiveStreamingFragment extends Fragment {private FragmentLiveStreamingBinding binding;@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {binding = FragmentLiveStreamingBinding.inflate(inflater, container, false);return binding.getRoot();}@Overridepublic void onDestroy() {super.onDestroy();binding = null;}
}public class RecommendFragment extends Fragment {private FragmentRecommendBinding binding;@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {binding = FragmentRecommendBinding.inflate(inflater, container, false);return binding.getRoot();}@Overridepublic void onDestroy() {super.onDestroy();binding = null;}
}// 其余几个碎片和上面的类似
// ...

activity_main.xml 代码如下:

<?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:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><com.google.android.material.tabs.TabLayoutandroid:id="@+id/tab_layout"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@android:color/transparent"android:elevation="0dp"app:tabMode="auto"app:tabSelectedTextColor="@color/pink"app:tabIndicatorColor="@color/pink"app:tabIndicatorGravity="bottom"/><androidx.viewpager2.widget.ViewPager2android:id="@+id/view_pager"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/><ImageViewandroid:layout_width="match_parent"android:layout_height="60dp"android:src="@drawable/p0"/></LinearLayout>

每个碎片布局都是简单的用了一个 ImageView 用来展示图片:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:id="@+id/image6"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/p12"/></FrameLayout>

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式学习-土堆目标检测(4)-day28

Pytorch中加载自定义数据集 - VOC其中需要pip install xmltodict#voc_dataset.pyimport os import torch import xmltodict from PIL import Image from torch.utils.data import Dataset import torchvision.transforms as transformsclass VOCDataset(Dataset): def __init_…

Spring MVC上下文容器在Web容器中是如何启动的(源码深入剖析)?

文章目录一、双容器架构&#xff1a;MVC容器与根容器的关系二、启动全流程解析1. 启动流程全景图2. 初始化根容器&#xff08;Root WebApplicationContext&#xff09;2.1 Tomcat 中启动入口源码解析2.2 Spring 根上下文启动源码解析3. 初始化 MVC 容器&#xff08;DispatcherS…

【iOS】编译和链接、动静态库及dyld的简单学习

文章目录编译和链接1️⃣核心结论&#xff1a;一句话区分2️⃣编译过程&#xff1a;从源代码到目标文件&#xff08;.o&#xff09;2.1 预处理&#xff08;Preprocessing&#xff09;&#xff1a;“替换变量复制粘贴”2.2 编译&#xff08;Compilation&#xff09;&#xff1a;…

金山办公WPS项目产品总监陈智新受邀为第十四届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会珠海金山办公软件有限公司WPS项目产品总监 陈智新先生 受邀为“PMO评论”主办的2025第十四届中国PMO大会演讲嘉宾&#xff0c;演讲议题为&#xff1a;中小团队PMO的成长之路&#xff0c;敬请关注&#xff01;议题简要&#xff1a;在竞争激烈、需求多变的…

web安全 | docker复杂环境下的内网打点

本文作者&#xff1a;Track-syst1m一.前言本文涉及的相关漏洞均已修复、本文中技术和方法仅用于教育目的&#xff1b;文中讨论的所有案例和技术均旨在帮助读者更好地理解相关安全问题&#xff0c;并采取适当的防护措施来保护自身系统免受攻击。二.大概流程1. 外网打点• 漏洞利…

iTwin 几何属性获取

面积体积半径获取几何属性&#xff0c;如面积&#xff0c;体积&#xff0c;半径&#xff0c;可以使用getMassProperties这个接口async onGetMassProperty(){const vp IModelApp.viewManager.selectedView;const iModel vp?.iModel;if (!iModel) return;console.log("iM…

OpenLayers 快速入门(九)Extent 介绍

看过的知识不等于学会。唯有用心总结、系统记录&#xff0c;并通过温故知新反复实践&#xff0c;才能真正掌握一二 作为一名摸爬滚打三年的前端开发&#xff0c;开源社区给了我饭碗&#xff0c;我也将所学的知识体系回馈给大家&#xff0c;助你少走弯路&#xff01; OpenLayers…

LeetCode 121. 买卖股票的最佳时机 LeetCode 122. 买卖股票的最佳时机II LeetCode 123.买卖股票的最佳时机III

LeetCode 121. 买卖股票的最佳时机尝试一&#xff1a;暴力解决方法常用两个指针去遍历prices数组&#xff0c;dp[i]用于记录在第i天所获得的最大利润。时间复杂度是O(N^2)&#xff0c;超出时间限制。Codeclass Solution(object):def maxProfit(self, prices):"""…

【LeNet网络架构】——深度学习.卷积神经网络

目录 1 MLP 2 LeNet简介 3 Minst数据集 3.1 MINST数据集简介 3.2 MNIST数据集的预处理 4 LeNet手写数字识别 LeNet由Yann Lecun 提出&#xff0c;是一种经典的卷积神经网络&#xff0c;是现代卷积神经网络的起源之一。Yann将该网络用于邮局的邮政的邮政编码识别&#xff…

Python笔记完整版

常用pip源 &#xff08;1&#xff09;阿里云 http://mirrors.aliyun.com/pypi/simple/&#xff08;2&#xff09;豆瓣 http://pypi.douban.com/simple/&#xff08;3&#xff09;清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/&#xff08;4&#xff09;中国科学技术大学…

2025 鸿蒙创新赛又来了,万少教你如何强势切入 HarmonyOS AI特性

2025 鸿蒙创新赛又来了&#xff0c;万少教你如何强势切入 前言 ​ 2025 华为HarmonyOS 创新赛又来了&#xff0c;创新赛是鸿蒙生态最大规模开发者官方赛事&#xff0c;最高获百万激励。 参赛资格 面向所有开发者开放以队伍的形式来参加&#xff0c;可以一个人报名一个队伍&a…

【智能模型系列】Unity通过访问Ollama调用DeepSeek模型进行本地部署

【智能模型系列】Unity通过访问Ollama调用DeepSeek模型进行本地部署 目录 一、前言 二、环境准备 三、核心代码解析 1、参数配置 2. CallDeepSeek.cs - API交互控制器 3、 MainPanel.cs - 用户界面控制器 四、源码 一、前言 在本教程中,我将分享如何在Unity中集成本地…

什么是5G-A三防平板?有什么特点?哪些领域能用到?

在工业自动化与数字化转型浪潮中&#xff0c;三防平板电脑已成为“危、急、特”场景的核心工具。这类设备不仅具备坚固耐用的物理防护特性&#xff0c;更融合了先进的通信技术与智能处理能力。而随着5G技术向5G-A阶段演进&#xff0c;新一代三防平板正为行业应用注入全新动能。…

Flink实时流量统计:基于窗口函数与Redis Sink的每小时PV监控系统(学习记录)

题目&#xff1a;利用flink统计网站浏览量&#xff0c;并写入redis。利用窗口函数以及算子实现每小时PV&#xff08;网站的页面浏览量&#xff09;统计&#xff0c;对统计后结果数据格式进行设计&#xff0c;存储至Redis中&#xff08;利用sink将处理后结果数据输出到redis数据…

使用Imgui和SDL2做的一个弹球小游戏-Bounze

使用Imgui和SDL2做的一个弹球小游戏-Bounze 油管上面TheCherno博主分享的一个视频FIRST GAME in C! Did He Do a Good Job? // Code Review (C/SDL2)里面分享了一个Github项目&#xff1a; https://github.com/staticaron/Bounze 使用了Imgui和SDL2&#xff0c;并且可以设置音…

SQL 中 CASE WHEN 及 SELECT CASE WHEN 的用法

SQL 中 CASE WHEN 及 SELECT CASE WHEN 的用法 CASE WHEN 是 SQL 中非常实用的条件表达式&#xff0c;它允许你在查询中实现条件逻辑。以下是详细的用法说明&#xff1a; 1. 基本语法结构 CASE WHEN condition1 THEN result1WHEN condition2 THEN result2...ELSE default_resul…

CentOS 7 Linux 基础知识点汇总

&#x1f427; CentOS 7 Linux 基础知识点汇总为方便初学者快速掌握 CentOS 7 系统的核心操作&#xff0c;本文档整理了常用系统命令、快捷键、目录结构及文件后缀名等基础内容&#xff0c;适合入门参考。 一、常见系统命令 &#x1f50d; 命令行提示符说明 终端中的提示符包含…

突发限制下的破局之路:国产之光 Lynx 重构 AI 开发安全壁垒

继 Pro 套餐 “明升暗降” 争议后&#xff0c;Cursor 本周再掀波澜 —— 包括 Claude 系列、GPT-4 在内的主流模型一夜之间对中国用户全面封禁。开发者社群瞬间沸腾&#xff0c;“付费却用不了”“项目数据导不出” 的焦虑刷屏&#xff0c;境外工具的政策波动再次给行业敲响警钟…

渗透测试实战 | docker复杂环境下的内网打点

本文作者&#xff1a;Track-syst1m一.前言本文涉及的相关漏洞均已修复、本文中技术和方法仅用于教育目的&#xff1b;文中讨论的所有案例和技术均旨在帮助读者更好地理解相关安全问题&#xff0c;并采取适当的防护措施来保护自身系统免受攻击。二.大概流程1. 外网打点漏洞利用•…

阿里云服务器 CentOS 7 安装 MySQL 8.4 超详细指南

阿里云服务器 CentOS 7 安装 MySQL 8.4 超详细指南 一、准备工作 系统要求&#xff1a; CentOS 7.9 64位2 核&#xff08;vCPU&#xff09;2 GiBroot 用户权限 服务器连接工具&#xff1a; FinalShell 下载安装包&#xff1a; 访问 MySQL 官网选择版本&#xff1a;MySQL 8.4.0…