Android auncher3实现简单的负一屏功能

Android launcher3实现简单的负一屏功能

在这里插入图片描述

1.前言:

之前实现过Launcher3从凑提修改成单层,今天来讲解一下如何实现一个简单的负一屏功能,涉及的类如下,直接看代码。

2.NegativeScreenAdapter:

package com.example.negativescreendemo.adapter;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import com.example.negativescreendemo.ActionItem;
import com.example.negativescreendemo.CardItem;
import com.example.negativescreendemo.NewsItem;
import com.example.negativescreendemo.R;
import com.example.negativescreendemo.ScheduleItem;
import com.example.negativescreendemo.TodoItem;import java.util.List;/*** @author: njb* @date: 2025/8/20 21:19* @desc: 描述*/
public class NegativeScreenAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{private Context context;private List<CardItem> cardItems;private OnItemClickListener listener;// 卡片类型public enum CardType {ACTIONS, SCHEDULE, NEWS, TODO}public NegativeScreenAdapter(Context context, List<CardItem> cardItems) {this.context = context;this.cardItems = cardItems;}@NonNull@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {LayoutInflater inflater = LayoutInflater.from(context);switch (viewType) {case 0: // 快捷功能卡片View actionView = inflater.inflate(R.layout.item_action_card, parent, false);return new ActionCardViewHolder(actionView);case 1: // 日程卡片View scheduleView = inflater.inflate(R.layout.item_schedule_card, parent, false);return new ScheduleCardViewHolder(scheduleView);case 2: // 新闻卡片View newsView = inflater.inflate(R.layout.item_news_card, parent, false);return new NewsCardViewHolder(newsView);case 3: // 待办事项卡片View todoView = inflater.inflate(R.layout.item_todo_card, parent, false);return new TodoCardViewHolder(todoView);default:return null;}}@Overridepublic void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {CardItem item = cardItems.get(position);if (holder instanceof ActionCardViewHolder) {((ActionCardViewHolder) holder).title.setText(item.getTitle());ActionAdapter actionAdapter = new ActionAdapter(context, item.getActionItems());((ActionCardViewHolder) holder).recyclerView.setAdapter(actionAdapter);((ActionCardViewHolder) holder).recyclerView.setLayoutManager(new GridLayoutManager(context, 3));}else if (holder instanceof ScheduleCardViewHolder) {((ScheduleCardViewHolder) holder).title.setText(item.getTitle());ScheduleAdapter scheduleAdapter = new ScheduleAdapter(context, item.getScheduleItems());((ScheduleCardViewHolder) holder).recyclerView.setAdapter(scheduleAdapter);}else if (holder instanceof NewsCardViewHolder) {((NewsCardViewHolder) holder).title.setText(item.getTitle());NewsAdapter newsAdapter = new NewsAdapter(context, item.getNewsItems());((NewsCardViewHolder) holder).recyclerView.setAdapter(newsAdapter);}else if (holder instanceof TodoCardViewHolder) {((TodoCardViewHolder) holder).title.setText(item.getTitle());TodoAdapter todoAdapter = new TodoAdapter(context, item.getTodoItems());((TodoCardViewHolder) holder).recyclerView.setAdapter(todoAdapter);}// 设置点击事件holder.itemView.setOnClickListener(v -> {if (listener != null) {listener.onItemClick(position);}});}@Overridepublic int getItemCount() {return cardItems.size();}@Overridepublic int getItemViewType(int position) {CardType type = cardItems.get(position).getType();switch (type) {case ACTIONS: return 0;case SCHEDULE: return 1;case NEWS: return 2;case TODO: return 3;default: return 0;}}// 快捷功能卡片ViewHolderpublic static class ActionCardViewHolder extends RecyclerView.ViewHolder {TextView title;RecyclerView recyclerView;public ActionCardViewHolder(View itemView) {super(itemView);title = itemView.findViewById(R.id.card_title);recyclerView = itemView.findViewById(R.id.action_recycler);}}// 日程卡片ViewHolderpublic static class ScheduleCardViewHolder extends RecyclerView.ViewHolder {TextView title;RecyclerView recyclerView;public ScheduleCardViewHolder(View itemView) {super(itemView);title = itemView.findViewById(R.id.card_title);recyclerView = itemView.findViewById(R.id.schedule_recycler);}}// 新闻卡片ViewHolderpublic static class NewsCardViewHolder extends RecyclerView.ViewHolder {TextView title;RecyclerView recyclerView;public NewsCardViewHolder(View itemView) {super(itemView);title = itemView.findViewById(R.id.card_title);recyclerView = itemView.findViewById(R.id.news_recycler);}}// 待办事项卡片ViewHolderpublic static class TodoCardViewHolder extends RecyclerView.ViewHolder {TextView title;RecyclerView recyclerView;public TodoCardViewHolder(View itemView) {super(itemView);title = itemView.findViewById(R.id.card_title);recyclerView = itemView.findViewById(R.id.todo_recycler);}}// 快捷功能子项适配器public class ActionAdapter extends RecyclerView.Adapter<ActionAdapter.ViewHolder> {private Context context;private List<ActionItem> items;public ActionAdapter(Context context, List<ActionItem> items) {this.context = context;this.items = items;}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(context).inflate(R.layout.item_action, parent, false);return new ViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {ActionItem item = items.get(position);holder.icon.setImageResource(item.getIconRes());holder.name.setText(item.getName());}@Overridepublic int getItemCount() {return items.size();}public class ViewHolder extends RecyclerView.ViewHolder {ImageView icon;TextView name;public ViewHolder(View itemView) {super(itemView);icon = itemView.findViewById(R.id.action_icon);name = itemView.findViewById(R.id.action_name);}}}// 日程子项适配器public class ScheduleAdapter extends RecyclerView.Adapter<ScheduleAdapter.ViewHolder> {private Context context;private List<ScheduleItem> items;public ScheduleAdapter(Context context, List<ScheduleItem> items) {this.context = context;this.items = items;}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(context).inflate(R.layout.item_schedule, parent, false);return new ViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {ScheduleItem item = items.get(position);holder.time.setText(item.getTime());holder.title.setText(item.getTitle());holder.location.setText(item.getLocation());}@Overridepublic int getItemCount() {return items.size();}public class ViewHolder extends RecyclerView.ViewHolder {TextView time, title, location;public ViewHolder(View itemView) {super(itemView);time = itemView.findViewById(R.id.schedule_time);title = itemView.findViewById(R.id.schedule_title);location = itemView.findViewById(R.id.schedule_location);}}}// 新闻子项适配器public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {private Context context;private List<NewsItem> items;public NewsAdapter(Context context, List<NewsItem> items) {this.context = context;this.items = items;}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(context).inflate(R.layout.item_news, parent, false);return new ViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {NewsItem item = items.get(position);holder.title.setText(item.getTitle());holder.source.setText(item.getSource());holder.time.setText(item.getTime());}@Overridepublic int getItemCount() {return items.size();}public class ViewHolder extends RecyclerView.ViewHolder {TextView title, source, time;public ViewHolder(View itemView) {super(itemView);title = itemView.findViewById(R.id.news_title);source = itemView.findViewById(R.id.news_source);time = itemView.findViewById(R.id.news_time);}}}// 待办事项子项适配器public class TodoAdapter extends RecyclerView.Adapter<TodoAdapter.ViewHolder> {private Context context;private List<TodoItem> items;public TodoAdapter(Context context, List<TodoItem> items) {this.context = context;this.items = items;}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(context).inflate(R.layout.item_todo, parent, false);return new ViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {TodoItem item = items.get(position);holder.content.setText(item.getContent());holder.checkBox.setChecked(item.isCompleted());holder.checkBox.setOnCheckedChangeListener((buttonView, isChecked) ->item.setCompleted(isChecked));}@Overridepublic int getItemCount() {return items.size();}public class ViewHolder extends RecyclerView.ViewHolder {CheckBox checkBox;TextView content;public ViewHolder(View itemView) {super(itemView);checkBox = itemView.findViewById(R.id.todo_checkbox);content = itemView.findViewById(R.id.todo_content);}}}// 点击事件接口public interface OnItemClickListener {void onItemClick(int position);}public void setOnItemClickListener(OnItemClickListener listener) {this.listener = listener;}
}

3.ActionItem:

package com.example.negativescreendemo;/*** @author: njb* @date: 2025/8/20 21:28* @desc: 描述*/
public class ActionItem {private String name;private int iconRes;public ActionItem(String name, int iconRes) {this.name = name;this.iconRes = iconRes;}public String getName() {return name;}public int getIconRes() {return iconRes;}
}

4.卡片CardItem:

package com.example.negativescreendemo;import com.example.negativescreendemo.adapter.NegativeScreenAdapter;import java.util.List;/*** @author: njb* @date: 2025/8/20 21:21* @desc: 描述*/
public class CardItem {private NegativeScreenAdapter.CardType type;private String title;private List<ActionItem> actionItems;private List<ScheduleItem> scheduleItems;private List<NewsItem> newsItems;private List<TodoItem> todoItems;// 私有构造方法,防止直接实例化private CardItem() {}/*** 创建快捷操作卡片*/public static CardItem createActionCard(NegativeScreenAdapter.CardType type, String title, List<ActionItem> actionItems) {CardItem item = new CardItem();item.type = type;item.title = title;item.actionItems = actionItems;return item;}/*** 创建日程卡片*/public static CardItem createScheduleCard(NegativeScreenAdapter.CardType type, String title, List<ScheduleItem> scheduleItems) {CardItem item = new CardItem();item.type = type;item.title = title;item.scheduleItems = scheduleItems;return item;}/*** 创建新闻卡片*/public static CardItem createNewsCard(NegativeScreenAdapter.CardType type, String title, List<NewsItem> newsItems) {CardItem item = new CardItem();item.type = type;item.title = title;item.newsItems = newsItems;return item;}/*** 创建待办事项卡片*/public static CardItem createTodoCard(NegativeScreenAdapter.CardType type, String title, List<TodoItem> todoItems) {CardItem item = new CardItem();item.type = type;item.title = title;item.todoItems = todoItems;return item;}// Getterspublic NegativeScreenAdapter.CardType getType() {return type;}public String getTitle() {return title;}public List<ActionItem> getActionItems() {return actionItems;}public List<ScheduleItem> getScheduleItems() {return scheduleItems;}public List<NewsItem> getNewsItems() {return newsItems;}public List<TodoItem> getTodoItems() {return todoItems;}
}

5.NewItem:

package com.example.negativescreendemo;/*** @author: njb* @date: 2025/8/20 21:28* @desc: 描述*/
public class NewsItem {private String title;private String source;private String time;public NewsItem(String title, String source, String time) {this.title = title;this.source = source;this.time = time;}public String getTitle() {return title;}public String getSource() {return source;}public String getTime() {return time;}
}

6.ScheduleItem:

package com.example.negativescreendemo;/*** @author: njb* @date: 2025/8/20 21:28* @desc: 描述*/
public class ScheduleItem {private String time;private String title;private String location;public ScheduleItem(String time, String title, String location) {this.time = time;this.title = title;this.location = location;}public String getTime() {return time;}public String getTitle() {return title;}public String getLocation() {return location;}
}

7.TodoItem:

package com.example.negativescreendemo;/*** @author: njb* @date: 2025/8/20 21:28* @desc: 描述*/
public class TodoItem {private String content;private boolean isCompleted;public TodoItem(String content, boolean isCompleted) {this.content = content;this.isCompleted = isCompleted;}public String getContent() {return content;}public boolean isCompleted() {return isCompleted;}public void setCompleted(boolean completed) {isCompleted = completed;}
}

8.主界面布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/gray_50"tools:context=".NegativeScreenActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><!-- 顶部时间天气区域 --><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="16dp"android:orientation="vertical"><TextViewandroid:id="@+id/time_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="12:30"android:textColor="@color/black"android:textSize="48sp"android:textStyle="bold" /><TextViewandroid:id="@+id/date_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="8dp"android:text="星期一, 六月 15日"android:textColor="@color/gray_600"android:textSize="16sp" /><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="12dp"android:gravity="center"android:layout_gravity="center"android:orientation="horizontal"><ImageViewandroid:id="@+id/weather_icon"android:layout_width="24dp"android:layout_height="24dp"android:src="@drawable/ic_scan" /><TextViewandroid:id="@+id/weather_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:text="25°C 晴朗"android:textColor="@color/gray_600"android:textSize="16sp" /></LinearLayout></LinearLayout><!-- 卡片列表 --><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recycler_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:paddingHorizontal="16dp"android:clipToPadding="false" /></LinearLayout>
</androidx.core.widget.NestedScrollView>

9.主界面测试代码:

package com.example.negativescreendemo;import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import com.example.negativescreendemo.adapter.NegativeScreenAdapter;import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;/*** @author: njb* @date: 2025/8/20 21:18* @desc: 描述*/
public class NegativeScreenActivity extends AppCompatActivity {private RecyclerView recyclerView;private NegativeScreenAdapter adapter;private List<CardItem> cardItems;private TextView timeTextView;private TextView dateTextView;private TextView weatherTextView;private ImageView weatherIcon;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_negative_screen);// 初始化视图initViews();// 初始化数据initData();// 设置适配器adapter = new NegativeScreenAdapter(this, cardItems);recyclerView.setAdapter(adapter);recyclerView.setLayoutManager(new LinearLayoutManager(this));// 设置点击事件adapter.setOnItemClickListener(position -> {CardItem item = cardItems.get(position);Toast.makeText(NegativeScreenActivity.this,"点击了: " + item.getTitle(), Toast.LENGTH_SHORT).show();});// 更新时间updateTime();}private void initViews() {recyclerView = findViewById(R.id.recycler_view);timeTextView = findViewById(R.id.time_text);dateTextView = findViewById(R.id.date_text);weatherTextView = findViewById(R.id.weather_text);weatherIcon = findViewById(R.id.weather_icon);}private void initData() {// 模拟天气数据weatherTextView.setText("25°C 晴朗");// 初始化卡片数据cardItems = new ArrayList<>();// 添加快捷功能卡片List<ActionItem> actionItems = new ArrayList<>();actionItems.add(new ActionItem("扫一扫", R.drawable.ic_scan));actionItems.add(new ActionItem("付款", R.drawable.ic_pay));actionItems.add(new ActionItem("乘车码", R.drawable.ic_bus));actionItems.add(new ActionItem("健康码", R.drawable.ic_health));actionItems.add(new ActionItem("充电宝", R.drawable.ic_power_bank));actionItems.add(new ActionItem("更多", R.drawable.ic_more));cardItems.add(CardItem.createActionCard(NegativeScreenAdapter.CardType.ACTIONS, "快捷功能", actionItems));// 添加日程卡片List<ScheduleItem> scheduleItems = new ArrayList<>();scheduleItems.add(new ScheduleItem("9:30", "团队周会", "会议室A"));scheduleItems.add(new ScheduleItem("14:00", "客户拜访", "XX公司"));cardItems.add(CardItem.createScheduleCard(NegativeScreenAdapter.CardType.SCHEDULE, "今日日程", scheduleItems));// 添加新闻卡片List<NewsItem> newsItems = new ArrayList<>();newsItems.add(new NewsItem("最新科技突破:人工智能新进展", "科技日报", "10分钟前"));newsItems.add(new NewsItem("本地气温将持续升高,最高达35°C", "本地新闻", "30分钟前"));cardItems.add(CardItem.createNewsCard(NegativeScreenAdapter.CardType.NEWS, "热点新闻", newsItems));// 添加待办事项卡片List<TodoItem> todoItems = new ArrayList<>();todoItems.add(new TodoItem("完成项目报告", false));todoItems.add(new TodoItem("购买生日礼物", true));todoItems.add(new TodoItem("回复客户邮件", false));cardItems.add(CardItem.createTodoCard(NegativeScreenAdapter.CardType.TODO, "待办事项", todoItems));}private void updateTime() {// 更新时间和日期final Handler handler = new Handler(Looper.getMainLooper());Timer timer = new Timer();timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {handler.post(() -> {SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm", Locale.getDefault());SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, MMMM d日", Locale.getDefault());String time = timeFormat.format(new Date());String date = dateFormat.format(new Date());timeTextView.setText(time);dateTextView.setText(date);});}}, 0, 60000); // 每分钟更新一次}
}

10.实现效果如下:

在这里插入图片描述

11.总结:

分层架构 + 模块化设计为核心,通过 “数据模型封装 - UI 适配渲染 - 界面逻辑控制” 三层结构,快速搭建 Launcher3 负一屏功能,核心是利用RecyclerView嵌套实现 “卡片容器 + 子项列表” 的灵活布局,同时保证界面交互与数据展示的解耦。

关键技术点

  • RecyclerView 多类型布局:通过getItemViewType()和不同ViewHolder,实现 4 类卡片的差异化展示,降低代码耦合。
  • RecyclerView 嵌套:外层RecyclerView(卡片列表)嵌套内层RecyclerView(卡片子项),结合GridLayoutManager(快捷功能 3 列)和LinearLayoutManager(其他卡片单列),满足不同布局需求。
  • 线程安全的 UI 更新:用Handler(Looper.getMainLooper())Timer的定时任务切换到主线程,避免子线程操作 UI 的异常。
  • 数据模型私有化构造CardItem通过私有构造 + 静态创建方法,强制规范卡片创建流程,避免错误数据赋值。

12.源码地址:

https://gitee.com/jackning_admin/negative-screen-demo

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

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

相关文章

跨网闸数据库同步:在物理隔离中架起安全的数据桥梁

作者:DeepSeek-R1 | 日期:2025年8月17日 引言 在等保2.0和分级保护政策的要求下,高密级网络(如政务内网、金融核心网)必须与低密级网络(如互联网)物理隔离。但业务又要求数据跨网流动(如市民在线提交申请、分支机构数据回传)。如何解决这一矛盾?双向网闸与单向光闸成…

【Android】一文详解Android里的AOP编程

一文详解Android里的AOP编程 1. 基于 AspectJ&#xff08;编译期/打包期织入&#xff09; 思路&#xff1a;用 AspectJ 编译器在 编译阶段 或 Gradle Transform 阶段&#xff0c;把切面逻辑织入 class / bytecode。 特点&#xff1a; 能实现类似 Spring AOP 的注解切面&#…

AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年8月21日第167弹

从今天开始&#xff0c;咱们还是暂时基于旧的模型进行预测&#xff0c;好了&#xff0c;废话不多说&#xff0c;按照老办法&#xff0c;重点8-9码定位&#xff0c;配合三胆下1或下2&#xff0c;杀1-2个和尾&#xff0c;再杀4-5个和值&#xff0c;可以做到100-300注左右。(1)定位…

机器学习【十】neural network

系统梳理了机器学习与神经网络的基础知识&#xff0c;涵盖理论、核心概念及代码实践。理论部分包括线性模型&#xff08;向量表示、广义线性模型&#xff09;、分类与回归的区别、梯度下降&#xff08;批量/随机/小批量&#xff09;、激活函数&#xff08;Sigmoid、ReLU等&…

如何用算力魔方4060安装PaddleOCR MCP 服务器

在当今数字化快速发展的时代&#xff0c;OCR&#xff08;光学字符识别&#xff09;技术已经成为从图像中提取文本信息的重要工具。无论是在自动化办公、智能文档处理还是在内容创作领域&#xff0c;OCR 技术的应用都极大地提高了工作效率和准确性。本文将详细介绍如何利用算力魔…

Azure的迁移专业服务是怎么提供的

好的&#xff0c;这是一个非常实际的问题。Azure的迁移专业服务&#xff08;Professional Services for Migration&#xff09;并非一个单一的“产品”&#xff0c;而是一个由微软及其庞大的合作伙伴生态系统共同提供的、基于成熟方法论的综合服务框架。其提供方式可以概括为&a…

Seaborn数据可视化实战:Seaborn入门-环境搭建与基础操作

Seaborn环境搭建与配置 学习目标 本课程将指导学员如何在不同的操作系统&#xff08;Windows, macOS, Linux&#xff09;上安装Seaborn库&#xff0c;以及如何配置Python环境&#xff0c;包括使用Jupyter Notebook和Spyder等集成开发环境&#xff08;IDE&#xff09;的基本操作…

Windows下RabbitMQ完整安装指南

一、RabbitMQ 简介 RabbitMQ 是一款基于 Erlang 语言开发的开源消息队列中间件&#xff0c;实现了高级消息队列协议&#xff08;AMQP&#xff09;。其最初起源于金融系统&#xff0c;专为分布式系统中的消息存储与转发设计&#xff0c;在可靠性、扩展性和高可用性方面表现卓越…

thingsboard 通过Entities hierarchy部件实现左边菜单点击,右边的表格按左边的分类型进行过滤筛选数据源

在 ThingsBoard 中&#xff0c;要让“Entities hierarchy”部件&#xff08;左侧树形导航&#xff09;与右侧的数据表格实现联动——即点击左侧某个节点后&#xff0c;右侧表格立刻按该节点对应的实体类型/层级进行过滤——需要把“数据源别名&#xff08;Alias&#xff09; 仪…

【Ansible】核心概念解析:架构、清单管理与配置入门

本专栏文章持续更新&#xff0c;新增内容使用蓝色表示。对于系统管理员而言&#xff0c;手动管理每一台服务器不仅维护难度极大&#xff0c;而且即使经验丰富&#xff0c;也难免出现疏忽和错误。自动化技术能有效避免因手动管理系统和基础架构而产生的各类问题。其优点包括&…

rs-fMRI_两篇文章中分析方法的梳理(近乎翻译)

文章一文章信息APOE ε4 influences within and between network functional connectivity in posterior cortical atrophy and logopenic progressive aphasia2024美国梅奥诊所发表在Alzheimers Dement. 的文章。“APOE ε4等位基因对后皮质萎缩与进行性语言障碍型失语症的网络…

在互联网大厂的Java面试:谢飞机的搞笑历险记

在互联网大厂的Java面试&#xff1a;谢飞机的搞笑历险记 在一个阳光明媚的早上&#xff0c;我们的主角&#xff0c;程序员谢飞机&#xff0c;走进了一家著名的互联网大厂&#xff0c;准备迎接他人生中最严峻的挑战——Java面试。 第一轮&#xff1a;基础技术面试 面试官&#x…

微软AD国产化替换倒计时——不是选择题,而是生存题

一直以来&#xff0c;微软Active Directory&#xff08;AD&#xff09;作为企业身份管理和访问控制的核心组件&#xff0c;承担着用户认证、权限分配、资源目录管理等基础职能。然而&#xff0c;随着政策、合规与网络安全压力不断加剧&#xff0c;AD面临着前所未有的挑战&#…

MyBatis-Plus MetaObjectHandler的几个坑(主要是id字段)

1.背景 主要是要实现一个id字段的自增长&#xff0c;不依赖数据库的能力&#xff08;已避免后续换库的问题&#xff09;。姑且使用redis作为表的id分配器&#xff0c;因此使用MyBatis-Plus MetaObjectHandler对每个insert的id进行分配。 2.实施过程 以下是实现过程 1.实现MetaO…

Springboot 项目配置多数据源

Springboot 项目配置多数据源 基础环境 java8、springboot2.2.13、mybatis、mysql5.x、oracle 项目配置 1.application.yml spring:datasource:mysql1:username: abcpassword: 123456url: jdbc:mysql://127.0.0.1:3306/panda?useUnicodetrue&characterEncodingUTF-8&z…

STM32_0001 KEILMDK V5.36 编译一个STM32F103C8T6说core_cm3.h文件找不到以及编译器版本不匹配的解决办法

KEILMDK V5.36 编译一个STM32F103C8T6说core_cm3.h文件找不到的解决办法利用KEILMDK V5.36 编译一个STM32F103C8T6说core_cm3.h文件找不到。主要错误信息如下D:/stm32studio/Armmdk/Packs/Keil/STM32F1xx_DFP/2.4.1/Device/Include\stm32f10x.h(486): error: core_cm3.h file n…

基于Transformer的机器翻译——训练篇

前言 还在为机器翻译模型从理论到落地卡壳&#xff1f;系列博客第三弹——模型训练篇强势登场&#xff0c;手把手带你走完Transformer中日翻译项目的最后关键一步&#xff01; 前两期我们搞定了数据预处理&#xff08;分词、词表构建全流程&#xff09;和模型搭建&#xff08…

智能编程中的智能体与 AI 应用:概念、架构与实践场景

一、智能体&#xff08;Intelligent Agent&#xff09;在编程中的定义与架构1. 智能体的核心概念 智能体是指在特定环境中能够自主感知、决策并执行动作的软件实体&#xff0c;具备以下特征&#xff1a;自主性&#xff1a;无需人工干预即可根据环境变化调整行为。交互性&#x…

数组实现各类数据结构

目录 一、数组实现单链表 二、数组实现双链表 三、数组实现栈 四、数组模拟队列 五、数组模拟单调栈 六、数组模拟单调队列&#xff08;滑动窗口&#xff09; 七、数组模拟堆 一、数组实现单链表 #include<iostream> #include<algorithm> #include<cstr…

数据处理与统计分析 —— apply自定义函数

目录 一、向量化与伪向量化 1、向量化 2、np.vectorize 伪向量化&#xff08;特定场景&#xff09; 3、apply&#xff08;自定义函数&#xff09; 二、apply函数 1、对series中使用apply 2、对dataframe中使用apply 3、apply函数案例-泰坦尼克号数据集] 数据集下载链接&#xf…