我正在嘗試基于 bool 為搜索欄的 TextField 寬度設定影片isSearching。我最初使用 AnimatedContainer,如果isSearching為假,則寬度設定為 350,如果isSearching為真,則設定為 300。搜索時,我需要在 TextField 的右側出現一個“取消”按鈕。在較大的手機尺寸 (iPhone 13) 上使用 350 和 300 效果很好,但在較小的螢屏尺寸 (iPhone 13 mini) 上進行測驗時會出現渲染溢位。
這是我的班級設定:
class _ExplorePageState extends ConsumerState<ExplorePage> {
bool _isSearching = false;
bool _cancelVisibility = false;
late TextEditingController _searchController;
late FocusNode _focusNode;
double _searchFieldSize = 350;
Future<void> toggleCancelButton() async {
await Future.delayed(
const Duration(milliseconds: 400),
() {
setState(() {
_cancelVisibility = true;
});
},
);
}
@override
void initState() {
_searchController = TextEditingController();
_focusNode = FocusNode();
_focusNode.addListener(() {
if (_focusNode.hasFocus || _isSearching) {
_searchFieldSize = 300;
setState(() {
_isSearching = true;
toggleCancelButton();
});
} else {
_searchFieldSize = 350;
setState(() {
_isSearching = false;
_cancelVisibility = false;
_focusNode.unfocus();
});
}
});
super.initState();
}
@override
void dispose() {
super.dispose();
_focusNode.dispose();
_searchController.dispose();
}
AnimatedContainer這是我要制作影片的行所在的行:
SizedBox(
width: MediaQuery.of(context).size.width,
child: Row(
children: [
const SizedBox(width: defaultMargin),
AnimatedContainer(
duration: const Duration(milliseconds: 350),
width: _searchFieldSize,
child: TextField(
focusNode: _focusNode,
controller: _searchController,
autofocus: false,
autocorrect: false,
style:
Theme.of(context).textTheme.bodySmall!.copyWith(
color: isDark
? darkThemeDefaultTextColor
: lightThemeDefaultTextColor,
),
decoration: InputDecoration(
prefixIcon: Icon(
Ionicons.search_outline,
color: isDark
? darkThemeSubTextColor
: lightThemeSubTextColor,
size: 16,
),
suffixIcon: _cancelVisibility
? IconButton(
icon: Icon(
Ionicons.close_circle_outline,
size: 18,
color: isDark
? darkThemeSubTextColor
: lightThemeSubTextColor,
),
onPressed: () {
_searchController.clear();
ref
.read(explorePageControllerProvider
.notifier)
.clearAll();
setState(() {});
},
)
: null,
hintStyle: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
color: isDark
? darkThemeSubTextColor
: lightThemeSubTextColor,
),
hintText: 'Search (character, village)',
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 8.0, top: 8.0),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: isDark
? darkThemeSubTextColor
: lightThemeSubTextColor,
),
borderRadius: BorderRadius.circular(15),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: isDark
? darkThemeSubTextColor
: lightThemeSubTextColor,
),
borderRadius: BorderRadius.circular(15),
),
),
onChanged: (value) async {
if (_searchController.value.text.isEmpty) {
ref
.read(
explorePageControllerProvider.notifier)
.clearAll();
} else {
await ref
.read(
explorePageControllerProvider.notifier)
.getSearchResults(value);
}
setState(() {});
},
),
),
Visibility(
visible: _cancelVisibility,
child: TextButton(
style: ButtonStyle(
overlayColor:
MaterialStateProperty.all(Colors.transparent),
),
onPressed: () {
_searchController.clear();
_focusNode.unfocus();
setState(() {
_isSearching = false;
_cancelVisibility = false;
_searchFieldSize = 350;
});
},
child: Text(
'cancel',
style: Theme.of(context).textTheme.bodySmall,
),
),
),
],
),
),
為了適應較小的手機尺寸,我通常會使用它來設定寬度,但我需要在運行構建之前MediaQuery處理內部的寬度。initState
有沒有辦法做到這一點,AnimatedContainer或者我應該使用不同的方法來為搜索欄設定影片?
uj5u.com熱心網友回復:
我不確定這是否可行,但你可以試試這個:
// You should try to estimate the width of the cancel button (Space it will take)
//As i think it is constant across mobile devices.
Say the width of your Cancel button is 50,
var initialWidth = MediaQuery.of(context).size.width; // without cancel button
AnimatedContainer(
duration: const Duration(milliseconds: 350),
width: !isSearching ? initialWidth: initialWidth - 50 ,
child: TextField()), TextButton(child:Text("Cancel"),onPressed(){})
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/506582.html
上一篇:如何將CSS計時與JS間隔同步?
