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
英文地址,請注明出處:http://en.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…