当前位置: 首页 > news >正文

Android Snackbar

1.Snackbar

Snackbar是Material Design中的一个控件,用来代替Toast。Snackbar是一个类似Toast的快速弹出消息提示的控件。Snackbar在显示上比Toast丰富,而且提供了用户交互的接口。

①默认情况下,Snackbar显示在屏幕底部,它出现在屏幕所有元素之上,且同时最多只能显示一个Snackbar。

②Snackbar与某些视图相关联,并且仅当视图在屏幕上时才会显示Snackbar。

③Snackbar出现时不会阻碍用户在屏幕上的输入。Snackbar可以自定义时长。

④当Snackbar在CoordinatorLayout下使用时,支持右滑删除功能。

 

2.Snackbar的用法

Snackbar的用法很简单,不需要在xml中写布局,像Toast一样直接在代码里使用即可。

首先需要添加依赖:

implementation "com.google.android.material:$latest_version" 

然后就可以在代码中使用了:

①最基本的用法

Snackbar.make(view, "Show some message here",Snackbar.LENGTH_LONG)

.setAction("Action", v1 -> {

        Log.e(TAG, "点击了确定按钮");

}).show();

92ff9ab3f82449e09f7f41086249ca7a.png

注意:Snackbar不支持设置多个action,如果设置多个action,只有最后一个生效。

②设置颜色

Snackbar.make(view, "Show some message here", Snackbar.LENGTH_SHORT)

.setBackgroundTint(ContextCompat.getColor(this, R.color.baseCyan))

.setActionTextColor(ContextCompat.getColor(this, R.color.white))

.setTextColor(ContextCompat.getColor(this,R.color.black))

.setAction("Action") { 

     Log.e(TAG, "点击了确定按钮");

}

.show()

fbef3ab2c7344652804db1b9abdcbeb8.png

 ③添加回调

addCallback()用于给snackbar添加回调,回调Snackbar弹出和关闭动作。

Snackbar.make(view, "Show some message here", Snackbar.LENGTH_SHORT)

.addCallback(new Snackbar.Callback() {

    public void onShown(Snackbar sb) {

        super.onShown(sb)

        Log.d(TAG, "onShown")

    }

    public void onDismissed( transientBottomBar: Snackbar?, event: Int) {

        super.onDismissed(transientBottomBar, event)

        Log.d(TAG, "onDismissed")

    }

}).show();

④在文本前面添加图片

Snackbar snackbar = Snackbar.make(view, "这是一个snackbar", Snackbar.LENGTH_SHORT);

snackbar.setAction("取消", new View.OnClickListener() {

    @Override

    public void onClick(View v) {

    }

});

TextView textView = snackbar.getView().findV iewById(R.id.snackbar_text);

Drawable drawable = getResources().getDrawa ble(R.mipmap.ic_launcher_round);

drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());

textView.setCompoundDrawables(drawable, null, null, null);

//增加文字和图标的距离

textView.setCompoundDrawablePadding(20);

textView.setGravity(Gravity.CENTER);

snackbar.show();

65eea4a867334a5bb4662aa344078bfd.webp

⑤自定义布局

自定义布局的步骤:

1)通过Snackbar.getView获取到view;

1)通过LayoutInflater去加载布局得到自定义的布局view;

3)通过①中获取到的view添加②中加载好的布局view;

4)通过①中得到的自定义布局获取里面的控件去执行一些操作,比如点击事件,设置文字和文字颜色等。

View rootView = getWindow().getDecorView();

View coordinatorLayout = rootView.findViewById(android.R.id.content);

Snackbar snackbar = Snackbar.make( coordinatorLayout, "", Snackbar.LENGTH_SHORT);

// 获取到Snackbar.getView获取的Snackbar的view

Snackbar.SnackbarLayout snackbarView = (Snackbar.SnackbarLayout) snackbar.getView();

// 加载自定义布局

View inflate = LayoutInflater.from( snackbar.getView().getContext()).inflate(R.layout.snacbar_layout, null);

// 获取自定义布局中的控件

TextView text = inflate.findViewById( R.id.textView);

text.setText("自定义布局的Snackbar");

ImageView imageView = inflate.findViewById( R.id.imageView);

imageView.setOnClickListener(v1 -> Log.d("TAG", "点击了自定义布局中的控件"));

// 将自定义布局view添加到SnackbarView中

snackbarView.addView(inflate);

snackbar.show();

⑥修改Snackbar的位置

自定义位置的步骤:

1)获取到SnackbarView的LayoutParams;

2)通过①中获取到的LayoutParams创建新的LayoutParams;

③给②中的LayoutParams设置Gravity;

④将新的LayoutParams设置给SnackbarView。

View rootView = getWindow().getDecorView();

View coordinatorLayout = rootView.findViewById(android.R.id.content);

Snackbar snackbar = Snackbar.make(coordinatorLayout, "", Snackbar.LENGTH_SHORT);

// 设置SnackbarView的padding都为0,避免上图中出现黑色边框背景的情况

snackbar.getView().setPadding(0,0,0,0);

// 将SnackbarView的背景颜色设置为透明,避免在自定义布局中有圆角或者自适应宽度的时候显示一块黑色背景的情况

snackbar.getView().setBackgroundColor(Color.TRANSPARENT);

// 获取到Snackbar.getView获取的Snackbar的view

Snackbar.SnackbarLayout snackbarView = (Snackbar.SnackbarLayout) snackbar.getView();

// 获取到SnackbarView的LayoutParams

ViewGroup.LayoutParams layoutParams = snackbarView.getLayoutParams();

// 新建一个LayoutParams将SnackbarView的LayoutParams的宽高传入

FrameLayout.LayoutParams fl = new FrameLayout.LayoutParams(layoutParams.width, layoutParams.height);

// 设置新的元素位置

fl.gravity = Gravity.CENTER;

// 将新的LayoutParams设置给SnackbarView

snackbarView.setLayoutParams(fl);

// 自定义的布局

View inflate = LayoutInflater.from( snackbar.getView().getContext()).inflate(R.layout.snacbar_layout, null);

TextView text = inflate.findViewById( R.id.textView);

text.setText("自定义布局的Snackbar");

ImageView imageView = inflate.findViewById(R.id.imageView);

imageView.setOnClickListener(v1 -> Log.d("TAG", "点击了自定义布局中的控件"));

snackbarView.addView(inflate);

snackbar.show();

 

3.Snackbar源码

①Snackbar使用静态方法make()创建实例

public static Snackbar make(View view, int resId, int duration) {

    return make(view, view.getResources().getText(resId), duration);

}

public static Snackbar make(View view, CharSequence text, int duration) {

    ViewGroup parent = findSuitableParent( view);

    if (parent == null) {

        throw new IllegalArgumentException("No suitable parent found from the given view. Please provide a valid view.");

    }

    final LayoutInflater inflater = LayoutInflater.from(parent.getContext());

    final SnackbarContentLayout content =(SnackbarContentLayout) inflater.inflate( R.layout.design_layout_snackbar_include, parent, false);

    final Snackbar snackbar = new Snackbar( parent, content, content);

    snackbar.setText(text);

    snackbar.setDuration(duration);

    return snackbar;

}

②findSuitableParent()

创建Snackbar实例,需要寻找合适的父视图,优先选择CoordinatorLayout作为父视图。

private static ViewGroup findSuitableParent( View view) {

    ViewGroup fallback = null;

    do {

        if (view instanceof CoordinatorLayout) {

            return (ViewGroup) view;

        } else if (view instanceof FrameLayout) {

            if(view.getId() == android.R.id.content) {

                return (ViewGroup) view;

            } else {

                fallback = (ViewGroup) view;

            }

        }

        if (view != null) {

            final ViewParent parent = view.getParent();

            view = parent instanceof View ? (View) parent : null;

        }

    } while (view != null);

    return fallback;

}

③SnackbarContentLayout

SnackbarContentLayout继承LinearLayout,并实现了BaseTransientBottomBar.ContentViewC allback,包含一个TextView和Button。

design_layout_snackbar_include.xml文件:

<view xmlns:android="http://schemas.andro id.com/apk/res/android"

    class="android.support.design.internal.Sna ckbarContentLayout"

    android:theme="@style/ThemeOverlay.Ap pCompat.Dark"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:layout_gravity="bottom">

    <TextView

        android:id="@+id/snackbar_text"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_weight="1"

        android:paddingTop="@dimen/design_sn ackbar_padding_vertical"

        android:paddingBottom="@dimen/desig n_snackbar_padding_vertical"

        android:paddingLeft="@dimen/design_sn ackbar_padding_horizontal"

        android:paddingRight="@dimen/design_s nackbar_padding_horizontal"

        android:textAppearance="@style/TextAp pearance.Design.Snackbar.Message"

        android:maxLines="@integer/design_sna ckbar_text_max_lines"

        android:layout_gravity="center_vertical| left|start"

        android:ellipsize="end"

        android:textAlignment="viewStart"/>

        <Button

        android:id="@+id/snackbar_action"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_marginLeft="@dimen/de sign_snackbar_extra_spacing_horizontal"

        android:layout_marginStart="@dimen/de sign_snackbar_extra_spacing_horizontal"

        android:layout_gravity="center_vertical| right|end"

        android:minWidth="48dp"

        android:visibility="gone"

        android:textColor="?attr/colorAccent"

        style="?attr/borderlessButtonStyle"/>

</view>

④SnackbarManager类

SnackbarManager用来管理Snackbar控件的状态。

Snackbar的show()方法会调用SnackbarManager的show(int, Callback)方法,而mManagerCallback会回调Snackbar的showView()和hideView(int)方法。

static {

    sHandler = new Handler( Looper.getMainLooper(), new Handler.Callback() {

        @Override

        public boolean handleMessage(Message message) {

            switch (message.what) {

                case MSG_SHOW:

                    ((BaseTransientBottomBar) message.obj).showView();

                    return true;

                case MSG_DISMISS:

                    ((BaseTransientBottomBar) message.obj).hideView(message.arg1);

                    return true;

            }

            return false;

        }

    });

}

final SnackbarManager.Callback mManagerCallback = new SnackbarManager.Callback() {

    @Override

    public void show() {

        sHandler.sendMessage( sHandler.obtainMessage(MSG_SHOW, BaseTransientBottomBar.this));

    }

    @Override

    public void dismiss(int event) {

        sHandler.sendMessage( sHandler.obtainMessage(MSG_DISMISS, event, 0, BaseTransientBottomBar.this));

    }

};

public void show() {

    SnackbarManager.getInstance().show( mDuration, mManagerCallback);

}

SnackbarManager内部包含两个记录mCurrentSnackbar和mNextSnackbar。在SnackbarManager的show(int, Callback)方法中,①查看是否是当前Snackbar,如果是,更新超时时间,结束。②查看是否是NextSnackbar,如果是,更新数据,如果不是创建新的NextSnackbar。③取消当前Snackbar或者显示NextSnackbar。

⑤show(int, Callback)方法

public void show(int duration, Callback callback) {

    synchronized (mLock) {

        if (isCurrentSnackbarLocked(callback)) {

            // 如果是当前Snackbar,更新duration和超时提示

            mCurrentSnackbar.duration = duration;

            mHandler.removeCallbacksAndMessag es( mCurrentSnackbar);

            scheduleTimeoutLocked( mCurrentSnackbar);

            return;

        } else if (isNextSnackbarLocked(callback)){

            // 如果是NextSnackbar,更新duration

            mNextSnackbar.duration = duration;

        } else {

            // 否则就创建新的NextSnackbar

            mNextSnackbar = new SnackbarRecord(duration, callback);

        }

        if (mCurrentSnackbar != null && cancelSnackbarLocked(mCurrentSnackbar, Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE)) {

            // 如果当前Snackbar存在,取消显示当前Snackbar                

            return;

        } else {                

            mCurrentSnackbar = null;

            // 如果当前Snackbar不存在,显示NextSnackbar

            showNextSnackbarLocked();

        }

    }

}

// 取消显示当前Snackbar,调用callback的dismiss(DISMISS_EVENT_CONSECUTIVE)方法

private boolean cancelSnackbarLocked( SnackbarRecord record, int event) {

    final Callback callback = record.callback.get();

    if (callback != null) {

        mHandler.removeCallbacksAndMessages( record);

        callback.dismiss(event);

        return true;

    }

    return false;

}

private boolean isCurrentSnackbarLocked( Callback callback) {

    return mCurrentSnackbar != null && mCurrentSnackbar.isSnackbar(callback);

}

private boolean isNextSnackbarLocked( Callback callback) {

    return mNextSnackbar != null && mNextSnackbar.isSnackbar(callback);

}

// 更新超时提示

private void scheduleTimeoutLocked( SnackbarRecord r) {

    if (r.duration == Snackbar.LENGTH_INDEFINITE) {

        return;

    }

    int durationMs = LONG_DURATION_MS;

    if (r.duration > 0) {

        durationMs = r.duration;

    } else if (r.duration == Snackbar.LENGTH_SHORT) {

        durationMs = SHORT_DURATION_MS;

    }

    mHandler.removeCallbacksAndMessages(r);

    mHandler.sendMessageDelayed( Message.obtain(mHandler, MSG_TIMEOUT, r), durationMs);

}

// 显示NextSnackbar,调用callback的show方法

private void showNextSnackbarLocked() {

    if (mNextSnackbar != null) {

        mCurrentSnackbar = mNextSnackbar;

        mNextSnackbar = null;

        final Callback callback = mCurrentSnackbar.callback.get();

        if (callback != null) {

            callback.show();

        } else {

            mCurrentSnackbar = null;

        }

    }

}

Snackbar的showView()会调用onViewShown(),hideView(int)会调用onViewHidden(int):

final void showView() {

    ... ...

    if (shouldAnimate()) {

        // If animations are enabled, animate it in

        animateViewIn();

    } else {

        // Else if anims are disabled just call back now

        onViewShown();

    }

    ... ...

}

final void hideView(final int event) {

    if (shouldAnimate() && mView.getVisibility() == View.VISIBLE) {

        animateViewOut(event);

    } else {

        // If anims are disabled or the view isn't visible, just call back now

        onViewHidden(event);

    }

}

void onViewShown() {

    SnackbarManager.getInstance().onShown( mManagerCallback);

}

void onViewHidden(int event) {    

    SnackbarManager.getInstance().onDismi ssed(mManagerCallback);

}

SnackbarManager的onShown(Callback)和onDismissed(Callback)方法:

public void onShown(Callback callback) {

    synchronized (mLock) {

        if (isCurrentSnackbarLocked(callback)) {

            scheduleTimeoutLocked( mCurrentSnackbar);

        }

    }

}

public void onDismissed(Callback callback) {

    synchronized (mLock) {

        if (isCurrentSnackbarLocked(callback)) {

            // If the callback is from a Snackbar currently show, remove it and show a new one

            mCurrentSnackbar = null;

            if (mNextSnackbar != null) {

                showNextSnackbarLocked();

            }

        }

    }

}

 

相关文章:

Android Snackbar

1.Snackbar Snackbar是Material Design中的一个控件&#xff0c;用来代替Toast。Snackbar是一个类似Toast的快速弹出消息提示的控件。Snackbar在显示上比Toast丰富&#xff0c;而且提供了用户交互的接口。 ①默认情况下&#xff0c;Snackbar显示在屏幕底部&#xff0c;它出现…...

详解API接口如何安全的传输数据(内附商品详情API接口接入方式)

概述 API接口的安全传输是确保数据在API请求和响应之间的传输过程中不被截获、篡改或泄露的重要步骤。以下是一些用于增强API接口安全传输的常见技术和最佳实践&#xff1a; 使用HTTPS&#xff1a;使用HTTPS协议而不是HTTP&#xff0c;以确保数据在传输过程中的安全性。HTTPS使…...

网工内推 | 大专以上,福利待遇好,IE认证优先(云厂商)

01 主动脉科技有限公司 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1.负责云计算&#xff0c;IDC&#xff0c;BGP网络&#xff0c;通过团队协作&#xff0c;构建云业务后台技术支持服务体系。 2.通过工单、其他通讯工具等线上方式完成对客户的实施售后支持&#x…...

Python time strptime()和strftime()

1 strptime()方法 根据指定的格式把一个时间字符串解析为时间元组 重要的时间日期格式化符号 %y 两位数的年份表示&#xff08;00-99&#xff09; %Y 四位数的年份表示&#xff08;000-9999&#xff09; %m 月份&#xff08;01-12&#xff09; %d 月内中的一天&#xff08;0-…...

是谁家班主任还不知道 怎么发布期中成绩啊。

你知道吗&#xff1f;居然还有班主任不知道怎么发布期中成绩&#xff01; 发布成绩并不是一件难事&#xff0c;只需几个步骤&#xff0c;就能轻松搞定&#xff01; 给大家讲一下成绩查询是什么。成绩查询是指学生通过一定的方式&#xff0c;如输入学号、姓名等&#xff0c;在指…...

损失函数(Loss Function)一文详解-聚类问题常见损失函数Python代码实现+计算原理解析

损失函数(Loss Function)一文详解-聚类问题常见损失函数Python代码实现计算原理解析 前言 损失函数无疑是机器学习和深度学习效果验证的核心检验功能&#xff0c;用于评估模型预测值与实际值之间的差异。我们学习机器学习和深度学习或多或少都接触到了损失函数&#xff0c;但…...

测试用例设计方法 —— 场景法详解

场景法是通过运用场景来对系统的功能点或业务流程的描述&#xff0c;从而提高测试效果的一种方法。 场景法一般包含基本流和备用流&#xff0c;从一个流程开始&#xff0c;通过描述经过的路径来确定的过程&#xff0c;经过遍历所有的基本流和备用流来完成整个场景。 场景主要…...

el-table表格设置——动态修改表头

(1) 首先是form表单写表单设置按钮&#xff1a; &#xff08;1.1&#xff09;使用el-popover&#xff0c;你需要修改的是this.colOptions&#xff0c;colSelect: <el-popover id"popover" popper-class"planProver" placement"bottom" width&…...

京东数据分析:2023年9月京东洗地机行业品牌销售排行榜

鲸参谋监测的京东平台9月份洗地机市场销售数据已出炉&#xff01; 9月份&#xff0c;洗地机市场的销售额增长。根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;9月京东平台上洗地机的销量为9.2万&#xff0c;销售额将近2.2亿&#xff0c;同比增长约9%。从价格上看&#…...

使用 TensorFlow SSD 网络进行对象检测

使用 TensorFlow SSD 网络进行对象检测 目录 描述这个示例是如何工作的&#xff1f; 处理输入图准备数据sampleUffSSD 插件验证输出TensorRT API 层和操作 先决条件运行示例 示例 --help 选项 附加资源许可证更改日志已知问题 描述 该示例 sampleUffSSD 预处理 TensorFlow …...

(2)STM32单片机上位机

使用VX小程序开发上位机&#xff0c; 样式如何创建&#xff1f; 在你所在页面 开辟空间 使用 view 在view 中 输入class 就是样式&#xff0c;在编辑样式的时候&#xff0c;如何寻找哪一块的样式 就是通过这个class寻找的 按钮使用switch...

从InnoDB索引的数据结构,去理解索引

从InnoDB索引的数据结构&#xff0c;去理解索引 1、InnoDB 中的 BTree1.1、BTree 的组成1.2、BTree中的数据页 2、聚簇索引2.1、聚簇索引的特点2.2、聚簇索引的结构示例2.3、聚簇索引的优缺点 3、非聚簇索引3.1、非聚簇索引结构示例3.2、关于回表3.3、聚簇索引和非聚簇索引的区…...

Nacos:动态服务发现与配置管理的终极解决方案

今天我想和大家分享一下Nacos&#xff0c;这是一个由阿里巴巴开源的动态服务发现、配置和服务管理平台。我将详细介绍Nacos的主要特性&#xff0c;并通过实例来演示如何使用它。同时&#xff0c;我还会指出Nacos的优点&#xff0c;希望这篇文章能够帮助大家更好地理解和使用Nac…...

易思无人值守智能物流系统Sys_ReportFile文件上传漏洞复现

文章目录 易思无人值守智能物流系统Sys_ReportFile文件上传漏洞复现0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 易思无人值守智能物流系统Sys_ReportFile文件上传漏洞复现 0x01 前言 免责声明&#xff1a;请…...

java Map List转化,通过Map保存数据,通过List排序。取前三名

java Map List转化&#xff0c;通过Map保存数据&#xff0c;通过List排序。取前三名 package yo;import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map;public class a {public static void …...

LEECODE 1480一维数组的动态和

class Solution { public:vector<int> runningSum(vector<int>& nums) {vector<int> runningSum;int sum 0;int len nums.size();for(int i 0; i < len; i){sum sum nums[i];runningSum.push_back(sum);}return runningSum;} };...

python文档链接

python与并行计算...

HTTP调试代理工具/Proxyman

Proxyman专为开发人员和网络爱好者设计&#xff0c;它允许用户拦截、查看和修改所有传入和传出的网络请求&#xff0c;并提供详细的分析和调试功能。 Proxyman支持HTTP、HTTPS和WebSocket协议&#xff0c;因此&#xff0c;可以轻松捕获和查看这些协议下的网络流量。用户可以使…...

搭建Qt5.7.1+kylinV10开发环境、运行环境

1.下载Qt源码 Index of / 2.编译Qt 解压缩qt-everywhere-opensource-src-5.7.1.tar.gz 进入到qt-everywhere-opensource-src-5.7.1/qtbase/mkspecs这个目录下&#xff0c; 2.1找到以下目录 复制他&#xff0c;然后改名linux-x86-arrch64&#xff0c;博主这里名字取的有些问…...

Ceph:关于Ceph 中创建和管理自定义 CRUSH Map

写在前面 准备考试&#xff0c;整理 Ceph 相关笔记博文内容涉及&#xff0c;管理和定制CRUSH Map以及管理OSD Map理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff0c;永不停息。所…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗&#xff1f; 在ComfyUI中实现图生视频并延长到5秒&#xff0c;需要结合多个扩展和技巧。以下是完整解决方案&#xff1a; 核心工作流配置&#xff08;24fps下5秒120帧&#xff09; #mermaid-svg-yP…...