Flutter-Container详解

概述

Container是一个拥有绘制、定位、调整大小的 widget,是开发中最常用、最基础的组件。虽然最基础但不可小觑,熟悉每一个属性可以帮助我们更好更快的实现想要的效果,避免走弯路,也能避免代码冗余。本文主要针对其属性进行讲解。

属性

  Container({
    Key? key,
    this.alignment,
    this.padding,
    this.color,
    this.decoration,
    this.foregroundDecoration,
    double? width,
    double? height,
    BoxConstraints? constraints,
    this.margin,
    this.transform,
    this.transformAlignment,
    this.child,
    this.clipBehavior = Clip.none,
  })
key

key用于控制控件如何取代树中的另一个控件,即若widget指定了相同的key,则这些widget可以复用。 如果widget的key值不为空,会判断key._currentElement值所指向的widget,和当前widget的类型key都相同,那么就从旧的父节点上移除,作为当前的节点的子widget之一, 否则将进行真实的创建新的Element。若开发中对组建的复用没有较高要求,一般不设置该属性。

继续阅读Flutter-Container详解

Riverpod AsyncNotifier 的用法

Riverpod AsyncNotifier may sound a litle confusing if you are just coming to Riverpod. After all Riverpod and the latest versions they introduced many concepts. AsyncNotifier works with AsyncNotifierProvider. AsyncNotifier is a wrapper around your state or data which works asyncronomously(await and async).

继续阅读Riverpod AsyncNotifier 的用法

WordPress通过自带的Thickbox实现简单的弹出窗口

One simple way of enabling pop-up windows right from your WordPress posts, is by using the Thickbox javascript library that comes with WordPress.

You can link the pop-up window to a HTML input element such as a button, or you can simply link the pop-up window to a HTML hyperlink. Below we show examples of both –

Show Thickbox Example Pop-up 2

How to Add Pop-up Windows to Your WordPress Posts

Step 1

You need to add thickbox to your WordPress post. You can do this by adding the add_thickbox function to the ‘init’ function of your theme. In particular, add the code below to your theme functions.php file.

<?php
add_action('init', 'init_theme_method');
 
function init_theme_method() {
   add_thickbox();
}
?>
Step 2

Now we can just add the button right in our post and link it to thickbox by specifying class=thickbox. Click on the HTML tab in your post editor and paste the HTML code below into your post.

<div style="text-align:center;padding:20px 0;"> 
<input alt="#TB_inline?height=300&width=400&inlineId=examplePopup1" title="add a caption to title attribute / or leave blank" class="thickbox" type="button" value="Show Thickbox Example Pop-up 1" />  
</div>
Step 3

Finally, we specify the content that goes into our pop-up window by creating a div with id=examplePopup1.

<div id="examplePopup1" style="display:none">
<h2>Example Pop-up Window 1</h2>
<div style="float:left;padding:10px;">
<img src="https://shibashake.com/wordpress-theme/wp-content/uploads/2010/03/bio1.jpg"  width="150" height = "168"/>
</div>
I was born at DAZ Studio. They created me with utmost care and that is why I am the hottie that you see today. My interests include posing, trying out cute outfits, and more posing.
 
<select name=""><option>test</option></select>
 
<strong>Just click outside the pop-up to close it.</strong>
</div>


<strong>Just click outside the pop-up to close it.</strong>
</div>

And just like that, we have our pop-up window.

There are a variety of other thickbox options including using iframes, displaying image galleries, and using AJAX content.

Only Include Thickbox as Necessary

While the example above works, it is not the most efficient because you are including the thickbox library into all of your WordPress posts, whether you are using it or not.

Ideally, you only want to include thickbox in those posts that actually require it.

One way to achieve this is by using the is_single or is_page WordPress functions to include thickbox on a post by post basis.

add_action('template_redirect', 'add_scripts');
 
function add_scripts() {
    if (is_single('2794')) {
      add_thickbox(); 
    }
}

Line 1 – Instead of tying the add_thickbox function to the init action hook, we tie it to the template_redirect action hook instead. This will allow us to properly use the is_single and is_page commands in our hook function.

Lines 4-6 – Only add thickbox to this post which has an id of 2794.

Include Thickbox Based on Post Tags

The solution above works well if you want to include pop-up windows to a small set of posts and pages. However, if you later decide to use pop-ups on a large set of posts, using is_single may quickly become unwieldy.

While you can pass in an array of posts to the is_single function, you will still need to list out the title or id of each and every post that uses thickbox.

A more elegent solution, is to include the thickbox libraries based on post tags.

<?php
function add_scripts() {
    global $wp_query;
    if (!is_singular() || !$wp_query->post) return;
    // Get post tags
    $tags = wp_get_object_terms($wp_query->post->ID, 'post_tag');
    foreach ($tags as $tag) {
        if ($tag->name == "thickbox") {
            add_thickbox();
            break;
        }
    }   
}
?>

Line 4 – We only add thickbox for single posts, pages, or attachments.

Line 6 – Get the post tags for the current post.
*Note*, we cannot used WordPress Loop functions at this point because the template_redirect action hook is called before the Loop is fully instantiated. However, query_vars has already been called, so the $wp_query global variable contains the values that we need.

Lines 7-12 – Check for the thickbox tag. If we find it, we add the thickbox library.

Now all we need to do is add the thickbox tag to posts that use the thickbox library and we are done.

参考链接


Coping with the TCP TIME-WAIT state on busy Linux servers

TL;DR

Do not enable net.ipv4.tcp_tw_recycle—it doesn’t even exist anymore since Linux 4.12. Most of the time, TIME-WAIT sockets are harmless. Otherwise, jump to the summary for the recommended solutions.

The Linux kernel documentation is not very helpful about what net.ipv4.tcp_tw_recycle and net.ipv4.tcp_tw_reuse do. This lack of documentation opens the path to numerous tuning guides advising to set both these settings to 1 to reduce the number of entries in the TIME-WAIT state. However, as stated by the tcp(7) manual page, the net.ipv4.tcp_tw_recycle option is quite problematic for public-facing servers as it won’t handle connections from two different computers behind the same NAT device, which is a problem hard to detect and waiting to bite you:

Enable fast recycling of TIME-WAIT sockets. Enabling this option is not recommended since this causes problems when wrking with NAT (Network Address Translation).

I will provide here a more detailed explanation of how to properly handle the TIME-WAIT state. Also, keep in mind we are looking at the TCP stack of Linux. This is completely unrelated to Netfilter connection tracking which may be tweaked in other ways.1

继续阅读Coping with the TCP TIME-WAIT state on busy Linux servers

在Windows下像Linux一样安装程序 -- winget

用户可以在 Windows 10 和 Windows 11 计算机上使用 winget 命令行工具来发现、安装、升级、删除和配置应用程序。 此工具是 Windows 程序包管理器服务的客户端接口。

安装 winget

Windows 程序包管理器 winget 命令行工具作为应用安装程序的一部分在 Windows 11 和现代版本的 Windows 10 上提供。

可以从 Microsoft Store 获取应用安装程序。 如果已安装,请确保已将其更新为最新版本。

 备注

winget 命令行工具仅在 Windows 10 1709(版本 16299)或更高版本上受支持。 在你首次以用户身份登录 Windows(这会触发 Microsoft Store 将 Windows 程序包管理器注册为异步进程的一部分)之前,winget 工具不可用。 如果最近已经以用户身份进行了首次登录,但发现 winget 尚不可用,则可以打开 PowerShell 并输入以下命令来请求此 winget 注册:Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe

安装 winget 预览版 [仅限开发人员]

WinGet 包含在 Windows 应用安装程序中。 要试用最新的 Windows 程序包管理器功能,可以通过以下方式之一安装预览版:

  • 下载最新的 winget 预览版。 阅读 winget 预览版发行说明,了解任何新功能。 安装此包将为你提供 WinGet 客户端预览版,但它不会从 Microsoft Store 中启用新预览版的自动更新。

  • 使用 Microsoft 帐户 (MSA)、工作、学校或 Azure Active Directory (AAD) 帐户注册 Windows 预览体验成员开发频道。 Windows 预览体验成员开发频道包括 Microsoft Store 中新预览版的自动更新。

  • 使用 Microsoft 帐户 (MSA) 注册 Windows 程序包管理器预览体验计划。 在添加你的 Microsoft 帐户 (MSA) 后(在你收到电子邮件通知后几天),你将收到 Microsoft Store 中新预览版的自动更新。

在 Windows 沙盒上安装 winget

Windows 沙盒提供了一个轻型桌面环境,可以安全地独立运行应用程序。 安装在 Windows 沙盒环境中的软件保持“沙盒”状态,并独立于主机运行。 Windows 沙盒不包含 winget,也不包含 Microsoft Store 应用,因此你需要从 GitHub 上的 winget 版本页下载最新的 winget 包。

要在 Windows 沙盒上安装 winget 的稳定版本,请从 Windows PowerShell 命令提示符执行以下步骤:

$progressPreference = 'silentlyContinue'
Write-Information "Downloading WinGet and its dependencies..."
Invoke-WebRequest -Uri https://aka.ms/getwinget -OutFile Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle
Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx -OutFile Microsoft.VCLibs.x64.14.00.Desktop.appx
Invoke-WebRequest -Uri https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.7.3/Microsoft.UI.Xaml.2.7.x64.appx -OutFile Microsoft.UI.Xaml.2.7.x64.appx
Add-AppxPackage Microsoft.VCLibs.x64.14.00.Desktop.appx
Add-AppxPackage Microsoft.UI.Xaml.2.7.x64.appx
Add-AppxPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle

如果需要程序包管理器的预览版或其他版本,请转到 https://github.com/microsoft/winget-cli/releases。 复制你需要的版本 URL 并更新上述 URI。

有关 Windows 沙盒的详细信息,包括如何安装沙盒以及使用沙盒的预期结果,请参阅 Windows 沙盒文档

管理员注意事项

安装程序的行为可能会有所不同,具体取决于你是否是以管理员权限运行 winget

  • 在没有管理员权限的情况下运行 winget 时,某些应用程序可能会要求提升权限才能进行安装。 当安装程序运行时,Windows 会提示你提升权限。 如果你选择不提升权限,则应用程序无法进行安装。

  • 在管理员命令提示符下运行 winget 时,如果应用程序要求你提升权限,你不会看到提升权限提示。 以管理员身份运行命令提示符时请务必小心,仅安装你信任的应用程序。

继续阅读在Windows下像Linux一样安装程序 -- winget

Flutter问题记录:runApp的时候报错:连接超时

问题:Launching lib\main.dart on ELE AL00 in debug mode...

Running Gradle task 'assembleDebug'...
Exception in thread "main" java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:666)
at sun.security.ssl.BaseSSLSocketImpl.connect(BaseSSLSocketImpl.java:173)
at sun.net.NetworkClient.doConnect(NetworkClient.java:180)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:264)
at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:367)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
at org.gradle.wrapper.Download.downloadInternal(Download.java:58)
at org.gradle.wrapper.Download.download(Download.java:44)
at org.gradle.wrapper.Install$1.call(Install.java:61)
at org.gradle.wrapper.Install$1.call(Install.java:48)
at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:65)
at org.gradle.wrapper.Install.createDist(Install.java:48)
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:128)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:61)
Exception: Gradle task assembleDebug failed with exit code 1

解决方案:

1、调整项目空间中的gradle-wrapper.properties文件中的URL,改为你本地最新的gradle版本就好

如:

distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

2、调整Android包中的build.gradle文件中的kotlin版本号:跟本地kotlin版本同步就行

如:ext.kotlin_version = '1.3.50'

参考链接


Flutter问题记录:runApp的时候报错:连接超时

MacBook Pro 2023-Apple M2 Pro使用Fn按键作为标准功能键

在按下某个功能键的同时按住功能 (Fn)/地球键。例如,同时按下 Fn 和 F12(扬声器图标)可执行分配给 F12 键的操作,而不是提高扬声器的音量1。如果你的键盘没有 Fn 键,请尝试在按下某个功能键的同时按住 Control 键。

更改按键的默认行为

如果你要更改顶行按键以使它们在无需按住 Fn 键的情况下用作标准功能键,请按照以下步骤操作,具体取决于你使用的 macOS 版本

macOS Ventura
  1. 选取苹果菜单  >“系统设置”。

  2. 点按边栏中的“键盘”。

  3. 点按右侧的“键盘快捷键”按钮。

  4. 点按边栏中的“功能键”。

  5. 打开“将 F1、F2 等键用作标准功能键”2

更低版本的 macOS
  1. 选取苹果菜单  >“系统偏好设置”。

  2. 点按“键盘”。

  3. 选择“将 F1、F2 等键用作标准功能键”2

参考链接


使用按键作为标准功能键

升级Flutter 3.13.x 之后出现watcher-1.0.2报错

Failed to build intl_utils:generate:
../../../.pub-cache/hosted/pub.flutter-io.cn/watcher-1.0.2/lib/src/constructable_file_system_event.dart:7:57: Error: The class 'FileSystemEvent' can't be extended, implemented, or mixed in outside of its library because it's a sealed class.
abstract class _ConstructableFileSystemEvent implements FileSystemEvent {

请尝试

dart pub upgrade

命令,如果还是报错

dart pub cache repair

这样我们就可以使用到最新的watcher-1.1.0版本,就不会出现上面这个报错了。

参考链接


GNOME 46 桌面环境加入 RDP 协议支持,今年 3 月起 Linux 发行版用户远程登录更轻松

外媒 Phoronix 报道,GNOME 桌面环境在最近合并的 PR 中获得了远程桌面协议(RDP)支持,预计相关特性将集成至 2024 年 3 月发布的 GNOME 46 版本中,届时 Linux 发行版用户能够更方便地使用 RDP 软件远程访问桌面环境。

Written by Michael Larabel in GNOME on 6 January 2024 at 01:16 PM EST. 58 Comments

After the merge request was open since August of 2022, merged today is support within the GNOME Remote Desktop code for handling graphical remote log-ins.

The merge request by Joan Torres finishes an important piece of the Remote Desktop Protocol (RDP) support for the GNOME desktop with allowing graphical remote logins. Torres explained in that merge request:
"The standard daemon now is abstracted and two new behaviours are implemented:

- Running as a system service (AKA daemon-system):
Started with --system option. It is started as gnome-remote-desktop user. On a new RDP connection it requests GDM to start a RemoteDisplay with a headless GDM greeter session. When a new RemoteDisplay iface from GDM is exported it will register a handover iface to handover the RDP client to the session on this RemoteDisplay. It handovers RDP clients between sessions using these handover ifaces (See the commit descriptions for more info).

- Running on a headless user session (AKA daemon-handover):
Started with --handover option. This daemon is attached as a service on greeter or user headless sessions. It will tell daemon-system using the handover dbus iface to start the handover, and daemon-system will proceed with the handover process. This daemon gets the RDP socket connection from the daemon-system.

- The standard daemon now is daemon-user."

这项 RDP 功能同时支持 X.Org 与 Wayland 显示服务器协议,可作为系统服务运行,也可在无 header 用户会话中运行,从而为 GNOME 桌面环境实现 GUI 远程桌面能力。

继续阅读GNOME 46 桌面环境加入 RDP 协议支持,今年 3 月起 Linux 发行版用户远程登录更轻松

Flutter Provider状态管理---八种提供者使用分析

前言

在我们上一篇文章中对Provider进行了介绍以及类结构的说明,最后还写了一个简单的示例,通过上一章节我们对Provider有了一个基本的了解,这一章节我们来说说Provider的8种提供者以及他们的使用区别。

Provider

Provider是最基本的Provider组件,可以使用它为组件树中的任何位置提供值,但是当该值更改的时候,它并不会更新UI,下面我们给出一个示例

第一步:创建模型
class UserModel {

  String name = "Jimi";

  void changeName() {
    name = "hello";
  }
}
第二步:应用程序入口设置
return Provider<UserModel>(
  create: (_) => UserModel(),
  child: MaterialApp(
    debugShowCheckedModeBanner: false,
    home: ProviderExample(),
  ),
);
第三步:使用共享数据

关于Consumer后面将消费者在提及,我们这里只需要知道有两个消费者,第一个用于展示模型的数据,第二个用于改变模型的数据。

  • 第一个Comsumer是用于读取模型的数据name
  • 第二个Consumer用于改变模型的数据name
import 'package:flutter/material.dart';
import 'package:flutter_provider_example/provider_example/user_model.dart';
import 'package:provider/provider.dart';

class ProviderExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ProviderExample"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Consumer<UserModel>(
              builder: (_, userModel, child) {
                return Text(userModel.name,
                    style: TextStyle(
                        color: Colors.red,
                        fontSize: 30
                    )
                );
              },
            ),
            Consumer<UserModel>(
              builder: (_, userModel, child) {
                return Padding(
                  padding: EdgeInsets.all(20),
                  child: ElevatedButton(
                    onPressed: (){
                      userModel.changeName();
                    },
                    child: Text("改变值"),
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

继续阅读Flutter Provider状态管理---八种提供者使用分析