Androidでは、すべてのView
サブクラスにView
オブジェクトの可視性を変更できるsetVisibility()
メソッドがあります
可視性の設定には3つのオプションがあります。
View
をレイアウト内に表示しますView
を非表示にしますが、View
が表示されている場合に占有するのと同等のギャップを残しますView
を非表示にし、レイアウトから完全に削除します。 height
とwidth
が0dp
であるかのようにFlutterのウィジェットに上記と同等のものはありますか?
クイックリファレンス: https://developer.Android.com/reference/Android/view/View.html#attr_Android:visibility
更新:この回答が書かれて以来、 Visibility
が導入され、この問題に対する最善の解決策が提供されました。
opacity:
の0.0
でOpacity
を使用して、要素を非表示にするがスペースを占有して描画することができます。
スペースを占有しないようにするには、空のContainer()
に置き換えます。
編集:Opacityオブジェクトにラップするには、次の操作を行います。
new Opacity(opacity: 0.0, child: new Padding(
padding: const EdgeInsets.only(
left: 16.0,
),
child: new Icon(pencil, color: CupertinoColors.activeBlue),
))
不透明度に関するGoogle Developersクイックチュートリアル: https://youtu.be/9hltevOHQBw
Invisible:ウィジェットは画面上の物理的なスペースを占有しますが、ユーザーには見えません。
Gone:ウィジェットは物理的なスペースを取らず、完全になくなっています。
目に見えない例
Visibility(
child: Text("Invisible"),
maintainSize: true,
maintainAnimation: true,
maintainState: true,
visible: false,
),
過去の例
Visibility(
child: Text("Gone"),
visible: false,
),
Dart 2.2以降、if
条件を使用できるようになりました。例:
Column(
children: <Widget>[
if (shouldShow) Text("This can be visible/not depending on condition"),
Text("This is always visible"),
],
)
質問と協力して、空のContainer()
で置き換える例を示します。
以下に例を示します。
import "package:flutter/material.Dart";
void main() {
runApp(new ControlleApp());
}
class ControlleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "My App",
home: new HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
HomePageState createState() => new HomePageState();
}
class HomePageState extends State<HomePage> {
bool visibilityTag = false;
bool visibilityObs = false;
void _changed(bool visibility, String field) {
setState(() {
if (field == "tag"){
visibilityTag = visibility;
}
if (field == "obs"){
visibilityObs = visibility;
}
});
}
@override
Widget build(BuildContext context){
return new Scaffold(
appBar: new AppBar(backgroundColor: new Color(0xFF26C6DA)),
body: new ListView(
children: <Widget>[
new Container(
margin: new EdgeInsets.all(20.0),
child: new FlutterLogo(size: 100.0, colors: Colors.blue),
),
new Container(
margin: new EdgeInsets.only(left: 16.0, right: 16.0),
child: new Column(
children: <Widget>[
visibilityObs ? new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new Expanded(
flex: 11,
child: new TextField(
maxLines: 1,
style: Theme.of(context).textTheme.title,
decoration: new InputDecoration(
labelText: "Observation",
isDense: true
),
),
),
new Expanded(
flex: 1,
child: new IconButton(
color: Colors.grey[400],
icon: const Icon(Icons.cancel, size: 22.0,),
onPressed: () {
_changed(false, "obs");
},
),
),
],
) : new Container(),
visibilityTag ? new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new Expanded(
flex: 11,
child: new TextField(
maxLines: 1,
style: Theme.of(context).textTheme.title,
decoration: new InputDecoration(
labelText: "Tags",
isDense: true
),
),
),
new Expanded(
flex: 1,
child: new IconButton(
color: Colors.grey[400],
icon: const Icon(Icons.cancel, size: 22.0,),
onPressed: () {
_changed(false, "tag");
},
),
),
],
) : new Container(),
],
)
),
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new InkWell(
onTap: () {
visibilityObs ? null : _changed(true, "obs");
},
child: new Container(
margin: new EdgeInsets.only(top: 16.0),
child: new Column(
children: <Widget>[
new Icon(Icons.comment, color: visibilityObs ? Colors.grey[400] : Colors.grey[600]),
new Container(
margin: const EdgeInsets.only(top: 8.0),
child: new Text(
"Observation",
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: visibilityObs ? Colors.grey[400] : Colors.grey[600],
),
),
),
],
),
)
),
new SizedBox(width: 24.0),
new InkWell(
onTap: () {
visibilityTag ? null : _changed(true, "tag");
},
child: new Container(
margin: new EdgeInsets.only(top: 16.0),
child: new Column(
children: <Widget>[
new Icon(Icons.local_offer, color: visibilityTag ? Colors.grey[400] : Colors.grey[600]),
new Container(
margin: const EdgeInsets.only(top: 8.0),
child: new Text(
"Tags",
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: visibilityTag ? Colors.grey[400] : Colors.grey[600],
),
),
),
],
),
)
),
],
)
],
)
);
}
}
Flutterに Visibility Widget が含まれるようになりました。これはウィジェットの表示/非表示に使用する必要があります。ウィジェットを使用して、置換を変更することで2つのウィジェットを切り替えることもできます。
このウィジェットは、表示、非表示、非表示などの状態を実現できます。
Visibility(
visible: true //Default is true,
child: Text('Ndini uya uya'),
//maintainSize: bool. When true this is equivalent to invisible;
//replacement: Widget. Defaults to Sizedbox.shrink, 0x0
),
flutter 1.5およびDart 2.では、可視性がなくなったため、コンテナを使用せずにコレクション内でifステートメントを使用して可視性を設定できます。
例
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('This is text one'),
if (_isVisible) Text('can be hidden or shown'), // no dummy container/ternary needed
Text('This is another text'),
RaisedButton(child: Text('show/hide'), onPressed: (){
setState(() {
_isVisible = !_isVisible;
});
},)
],
)
属性offstage:trueが物理空間を占有せず、表示されない場合は「Offstage」ウィジェットを試してください。属性offstage:falseが物理空間を占有し表示される場合は
Offstage(offstage:true、子:Text( "Visible")、)、
Flutterに Visibility ウィジェットが追加されました。独自のソリューションを実装するには、以下のコードから始めます。
自分でウィジェットを作成します。
class ShowWhen extends StatelessWidget {
final Widget child;
final bool condition;
ShowWhen({this.child, this.condition});
@override
Widget build(BuildContext context) {
return Opacity(opacity: this.condition ? 1.0 : 0.0, child: this.child);
}
}
class RenderWhen extends StatelessWidget {
final Widget child;
final bool condition;
RenderWhen({this.child, this.show});
@override
Widget build(BuildContext context) {
return this.condition ? this.child : Container();
}
}
ところで、上記のウィジェットにはもっと良い名前がありますか?
bool _visible = false;
void _toggle() {
setState(() {
_visible = !_visible;
});
}
onPressed: _toggle,
Visibility(
visible:_visible,
child: new Container(
child: new Container(
padding: EdgeInsets.fromLTRB(15.0, 0.0, 15.0, 10.0),
child: new Material(
elevation: 10.0,
borderRadius: BorderRadius.circular(25.0),
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Search for brands and products', border: InputBorder.none,),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(icon: new Icon(Icons.cancel), onPressed: () {
controller.clear();
onSearchTextChanged('');
},),
),
),
),
),
),
初心者のためにこれも試してください。
class Visibility extends StatefulWidget {
@override
_VisibilityState createState() => _VisibilityState();
}
class _VisibilityState extends State<Visibility> {
bool a = true;
String mText = "Press to hide";
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "Visibility",
home: new Scaffold(
body: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new RaisedButton(
onPressed: _visibilitymethod, child: new Text(mText),),
a == true ? new Container(
width: 300.0,
height: 300.0,
color: Colors.red,
) : new Container(),
],
)
),
);
}
void _visibilitymethod() {
setState(() {
if (a) {
a = false;
mText = "Press to show";
} else {
a = true;
mText = "Press to hide";
}
});
}
}
@CopsOnRoadで既に強調されているように、Visibilityウィジェットを使用できます。ただし、ビューページャーを構築し、ページに基づいて特定のボタンを表示および非表示にする場合など、その状態を保持する場合は、この方法で実行できます
void checkVisibilityButton() {
setState(() {
isVisibileNextBtn = indexPage + 1 < pages.length;
});
}
Stack(children: <Widget>[
PageView.builder(
itemCount: pages.length,
onPageChanged: (index) {
indexPage = index;
checkVisibilityButton();
},
itemBuilder: (context, index) {
return pages[index];
},
controller: controller,
),
Container(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Visibility(
visible: isVisibileNextBtn == true ? true : false,
child: "your widget"
)
],
),
)
]))