帥小哥

文章 评论 浏览 28

帥小哥 2025-02-20 22:31:03

该函数的目的是将范围 x_min 映射到 x_max to值 0 2^bits

(int) ((x- x_min) / span * (1<<bits));

但是这里有一些骗局来帮助优化器。最后两个值首先重新主化并计算。从数学上讲是相同的,但是使用浮子将以不同的方式圆形。如此小的差异实际上是一个编译器标志,允许编译器忽略它(快速记录)。

(int) ((x- x_min)    *    ((1<<bits) / span));

施法到 float 是毫无意义的,因为算术促销已经将 1&lt; lt; bits 变成float, float/float/float 仍然 float float < /代码>。

现在您可能会问:这种转变的重点是什么?结果是(大约)相同。

这是我对此的想法:在源中, bits x_min x_max 将是文字或常数。因此, span 在编译时间也已知。转换允许编译器在编译时内线并计算(1&lt;&lt; bits) / span)< / code>。这仅留下一个 float 在运行时减法和乘法。因此,它将生成代码,该代码在没有FPU的Arduino上更快地运行。

The goal of the function is to map values in the range x_min to x_max to values 0 to 2^bits.

(int) ((x- x_min) / span * (1<<bits));

But there is some trickery being used here to help the optimizer. The last two values are re-aranged and computed first. Mathematically it's the same but with floats it will round differently. A difference so minor there is actually a compiler flag allowing the compiler to ignore it (fast-math).

(int) ((x- x_min)    *    ((1<<bits) / span));

The cast to float is pointless as arithmetic promotion already turns 1<<bits into a float and float / float remains float.

Now you might ask: What is the point of this transformation? The result is the (about) the same.

Here is my thought on that: In the source the bits, x_min and x_max will be literals or constants. So span is known at compile time too. The transformation allows the compiler to inline that function and compute (1<<bits) / span) at compile time. That leaves only one float subtraction and multiplication at runtime. It will therefore generate code that runs noticeable faster on something like an Arduino that has no FPU.

谁能向我解释此代码的数学?

帥小哥 2025-02-20 13:50:05

可以通过:

  • 解析命令行参数。
  • 查看该参数是否匹配允许参数的列表。
  • 基于参数列表中的索引中的一系列函数调用函数。

我们可以创建一个包含有效命令行字符串的结构,以及指向相应功能的指针:

typedef void vfunc_t (void);
typedef struct
{
  char*    str;
  vfunc_t* vfunc;
} arg_t;

然后声明此类结构的数组:

const arg_t valid_args [3] = 
{
  [0] = {.str="-V1", .vfunc=v1func },
  [1] = {.str="-V2", .vfunc=v2func },
  [2] = {.str="-V3", .vfunc=v3func },
};

完整示例:

#include <stdio.h>
#include <stdlib.h> 
#include <string.h>

typedef void vfunc_t (void);
typedef struct
{
  char*    str;
  vfunc_t* vfunc;
} arg_t;

// some functions with different behavior:
void v1func (void) { puts(__func__); }
void v2func (void) { puts(__func__); }
void v3func (void) { puts(__func__); }

// callback function to bsearch for our arg_t type:
static int argcmp (const void* o1, const void* o2)
{
  const arg_t* a1 = (const arg_t*)o1;
  const arg_t* a2 = (const arg_t*)o2;
  return strcmp(a1->str, a2->str);
}

int main (int argc, char* argv[])
{
  const arg_t valid_args [3] = 
  {
    [0] = {.str="-V1", .vfunc=v1func },
    [1] = {.str="-V2", .vfunc=v2func },
    [2] = {.str="-V3", .vfunc=v3func },
  };

  if(argc != 2)
  {
    puts("Usage: yadayada...");
    return 0;
  }

  /*
    As the strings are sorted in alphabetic order, bsearch 
    is the most efficient way to find the matching one. 
    Overkill in this simple example, but not when there's 
    hundreds of options.
  */
  arg_t key = {argv[1], NULL };
  arg_t* arg = bsearch(&key, 
                       valid_args, 
                       sizeof valid_args/sizeof *valid_args,
                       sizeof *valid_args,
                       argcmp);
  if(arg == NULL)
  {
    puts("Usage: yadayada...");
    return 0;
  }

  size_t index = arg - valid_args; // pointer arithmetic on the struct array
  vfunc_t* vfunc = valid_args[index].vfunc; // table look-up

  vfunc(); // call the function matching the command-line argument
}

注意:此代码稀疏使用错误处理。考虑添加界限检查,ARGV消毒和类似。

It can be done by:

  • Parse the command line arguments.
  • See if the argument matches the list of allowed arguments.
  • Call a function in an array of functions based on index from the list of arguments.

We can create a struct containing a valid command line string as well as a pointer to the corresponding function:

typedef void vfunc_t (void);
typedef struct
{
  char*    str;
  vfunc_t* vfunc;
} arg_t;

Then declare an array of such structs:

const arg_t valid_args [3] = 
{
  [0] = {.str="-V1", .vfunc=v1func },
  [1] = {.str="-V2", .vfunc=v2func },
  [2] = {.str="-V3", .vfunc=v3func },
};

Full example:

#include <stdio.h>
#include <stdlib.h> 
#include <string.h>

typedef void vfunc_t (void);
typedef struct
{
  char*    str;
  vfunc_t* vfunc;
} arg_t;

// some functions with different behavior:
void v1func (void) { puts(__func__); }
void v2func (void) { puts(__func__); }
void v3func (void) { puts(__func__); }

// callback function to bsearch for our arg_t type:
static int argcmp (const void* o1, const void* o2)
{
  const arg_t* a1 = (const arg_t*)o1;
  const arg_t* a2 = (const arg_t*)o2;
  return strcmp(a1->str, a2->str);
}

int main (int argc, char* argv[])
{
  const arg_t valid_args [3] = 
  {
    [0] = {.str="-V1", .vfunc=v1func },
    [1] = {.str="-V2", .vfunc=v2func },
    [2] = {.str="-V3", .vfunc=v3func },
  };

  if(argc != 2)
  {
    puts("Usage: yadayada...");
    return 0;
  }

  /*
    As the strings are sorted in alphabetic order, bsearch 
    is the most efficient way to find the matching one. 
    Overkill in this simple example, but not when there's 
    hundreds of options.
  */
  arg_t key = {argv[1], NULL };
  arg_t* arg = bsearch(&key, 
                       valid_args, 
                       sizeof valid_args/sizeof *valid_args,
                       sizeof *valid_args,
                       argcmp);
  if(arg == NULL)
  {
    puts("Usage: yadayada...");
    return 0;
  }

  size_t index = arg - valid_args; // pointer arithmetic on the struct array
  vfunc_t* vfunc = valid_args[index].vfunc; // table look-up

  vfunc(); // call the function matching the command-line argument
}

Note: This code is sparse with error handling. Consider adding bounds checks, argv sanitizing and similar.

C代表输入更改功能的行为

帥小哥 2025-02-20 12:54:58

将Cassandra 2.2.19群集直接升级到最新的3.11版本并不是一个问题。

不需要分手升级到C* 4.X-升级节点根本不是问题。您需要关注的是您是否需要升级所使用的驱动程序。

如果您确实需要升级驱动程序,则需要对应用程序进行重构,如果驱动程序的新版本与旧版本不兼容。例如,从java驱动程序3.x升级到4.x有破坏性的更改(请参阅 Java驱动程序V4升级指南)。

在升级群集之前,请确保您熟悉各种版本的升级说明:

It isn't an issue upgrading a Cassandra 2.2.19 cluster directly to the latest 3.11 release.

There is no requirement to have a break to upgrade to C* 4.x -- upgrading the nodes isn't going to be an issue at all. What you need to be concerned with is whether you need to upgrade the driver you're using.

If you do need to upgrade the driver, you need to refactor your application if the new version of the driver is not binary-compatible with the old version. For example, upgrading from Java driver 3.x to 4.x has breaking changes (see the Java driver v4 Upgrade Guide for details).

Before upgrading your cluster, make sure you familiarise yourself with the upgrade instructions for the various releases:

是否可以将Cassandra 2.2.19直接升级到3.11?

帥小哥 2025-02-20 08:28:50

在spartacus 4.3.x中:

您应该能够注入特殊令牌 cartitemcontext 喜欢此示例组件

而且,您可能对阅读 cartitemcontext.item $ 尤其感兴趣,它具有类型可观察到的ordertry&lt; orderentry&gt;

注意:从版本4.3.x开始,他 cartitemcontext 仅在默认组件 cartitemcomponent 。

In Spartacus 4.3.x:

You should be able to inject the special token CartItemContext like in this example component.

And you might be interested especially in reading the CartItemContext.item$, which has type Observable<OrderEntry>.

Note: As of version 4.3.x, he CartItemContext token is provided only inside the default component CartItemComponent.

如何在spartacus中注入订购的序列上下文。ITEM_DETAILS

帥小哥 2025-02-20 03:03:57

在您的ViewDetailRecord方法中,使用异步任务代替void,并以等待的方式调用buildurl方法。

使用如下:

private static async Task ViewDetailRecord()    
{      
    var obj = await _linkPlus.BuildUrl();  
     .....Your codes..............  
}

In your ViewDetailRecord method, use async Task instead of void and call the buildURL method with await.

Use like below:

private static async Task ViewDetailRecord()    
{      
    var obj = await _linkPlus.BuildUrl();  
     .....Your codes..............  
}

如何在静态方法中使用非静态异步方法?

帥小哥 2025-02-19 06:14:36

当您执行作业默认 tribdeadline 值,根据此问题。

如果您想手动运行它,我建议您从并通过 - 代码> 带有所需值的标志,如此答案:

gcloud beta scheduler jobs update http <job> --attempt-deadline=1800s --project <project>

When you execute a job from the GUI, it will be executed using the default attemptDeadline value, which is 60 seconds according to this question.

If you want to run it manually, I suggest to run the job from the Cloud Shell and pass the --attempt-deadline flag with the desired value, as shown on this answer:

gcloud beta scheduler jobs update http <job> --attempt-deadline=1800s --project <project>

为什么Google Cloud Scheduler不尊重dundeDeadline

帥小哥 2025-02-18 15:08:53

tldr;

简而言之:不,似乎没有一种基于扩展数据类型的元数据信息在AX 2009中自动创建表关系的方法。

扩展数据数据库中的类型指出:

从Microsoft Dynamics AX 2012开始,您不再可以在AOT中的EDT元素下定义关系。

请注意,AX 2012和D365FO中的扩展数据类型仍显示一个关系节点。这是为了向后兼容,仍然允许与关系的标准扩展数据类型。但是对于新的扩展数据类型,无法定义关系。

为什么?

那么,为什么微软会删除这种定义关系的方式呢?
可以在迁移扩展数据类型关系(白皮书)。在引言中,白皮书说:

EDT下的表关系
有一些缺点:

  • 它们不包含富裕关系元数据,例如基数和关系类型,可以
    被包括在表节点下的关系中。
  • 他们只能捕获单个字段关系,这可能不能代表表之间的预期(甚至可能更复杂)的关系。

在EDT和表格下定义的表关系的一个重大困难是
当两个位置定义表关系时,关系顺序很重要。在这种情况下,
内核将使用不同的算法决定首先检查哪种关系,具体取决于
上下文。

“增加关系?”对话框

问题提到对话框时,将扩展数据类型拖动到表的字段节点中,询问用户是否应创建关系。该对话框仍然存在,但是与较早的版本相比,它是针对更少的扩展数据类型提供的(例如,在AX 2012中为 itemID 扩展数据类型提供了D365f,而不是)。
提供或不提供此对话框的条件似乎是扩展数据类型上的表参考设置的组合,以及由扩展数据类型引用的表的主要索引。但是,到目前为止,我只能找到将主索引设置为默认值“替代密钥”的示例,其中提供了对话框。一个这样的示例是扩展数据类型 omdepartmentrecid ,它在D365FO中提供以下对话框:

除了前两个链接

外,我还想提及David Kidder的博客文章: referencencetable&amp; EDT上的表引用(不幸的是缺少图像,我找不到它具有它们的版本)。
它描述了扩展数据类型的表参考设置的各种组合以及结果行为是什么。它还提到“添加关系?”对话框,但至少对于D365FO,该描述不再匹配当前行为。

TLDR;

In short: no, there does not seem to be a way to create table relations automatically like in AX 2009 based on the extended data type's metadata information.

As the warning in Extended Data Types in the Database states:

Starting in Microsoft Dynamics AX 2012, you can no longer define relations under an EDT element in the AOT.

Note that the extended data types in AX 2012 and D365FO still show a relations node. This is for backwards compatibility to still allow standard extended data types with relations. But for new extended data types, no relations can be defined.

Why?

So why would Microsoft remove this way of defining relations?
Some answers can be found in the Migrating Extended Data Type Relations (White paper). In the introduction, the white paper says:

Table relationships under an EDT
have some disadvantages:

  • They do not contain the rich relationship metadata, such as cardinality and relation type, that can
    be included in relations under a table node.
  • They can only capture single field relationships, which might not represent the intended — and possibly more intricate — relationship between the tables.

A significant difficulty with having table relations defined under both an EDT and a table is that the
order of relations matters when table relationships are defined in both locations. In such cases, the
kernel will use different algorithms to decide which relationship to examine first, depending on the
context.

The "Add relation?" dialog

The question mentions a dialog when dragging and dropping an extended data type into the fields node of a table asking the user if a relation should be created. This dialog still exists, but compared with earlier versions, it is offered for fewer extended data types (e.g. in AX 2012 it is offered for the ItemId extended data type, in D365FO it is not).
The conditions under which this dialog is offered or not seem to be a combination of the table reference settings on the extended data type and the primary index of the table that is referenced by the extended data type. However, so far, I was only able to find examples where the primary index is set to the default value "Surrogate key" where the dialog is offered. One such an example is the extended data type OMDepartmentRecId, which offers the following dialog in D365FO:
Add relation dialog

More information

Apart from the previous two links, I would also like to mention a blog article by David Kidder: ReferenceTable & Table References on EDT (images are unfortunately missing and I couldn't find a version of it that has them).
It describes the various combinations of the table reference settings of an extended data type and what the resulting behavior is. It also mentions the "Add relation?" dialog, but at least for D365FO, the description doesn't match the current behavior any more.

AX 365:是否可以自动创建表关系?就像是在AX 2009中吗?

帥小哥 2025-02-18 02:52:17

insert into ( columns1, 2, etc... )
   select * from BaseTable

是您的实际查询吗? *,我希望您明确表示要拉的列。我看到了奇怪的事情,如果桌子结构发生了变化,您是否得到了您真正认为正确的列和与插入期望的序列相同的序列?另外,您没有子句,因此您将整个数据库从一个数据库中拉到存储表中,并且出于什么好处 /目的?

您提到表值函数。那是这个过于广泛的插入语句是什么,还是还有其他上下文,您只是为我们掩盖了它?

Your

insert into ( columns1, 2, etc... )
   select * from BaseTable

Is that your actual query? The *, I would expect you to explicitly indicate the columns you wanted to pull. I have seen weird things if a table structure was altered, are you getting what you really think are the correct columns and same sequence as insert is expecting? Also, you have no WHERE clause, so you are pulling the entire database from one into a memory table and for what benefit / purpose?

You mention a table valued function. Is that what this overly broad insert statement is, or is there some other context to it and you are just masking it for us?

非常慢的查询,没有阻止,不是坏执行计划:为什么?

帥小哥 2025-02-17 17:37:46

这就是错误来自新版本0.69.0
您可以使用 npx React-nitation Init ProjectName - Version 0.68.2 ,然后升至V 0.69。

That is error is from the new version 0.69.0
You can use npx react-native init ProjectName --version 0.68.2 and then upgrade to v 0.69 later.

TypeError:cli.init不是React Native的功能

帥小哥 2025-02-17 16:21:16

您可以首先计算每个“ v1 ”,“” v3 “,” v4 “,” v13 “带有 count 窗口函数的字段。然后与您的原始表一起重新加入,尽管保持数量大于1的行。

WITH cte AS (
    SELECT <your_table_identifier_field(s)>, 
           COUNT(*) OVER(PARTITION BY V1, V3, V4, V13) as cnt 
    FROM table
)
SELECT * 
FROM       tab
INNER JOIN cte
        ON tab.<your_table_identifier_field(s)> = cte.<your_table_identifier_field(s)>
       AND cte.cnt > 1

编辑:如果没有特定的行标识符,该怎么办?然后,您被迫匹配所有列值。

WITH cte AS (
    SELECT *, 
           COUNT(*) OVER(PARTITION BY V1, V3, V4, V13) as cnt 
    FROM table
)
SELECT * 
FROM       tab
INNER JOIN cte
        ON tab.<field1> = cte.<field1>
       AND tab.<field2> = cte.<field2>
       AND ...
       AND cte.cnt > 1

You can do it by first counting how many values you have for each "V1", "V3", "V4", "V13" fields with the COUNT window function. Then join back with your original table, though keeping those rows which have count bigger than 1.

WITH cte AS (
    SELECT <your_table_identifier_field(s)>, 
           COUNT(*) OVER(PARTITION BY V1, V3, V4, V13) as cnt 
    FROM table
)
SELECT * 
FROM       tab
INNER JOIN cte
        ON tab.<your_table_identifier_field(s)> = cte.<your_table_identifier_field(s)>
       AND cte.cnt > 1

EDIT: What if there's no specific row identifier? You're forced to match all column values then.

WITH cte AS (
    SELECT *, 
           COUNT(*) OVER(PARTITION BY V1, V3, V4, V13) as cnt 
    FROM table
)
SELECT * 
FROM       tab
INNER JOIN cte
        ON tab.<field1> = cte.<field1>
       AND tab.<field2> = cte.<field2>
       AND ...
       AND cte.cnt > 1

SQL在行中查找重复值

帥小哥 2025-02-17 08:23:45

这似乎是Eclipse循环分析而不是代码的问题。 Eclipse试图确保通过代码的所有路径关闭资源,但似乎犯了一个错误。

显示该问题的最小代码只是:

Scanner scan = new Scanner(System.in);

int i;
for (i = 0; i < 3; i++)
 {
   //
 }

scan.close();

将其更改为:

Scanner scan = new Scanner(System.in);

for (int i = 0; i < 3; i++)
 {
   //
 }

scan.close();

摆脱错误,因此似乎与 int i 声明有关。

更改代码以使用try-with-resources将是最好的修复:

 try (Scanner scan = new Scanner(System.in))
  {
    ... your code
  }

但是如评论中所述,在 system.in 上关闭扫描仪并不是一个好主意,因为它也将关闭 system.in 。您可以告诉Eclipse不要发出警告:

@SuppressWarnings("resource")
Scanner scan = new Scanner(System.in);

This appears to be a problem with the Eclipse loop analysis rather than your code. Eclipse is trying to make sure all paths through the code close the resource but it seems to have made a mistake.

The minimum code to show the problem is just:

Scanner scan = new Scanner(System.in);

int i;
for (i = 0; i < 3; i++)
 {
   //
 }

scan.close();

Just changing this to:

Scanner scan = new Scanner(System.in);

for (int i = 0; i < 3; i++)
 {
   //
 }

scan.close();

gets rid of the error, so it seems to be something to do with the int i declaration.

Changing the code to use try-with-resources would be the best fix:

 try (Scanner scan = new Scanner(System.in))
  {
    ... your code
  }

But as mentioned in the comments closing a scanner on System.in is not really a good idea as it will also close System.in. You can just tell Eclipse not to generate the warning with:

@SuppressWarnings("resource")
Scanner scan = new Scanner(System.in);

eclipse说扫描仪从未关闭

帥小哥 2025-02-17 06:24:52

在这里,如果您喜欢数字和水平线之间的更多空间,请更改CSS的css。line如{margin:5px 0; }

.kanban-circle {
  border-radius: 50%;
  width: 36px;
  height: 36px;
  padding: 8px;
  background: #fff;
  border: 2px solid #666;
  color: #666;
  text-align: center;
  font: 32px Arial, sans-serif;
  display: flex;
  flex-direction: column;
}

.line {
  padding: 0;
  margin: 0;
  width: 100%
}

span {
  font-size: 15px;
}
<div class="kanban-circle">
  <span>90</span>
  <hr class="line" />
  <span>100
</span></div>

Here it is, if you like more space between the number and the horizontal line, change the css for .line like { margin: 5px 0; }

.kanban-circle {
  border-radius: 50%;
  width: 36px;
  height: 36px;
  padding: 8px;
  background: #fff;
  border: 2px solid #666;
  color: #666;
  text-align: center;
  font: 32px Arial, sans-serif;
  display: flex;
  flex-direction: column;
}

.line {
  padding: 0;
  margin: 0;
  width: 100%
}

span {
  font-size: 15px;
}
<div class="kanban-circle">
  <span>90</span>
  <hr class="line" />
  <span>100
</span></div>

HTML CSS:外交号码除以总数

帥小哥 2025-02-16 22:44:50

您需要通过 x1 x2 一个对象中,请参阅 xdata in

测量数据的自变量。通常应该是
M长度序列或(K,M)形阵列用于K的功能
预测变量,但实际上可以是任何对象。


示例:

import numpy as np
from scipy.optimize import curve_fit

# generate sample data for a1, b1, c1, a2, b2, c2, d = 1, 2, 3, 4, 5, 6, 7
np.random.seed(0)
x1 = np.random.randint(0, 100, 100)
x2 = np.random.randint(0, 100, 100)
y1 = (1 * x1**3 + 2 * x1**2 + 3 * x1) + (4 * x2**3 + 5 * x2**2 + 6 * (x2+np.random.randint(-1, 1, 100))) + 7

def func(x, a1, b1, c1, a2, b2, c2, d):
    return (a1 * x[0]**3 + b1 * x[0]**2 + c1 * x[0]) + (a2 * x[1]**3 + b2 * x[1]**2 + c2 * x[1]) + d

popt, _ = curve_fit(func, np.stack([x1, x2]), y1)

结果:

array([1.00000978, 1.99945039, 2.97065876, 4.00001038, 4.99920966,
       5.97424668, 6.71464229])

You need to pass x1 and x2 in one object, see description of xdata in docs for curve_fit:

The independent variable where the data is measured. Should usually be
an M-length sequence or an (k,M)-shaped array for functions with k
predictors, but can actually be any object.

Example:

import numpy as np
from scipy.optimize import curve_fit

# generate sample data for a1, b1, c1, a2, b2, c2, d = 1, 2, 3, 4, 5, 6, 7
np.random.seed(0)
x1 = np.random.randint(0, 100, 100)
x2 = np.random.randint(0, 100, 100)
y1 = (1 * x1**3 + 2 * x1**2 + 3 * x1) + (4 * x2**3 + 5 * x2**2 + 6 * (x2+np.random.randint(-1, 1, 100))) + 7

def func(x, a1, b1, c1, a2, b2, c2, d):
    return (a1 * x[0]**3 + b1 * x[0]**2 + c1 * x[0]) + (a2 * x[1]**3 + b2 * x[1]**2 + c2 * x[1]) + d

popt, _ = curve_fit(func, np.stack([x1, x2]), y1)

Result:

array([1.00000978, 1.99945039, 2.97065876, 4.00001038, 4.99920966,
       5.97424668, 6.71464229])

Python curve_fit具有多个自变量(以获取某些不知道参数的值)

帥小哥 2025-02-16 21:55:22

您可以写出多行字符串,例如:(

>>> string = (
    'line1\n'
    'line2\n')

像元组一样,但没有逗号),

并且它可以打印

>>> print(string)
line1
line2

您可以正确保留代码标识

You can write your multiline string like:

>>> string = (
    'line1\n'
    'line2\n')

(like a tuple but without commas)

and it prints

>>> print(string)
line1
line2

moreover you can keep your code identation correctly

如何删除文本的段落?

帥小哥 2025-02-16 21:01:18

感谢Vladyslav Ulianytskyi的建议。

我已经使用 rawKeyboardListner 来完成此操作。这是示例代码。

RawKeyboardListener(
    autofocus: true,
    onKey: (event) {
        setState(() {
            if (event.isKeyPressed(LogicalKeyboardKey.backspace)) {
                print("Perform Your Action");
            }
        });
    },
    focusNode: FocusNode(),
    child: TextFormField(controller: bullet2Controller,
        focusNode: focusNode2,
        maxLines: null,
        minLines: 1,
        textCapitalization: TextCapitalization.sentences,
            cursorColor: Colors.black,
            showCursor: true,
            autofocus: true,
            textAlign: TextAlign.start,
            inputFormatters: [LengthLimitingTextInputFormatter(140),
            ],
            decoration: const InputDecoration(
                disabledBorder: InputBorder.none,
                border: InputBorder.none,
                filled: true,
                fillColor: Colors.white,
            ),
            keyboardType: TextInputType.multiline,
            textInputAction: TextInputAction.done,
        ),
    ),
)

Thanks to Vladyslav Ulianytskyi suggestion.

I have done this with the use of RawKEyboardListner. Here is the sample code.

RawKeyboardListener(
    autofocus: true,
    onKey: (event) {
        setState(() {
            if (event.isKeyPressed(LogicalKeyboardKey.backspace)) {
                print("Perform Your Action");
            }
        });
    },
    focusNode: FocusNode(),
    child: TextFormField(controller: bullet2Controller,
        focusNode: focusNode2,
        maxLines: null,
        minLines: 1,
        textCapitalization: TextCapitalization.sentences,
            cursorColor: Colors.black,
            showCursor: true,
            autofocus: true,
            textAlign: TextAlign.start,
            inputFormatters: [LengthLimitingTextInputFormatter(140),
            ],
            decoration: const InputDecoration(
                disabledBorder: InputBorder.none,
                border: InputBorder.none,
                filled: true,
                fillColor: Colors.white,
            ),
            keyboardType: TextInputType.multiline,
            textInputAction: TextInputAction.done,
        ),
    ),
)

当没有角色颤动时,Textformfield on Changed不会被调用

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

更多

友情链接

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文