Input 颤振文本字段小部件下的奇怪红色块
我正在我的Flitter应用程序的一个选项卡中处理购物清单,但在输入字段下,当键盘出现时,我总是会看到奇怪的红色方块(红色方块一直停留在那里,直到键盘消失) 调试报告,单击字段后显示Input 颤振文本字段小部件下的奇怪红色块,input,flutter,Input,Flutter,我正在我的Flitter应用程序的一个选项卡中处理购物清单,但在输入字段下,当键盘出现时,我总是会看到奇怪的红色方块(红色方块一直停留在那里,直到键盘消失) 调试报告,单击字段后显示 Performing full restart... Restarted app in 1.172ms. D/ViewRootImpl@da3a8cd[MainActivity](28869): ViewPostImeInputStageprocessPointer 0 D/ViewRootImpl@da3a8c
Performing full restart...
Restarted app in 1.172ms.
D/ViewRootImpl@da3a8cd[MainActivity](28869): ViewPostImeInputStageprocessPointer 0
D/ViewRootImpl@da3a8cd[MainActivity](28869): ViewPostImeInputStageprocessPointer 1
I/flutter (28869): [{name: Lukas, id: 1, value: 32}, {name: Sophie, id: 2, value: 20}, {name: Peter, id: 3, value: 45}]
D/ViewRootImpl@da3a8cd[MainActivity](28869): ViewPostImeInputStage processPointer 0
D/ViewRootImpl@da3a8cd[MainActivity](28869): ViewPostImeInputStage processPointer 1
V/InputMethodManager(28869): Starting input: tba=android.view.inputmethod.EditorInfo@b63ece2 nm : com.yourcompany.flutterapp ic=io.flutter.plugin.editing.InputConnectionAdaptor@484e873
I/InputMethodManager(28869): [IMM] startInputInner - mService.startInputOrWindowGainedFocus
D/InputTransport(28869): Input channel constructed: fd=101
D/InputTransport(28869): Input channel destroyed: fd=100
D/InputMethodManager(28869): ISS - flag : 0Pid : 28869 view : com.yourcompany.flutterapp
D/ViewRootImpl@da3a8cd[MainActivity](28869): MSG_RESIZED: frame=Rect(0, 0 - 1080, 2220) ci=Rect(0, 63 - 0, 918) vi=Rect(0, 63 - 0, 918) or=1
D/ViewRootImpl@da3a8cd[MainActivity](28869): Relayout returned: oldFrame=[0,0][1080,2220] newFrame=[0,0][1080,2220] result=0x1 surface={isValid=true -887126016} surfaceGenerationChanged=false
在这里,您可以看到我编写的代码:
import 'dart:async';
import 'dart:core';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
class ShoppingBasket extends StatefulWidget {
@override
ShoppingBasketState createState() => new ShoppingBasketState();
}
class ShoppingBasketState extends State<ShoppingBasket> {
Directory documentsDirectory;
String dirPath;
Database database;
List<Map> listRecords;
Widget listView;
final TextEditingController _controller1 = new TextEditingController(); // name field
final TextEditingController _controller2 = new TextEditingController(); // value field
@override
void initState() {
listView = beforeDataFetchIsFinished();
getPathAndCheckForDbAndPrepareListView();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Column(
children: <Widget>[
inputFieldCard(),
listView, //--> List view gets after all data was fetched here
],
),
);
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
//View Build ------------------------------------------------------------------------
/// Set the listview variable with an CircularPorgressIndicator.
/// gets overriden if the real listview has finished.
Widget beforeDataFetchIsFinished() {
return new Container(
margin: new EdgeInsets.fromLTRB(0.0, 30.0, 0.0, 0.0),
child: new Center(
child: new CircularProgressIndicator(
strokeWidth: 2.0,
),
),
);
}
/// The Inputfield card in one methode.
/// Returns the InputCard as one widget.
Widget inputFieldCard() {
return new Container(
child: new Card(
child: new Container(
child: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Container(
width: 150.0,
padding: new EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0),
child: new TextField(
controller: _controller1,
decoration: new InputDecoration(
hintText: 'Name...',
),
),
),
new Container(
width: 150.0,
padding: new EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 10.0),
child: new TextField(
keyboardType: TextInputType.number,
controller: _controller2,
decoration: new InputDecoration(
hintText: 'Value...',
),
),
),
],
),
new Container(
padding: new EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 20.0),
child: new RaisedButton(
color: Colors.green,
child: new Text('Insert Data', style: new TextStyle(color: Colors.white),),
onPressed: () {
insertToDb(_controller1.text, _controller2.text);
_controller1.clear();
_controller2.clear();
},
),
),
],
)
),
), //top card end
);
}
/// the CircularProgressIndicator gets overiden if this
/// methode gets all its data --> then rerender.
Widget injectListViewAfterAllDataIsFetched() {
return new Card(
child: new Container(
child: new ListView.builder(
shrinkWrap: true, //<-- Necessary because Listveiw inside Column
itemCount: listRecords == null ? 0 : listRecords.length,
itemBuilder: (BuildContext context, int index) {
return new ListTile(
title: new Text(listRecords[index]['name']),
);
},
),
),
);
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
//Data-Base Operations --------------------------------------------------------------
/// Start up --> Open db and fetching data when complete
/// start render engine again.
Future<bool> getPathAndCheckForDbAndPrepareListView() async {
documentsDirectory = await getApplicationDocumentsDirectory();
String dirPath = documentsDirectory.path;
List content = documentsDirectory.listSync();
final File file = new File(dirPath + '/myDataBase.db');
if(!content.contains(file)) { //Check if db exists
await createDbIfNotExists(file); //if not create it
}
print(await getRecords());
listRecords = await getRecords();
print(listRecords);
setState(() {
listView = injectListViewAfterAllDataIsFetched();
});
return true;
}
/// Inserting data into the data base.
/// @return true.
Future<bool> insertToDb(String name, String value) async {
if(name != '' && value != '') {
var valueSql = int.parse(value);
String sql = 'INSERT INTO Test(name, value) VALUES("$name", $valueSql)';
await database.inTransaction(() async {
await database.rawInsert(sql);
});
listRecords = await getRecords();
setState(() {
listView = injectListViewAfterAllDataIsFetched();
});
return true;
} else {
return false;
}
}
/// Gives the whole Db back.
/// @return Map with all records.
Future<List<Map>> getRecords() async {
return await database.rawQuery('SELECT * FROM Test');
}
/// Creating the given File (should be an .db file).
/// @param file Gives the file (.db) which gets created.
/// @return true.
Future<bool> createDbIfNotExists(File file) async {
database = await openDatabase(file.path, version: 1,
onCreate: (Database db, int version) async {
await db.execute(
"CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER)");
});
return true;
}
}
导入'dart:async';
导入“省道:核心”;
导入“dart:io”;
进口“包装:颤振/材料.省道”;
导入“package:flatter/rendering.dart”;
导入“package:path_provider/path_provider.dart”;
导入“包:sqflite/sqflite.dart”;
类ShoppingBasket扩展StatefulWidget{
@凌驾
ShoppingBasketState createState()=>新建ShoppingBasketState();
}
类ShoppingBasketState扩展了状态{
目录文件目录;
字符串路径;
数据库;
记录清单;
窗口小部件列表视图;
final TextEditingController _controller1=new TextEditingController();//名称字段
final TextEditingController _controller2=new TextEditingController();//值字段
@凌驾
void initState(){
listView=beforeDataFetchIsFinished();
getPathAndCheckForDbAndPrepareListView();
}
@凌驾
小部件构建(构建上下文){
归还新脚手架(
正文:新栏目(
儿童:[
inputFieldCard(),
listView,//-->在此处获取所有数据后获取列表视图
],
),
);
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
//视图构建------------------------------------------------------------------------
///使用CircularProgPressIndicator设置listview变量。
///如果实际listview已完成,则被重写。
DataFetchisFinished()之前的小部件{
退回新货柜(
边距:LTRB(0.0,30.0,0.0,0.0)的新边距集,
孩子:新中心(
儿童:新的循环压缩机指示器(
冲程宽度:2.0,
),
),
);
}
///一种方法中的Inputfield卡。
///将输入卡作为一个小部件返回。
Widget inputFieldCard(){
退回新货柜(
孩子:新卡(
子容器:新容器(
子:新列(
儿童:[
新行(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
新容器(
宽度:150.0,
填充:LTRB(10.0,20.0,10.0,10.0,10.0)的新边缘设置,
孩子:新文本字段(
控制器:_控制器1,
装饰:新的输入装饰(
hintText:'名称…',
),
),
),
新容器(
宽度:150.0,
填充:LTRB(10.0,20.0,10.0,10.0,10.0)的新边缘设置,
孩子:新文本字段(
键盘类型:TextInputType.number,
控制器:_控制器2,
装饰:新的输入装饰(
hintText:“值…”,
),
),
),
],
),
新容器(
填充:来自LTRB(0.0,0.0,0.0,20.0)的新边缘设置,
孩子:新升起的按钮(
颜色:颜色。绿色,
子项:新文本('插入数据',样式:新文本样式(颜色:Colors.white),),
已按下:(){
insertToDb(_controller1.text,_controller2.text);
_控制器1.clear();
_控制器2.clear();
},
),
),
],
)
),
),//顶卡端
);
}
///如果出现以下情况,循环压缩机指示器将被忽略
///methode获取其所有数据-->然后重新加载。
Widget injectListViewAfterAllDataIsFetched(){
归还新卡(
子容器:新容器(
子项:新建ListView.builder(
包覆面提取:true,//打开数据库并在完成时提取数据
///再次启动渲染引擎。
未来的getPathAndCheckForDbAndPrepareListView()异步{
documentsDirectory=等待getApplicationDocumentsDirectory();
字符串dirPath=documentsDirectory.path;
List content=documentsDirectory.listSync();
final File File=新文件(dirPath+'/myDataBase.db');
如果(!content.contains(file)){//检查数据库是否存在
等待createDbIfNotExists(文件);//如果不是,则创建它
}
打印(等待getRecords());
listRecords=等待getRecords();
打印(列表记录);
设置状态(){
listView=injectListViewAfterAllDataIsFetched();
});
返回true;
}
///将数据插入数据库。
///@返回true。
Future insertToDb(字符串名称、字符串值)异步{
如果(名称!=''&&value!=''){
var valueSql=int.parse(值);
字符串sql='插入测试(名称、值)值(“$name”,$valueSql)”;
等待数据库。内部事务(()异步{
wait database.rawisert(sql);
});
listRecords=等待getRecords();
设置状态(){
listView=injectListViewAfterAllDataIsFetched();
});
返回true;
}否则{
返回false;
}
}
///返回整个数据库。
///@返回所有记录的地图。
Future getRecords()异步{
返回wait database.rawQuery('SELECT*fromtest');
}
///创建给定文件(应为.db文件)。
///@param file提供创建的文件(.db)。
///@返回true。
未来的createDbIfNotExists(文件)异步{
database=wait openDatabase(file.path,v