从我阅读的内容来看,这应该是可能的,但我无法完全实现它。我在Stack
的{{1}}里面有一个bottom
,在appBar
里面有一个Positioned
列表。一切似乎都按预期放置,但是Stack
正在裁剪列表,因此如果appBar
和appBar
的内容在列表的顶部不显示。
我是Flutter的新手,但是在HTML的世界中,我将拥有一个绝对定位的列表,并且appBar将使用高于主体的z-index进行固定,以实现分层效果。
我尝试了很多变体,但似乎appBar想要种植它的孩子。任何帮助将不胜感激。
这是一段代码:
body
更新#1
return new Scaffold(
appBar: new AppBar(
title: new Row(
children: <Widget>[
new Padding(
padding: new EdgeInsets.only(
right: 10.0,
),
child: new Icon(Icons.shopping_basket),
),
new Text(appTitle)
],
),
bottom: new PreferredSize(
preferredSize: const Size.fromHeight(30.0),
child: new Padding(
padding: new EdgeInsets.only(
bottom: 10.0,
left: 10.0,
right: 10.0,
),
child: new AutoCompleteInput(
key: new ObjectKey('$completionList'),
completionList: completionList,
hintText: 'Add Item',
onSubmit: _addListItem,
),
),
),
),
答案 0 :(得分:1)
我从未测试过,但是AppBar具有flexibleSpace
属性,该属性将小部件作为参数。该小部件放置在AppBar顶部(标题所在的位置)和AppBar底部之间的空间中。如果将窗口小部件放置在此空间中而不是AppBar的底部(应仅用于TabBars之类的窗口小部件)的底部,则您的应用程序可能会正常运行。
另一种可能的解决方案是将列表元素放在DropdownButton中,而不是放在堆栈中。
您可以在AppBar here上找到更多信息。
编辑:您还可以考虑在使用搜索时使用脚手架主体显示建议。
此外,您可能会发现PopupMenuButton的源代码对于解决您的问题很有用(因为它的工作方式与建议框相似)。这是一个片段:
void showButtonMenu() {
final RenderBox button = context.findRenderObject();
final RenderBox overlay = Overlay.of(context).context.findRenderObject();
final RelativeRect position = new RelativeRect.fromRect(
new Rect.fromPoints(
button.localToGlobal(Offset.zero, ancestor: overlay),
button.localToGlobal(button.size.bottomRight(Offset.zero), ancestor: overlay),
),
Offset.zero & overlay.size,
);
showMenu<T>(
context: context,
elevation: widget.elevation,
items: widget.itemBuilder(context),
initialValue: widget.initialValue,
position: position,
)
.then<void>((T newValue) {
if (!mounted)
return null;
if (newValue == null) {
if (widget.onCanceled != null)
widget.onCanceled();
return null;
}
if (widget.onSelected != null)
widget.onSelected(newValue);
});
}
答案 1 :(得分:1)
您将无法使用Positioned
小部件将某些内容绝对定位在剪辑之外。 (AppBar要求此剪辑遵循材料规范,因此它可能不会更改)。
如果您需要将某些东西放置在其所构建的窗口小部件的边界之外,那么您需要一个Overlay
。叠加层本身是由MaterialApp
中的导航器创建的,因此您可以将新元素放入其中。使用Overlay
的其他一些小部件是工具提示和弹出菜单,因此您可以根据需要查看它们的实现以获取更多启发。
final OverlayEntry entry = new OverlayEntry(builder: (BuildContext context) => /* ... */)
Overlay.of(context, debugRequiredFor: widget).insert(_entry);
答案 2 :(得分:0)
我认为AppBar的空间有限。并在AppBar中放置列表是一个坏习惯。
答案 3 :(得分:0)
创建了一个示例文件,演示了我的想法(至少与此问题相关)。希望它可以使其他人免于不必要的麻烦。
using System;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
IStuff IStuff = new DerivedClass1("data1 here");
IStuff.DoStuff(); // prints "1: data here"
IStuff = new DerivedClass2("data2 here");
IStuff.DoStuff(); // prints "1: data here"
Console.ReadKey();
}
public class BaseClass
{
public BaseClass(string data)
{
Data = data;
}
public string Data { get; set; }
}
// Interface for derived Classes:
public interface IStuff
{
void DoStuff();
}
// Derived Classes:
// (Don't have own Properties besides the ones they get from BaseClass and
// no other Methods than they have to implement from IStuff)
public class DerivedClass1 : BaseClass, IStuff
{
public DerivedClass1(string data) : base(data)
{
}
public void DoStuff()
{
Console.WriteLine($"1: {Data}");
}
}
public class DerivedClass2 : BaseClass, IStuff
{
public DerivedClass2(string data) : base(data)
{
}
public void DoStuff()
{
Console.WriteLine($"2: {Data}");
}
}
//UnknownType GetDerivedClass(BaseClass baseClass, int value)
//{
// switch (value)
// {
// case 1:
// return baseClass as DerivedClass1;
// case 2:
// return baseClass as DerivedClass2;
// default:
// return null;
// }
//}
//var value = 1;
}
}