「ブッ」とスマホが振動するような動きをするアプリは多々あります。「カッ」と表現した方が良いかもしれません。この動作を haptic feedback (触覚フィードバック)と呼びます。
Expo + React Native でできたプロジェクトで、 haptic feedback を実現する方法を紹介します。
必要なライブラリのインストール
shell
npx expo install expo-haptics
実装方法
Expo のサンプルそのままで、非常にシンプルに動作します。
Haptic.tsx
Haptics.notificationAsync(
Haptics.NotificationFeedbackType.Error
)
自分の場合は、 React Navigator で「+」のタブをタップしたときに「カクッ」と触覚フィードバックが走るようにしました。
全体のコードを載せます。
TopTabNavigator.tsx
import MemoListScreen from '../screens/MemoListScreen';
import TopTabAddScreen from '../screens/TopTabAddScreen';
import TopTabSettingScreen from '../screens/TopTabSettingScreen';
import { Entypo, SimpleLineIcons } from '@expo/vector-icons';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import * as Haptics from 'expo-haptics';
import { Text } from 'react-native';
const Tab = createMaterialTopTabNavigator();
interface TabScreenProp {
name: string;
tabId: string;
}
const tabScreenProps: TabScreenProp[] = [
{ name: 'TodoList', tabId: '123' },
{ name: 'Memo', tabId: '456' },
{ name: 'Tasks', tabId: '789' },
{ name: '買い物', tabId: '101112' },
{ name: '下書き', tabId: '131415' },
{
name: '長い長いタブの名前はどうなるのかな?',
tabId: '131415',
},
];
export default function TopTabNavigator() {
return (
<Tab.Navigator
screenOptions={{
tabBarScrollEnabled: true,
tabBarItemStyle: { maxWidth: 160 },
}}
>
{tabScreenProps.map((tabScreenProp) => (
<Tab.Screen
key={tabScreenProp.name}
name={tabScreenProp.name}
component={MemoListScreen}
initialParams={{ tabId: tabScreenProp.tabId }}
options={{
tabBarLabel: ({ focused, color }) => (
<Text numberOfLines={1} ellipsizeMode="tail" style={{ color }}>
{tabScreenProp.name}
</Text>
),
}}
/>
))}
<Tab.Screen
key={'add-uuid'}
name={'add-uuid'}
component={TopTabAddScreen}
initialParams={{ tabId: 'add' }}
options={{
tabBarLabel: ({ focused, color }) => <Entypo name="plus" size={24} color={color} />,
}}
listeners={{
tabPress: async (e) => {
await Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
},
}}
/>
<Tab.Screen
key={'setting-uuid'}
name={'setting-uuid'}
component={TopTabSettingScreen}
initialParams={{ tabId: 'add' }}
options={{
tabBarLabel: ({ focused, color }) => (
<SimpleLineIcons
name="settings"
size={24}
color="black"
onPress={async () => {
await Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
}}
/>
),
}}
listeners={{
tabPress: async (e) => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
},
}}
/>
</Tab.Navigator>
);
}
以下の「+」をタップしたときに震えます。
余談ですが、 GPT-4に聞いたら React Navigation で onPress
で動作する機能はありません、みたいに回答があったのですが、普通に検索したら StackOverflow で回答が見つかったので、検索もまだまだ活用しなければなりませんね笑
React Navigation の Tab.Screen をタップしたときに onPress で関数を実行する方法
TabScreen.tsx
<Tab.Screen
name="Settings2"
component={SettingsScreen}
options={{
tabBarButton: props => (
<TouchableOpacity {...props} onPress={() => alert(123)} />
),
}}
/>