android - 如何实现应用程序范围的搜索栏?
问题描述
在标题中拥有一个应用程序范围的搜索栏似乎是一项非常常见的任务。不幸的是,我还没有找到一些关于如何以正确方式完成它的现成食谱。我的解决方案是使用headerTitle在 React Native Navigation 标头中放置一个自定义SearchBox组件:
static navigationOptions = ({navigation}) => {
headerTitle: () => (<SearchBox ... />)
它有其缺点,例如使用“静态”变量在应用程序和组件之间传递状态和行为。但它到目前为止工作。现在,在迁移到 RNN 4.1.1 后,由于 RNN 中如何实现标头的具体细节,它停止了工作:
TextInput 现在不填充标题的宽度并且不正确处理文本输入。
我正在寻找一种在 RN 中实现应用程序范围的搜索栏的方法,它具有以下属性:
- 它出现在应用程序范围内;
- 其内容可由想要执行搜索的用户修改;
- 当用户导航返回时,其内容符合显示的页面(例如,如果用户在页面 A 上键入查询,然后被重定向到页面 B,那么当他们返回页面 A 时,搜索框包含“页面 A”而不是他们输入的查询);
- 它支持建议(这也是一件棘手的事情)。
更新
理想情况下,我正在寻找具有以下方面的答案:
- 特定于 React Navigation v5;
- 说明搜索栏本身是如何实现的(例如,在上述场景中通过header属性作为组件传递);
- 展示搜索栏在以下场景中如何与核心应用程序通信:
- 用户提交查询;
- 搜索框查询独立于应用程序更新(例如,用户点击 TouchableOpacity 并导航到新页面);
- 如何在导航过程中保证查询的一致性。例如,当用户返回上一个屏幕时,搜索栏中的查询应该与屏幕内容匹配。
- 如何实施建议(用户可以在键入时看到他们的选项;选项从远程源在线加载)。
解决方案
你几乎完成了,但不幸的是,我认为这在 react-navigation 4 中是不可能的。在最新的 5.0 中,现在已经可以生产了,你必须重写你的堆栈。
在 5.0 中,您可以使用useFocusEffect很好地检测Back Actions。所以,你的标题是这样的:
function SearchBar(props) {
return (
<TextInput />
);
}
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ headerTitle: props => <SearchBar {...props} /> }}
/>
</Stack.Navigator>
);
}
问题是,您必须在每个屏幕上重复选项和 useFocusEffect 逻辑。
另一种方法可能是:
- 全局禁用所有标头
- 在所有屏幕中,创建如下布局:
<View style={{ flex: 1 }}>
<MyAppbarHeader title={'PageA'} resetOnBack={false/true} />
<View style={{ flex: 1, margin: 8 }}>
<FlatList
data={someDataOnMyScreen}
renderItem={renderItem}
/>
</View>
</View>
您可以将标题作为MyAppbarHeader
道具传递,以及其他道具(如 resetOnBack)并在此功能组件中实现逻辑。
推荐阅读
- amazon-web-services - 现有 VPC 中 s3 的云形成模板
- c# - Xamarin Forms Release apk 安装时禁用了打开按钮并消失了
- sql - 在 BIML 中连接到 Firebird 数据库
- laravel - 使用 updateOrCreate 方法的 Laravel 计划作业
- java - 运行“brew cask install 采用openjdk/openjdk/adoptopenjdk8”时出现自制错误
- java - 如何创建纹理以覆盖在增强面网格上?
- android - 有没有办法将 var toyList 设计为 LiveData
- > 在 ViewModel 中?
- javascript - Dialogflow - 使用 MySQL 实现 webhook
- javascript - 在类变量 JavaScript 上设置 getter/setter
- nlp - 使用corenlp在句子中标记变量?