u
This commit is contained in:
1 parent
68a834dd18
commit
a52e73fbba
9 files changed
+163
-49
No files matched your search
@@ -22,7 +22,8 @@
|
|||||||
"backgroundColor": "#ffffff"
|
"backgroundColor": "#ffffff"
|
||||||
},
|
},
|
||||||
"edgeToEdgeEnabled": true,
|
"edgeToEdgeEnabled": true,
|
||||||
"predictiveBackGestureEnabled": false
|
"predictiveBackGestureEnabled": false,
|
||||||
|
"package": "com.oneao.baseapp"
|
||||||
},
|
},
|
||||||
"web": {
|
"web": {
|
||||||
"favicon": "./assets/favicon.png"
|
"favicon": "./assets/favicon.png"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
"main": "expo-router/entry",
|
"main": "expo-router/entry",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "expo start",
|
"start": "expo start",
|
||||||
"android": "expo start --android",
|
"android": "expo run:android",
|
||||||
"ios": "expo start --ios",
|
"ios": "expo run:ios",
|
||||||
"web": "expo start --web"
|
"web": "expo start --web"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,39 +1,68 @@
|
|||||||
import React, { useState } from 'react'
|
import React from 'react'
|
||||||
import { KeyboardAvoidingView, Platform, StyleSheet, View } from 'react-native'
|
import {
|
||||||
import { KeyboardProvider } from 'react-native-keyboard-controller'
|
StyleSheet,
|
||||||
import { AInput } from '@/components/common/ao'
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
View,
|
||||||
|
} from 'react-native'
|
||||||
|
import { KeyboardAvoidingView } from 'react-native-keyboard-controller'
|
||||||
|
|
||||||
export default function MyInput() {
|
export default function KeyboardAvoidingViewExample() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.content}>
|
<KeyboardAvoidingView
|
||||||
<View style={styles.topSpace} />
|
behavior="padding"
|
||||||
|
keyboardVerticalOffset={100}
|
||||||
{/* 输入框 */}
|
style={styles.content}
|
||||||
<View style={styles.inputWrapper}>
|
>
|
||||||
<AInput
|
<View style={styles.inner}>
|
||||||
value=""
|
<Text style={styles.heading}>Header</Text>
|
||||||
placeholder="备注"
|
<View>
|
||||||
className="bg-[#f2f3f5] border-0"
|
<TextInput placeholder="Username" style={styles.textInput} />
|
||||||
size="sm"
|
<TextInput placeholder="Password" style={styles.textInput} />
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
|
<TouchableOpacity style={styles.button}>
|
||||||
|
<Text style={styles.text}>Submit</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
</KeyboardAvoidingView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
content: {
|
content: {
|
||||||
|
flex: 1,
|
||||||
|
maxHeight: 600,
|
||||||
|
},
|
||||||
|
heading: {
|
||||||
|
fontSize: 36,
|
||||||
|
marginBottom: 48,
|
||||||
|
fontWeight: '600',
|
||||||
|
},
|
||||||
|
inner: {
|
||||||
|
padding: 24,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
},
|
},
|
||||||
topSpace: {
|
textInput: {
|
||||||
flex: 1,
|
height: 45,
|
||||||
|
borderColor: '#000000',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 10,
|
||||||
|
marginBottom: 36,
|
||||||
|
paddingLeft: 10,
|
||||||
},
|
},
|
||||||
inputWrapper: {
|
button: {
|
||||||
marginHorizontal: 16,
|
marginTop: 12,
|
||||||
marginBottom: 20,
|
height: 45,
|
||||||
|
borderRadius: 10,
|
||||||
|
backgroundColor: 'rgb(40, 64, 147)',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
fontWeight: '500',
|
||||||
|
fontSize: 16,
|
||||||
|
color: 'white',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import type { KeyboardEvent } from 'react-native'
|
||||||
|
import React, { useEffect, useRef } from 'react'
|
||||||
|
import { Animated, Keyboard, Platform } from 'react-native'
|
||||||
|
|
||||||
|
interface BottomSectionProps {
|
||||||
|
children: React.ReactNode
|
||||||
|
safeMargin?: number // 输入框距离键盘的安全距离
|
||||||
|
}
|
||||||
|
|
||||||
|
const BottomSection: React.FC<BottomSectionProps> = ({ children, safeMargin = 8 }) => {
|
||||||
|
const translateY = useRef(new Animated.Value(0)).current
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const onKeyboardShow = (e: KeyboardEvent) => {
|
||||||
|
const keyboardHeight = e.endCoordinates.height
|
||||||
|
console.log(keyboardHeight)
|
||||||
|
Animated.timing(translateY, {
|
||||||
|
toValue: -(keyboardHeight - safeMargin),
|
||||||
|
duration: e.duration ?? 250,
|
||||||
|
useNativeDriver: true,
|
||||||
|
}).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onKeyboardHide = (e: KeyboardEvent) => {
|
||||||
|
Animated.timing(translateY, {
|
||||||
|
toValue: 0,
|
||||||
|
duration: e.duration ?? 250,
|
||||||
|
useNativeDriver: true,
|
||||||
|
}).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
const showSub = Keyboard.addListener(
|
||||||
|
Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow',
|
||||||
|
onKeyboardShow,
|
||||||
|
)
|
||||||
|
const hideSub = Keyboard.addListener(
|
||||||
|
Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide',
|
||||||
|
onKeyboardHide,
|
||||||
|
)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
showSub.remove()
|
||||||
|
hideSub.remove()
|
||||||
|
}
|
||||||
|
}, [safeMargin])
|
||||||
|
|
||||||
|
return <Animated.View style={{ transform: [{ translateY }] }}>{children}</Animated.View>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BottomSection
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { MoneyCategoryResult } from '@/request/api/money'
|
import type { MoneyCategoryResult } from '@/request/api/money'
|
||||||
import type { MoneyCategory } from '@/types/money'
|
import type { MoneyCategory } from '@/types/money'
|
||||||
import Big from 'big.js'
|
import Big from 'big.js'
|
||||||
import dayjs from 'dayjs'
|
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { Keyboard, Pressable, StyleSheet, Text, View } from 'react-native'
|
import { Keyboard, Platform, Pressable, StyleSheet, Text, TouchableWithoutFeedback, View } from 'react-native'
|
||||||
|
import { KeyboardProvider } from 'react-native-keyboard-controller'
|
||||||
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||||
import { AInput, LucideIcon } from '@/components/common/ao'
|
import { AInput, LucideIcon } from '@/components/common/ao'
|
||||||
import SegmentedTabs from '@/components/common/ao/SegmentedTabs'
|
import SegmentedTabs from '@/components/common/ao/SegmentedTabs'
|
||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
DrawerHeader,
|
DrawerHeader,
|
||||||
} from '@/components/ui/drawer'
|
} from '@/components/ui/drawer'
|
||||||
import { Grid, GridItem } from '@/components/ui/grid'
|
import { Grid, GridItem } from '@/components/ui/grid'
|
||||||
|
import { useKeyboardHeight } from '@/hooks/useKeyboardHeight'
|
||||||
import { getMoneyCategoryApi } from '@/request/api/money'
|
import { getMoneyCategoryApi } from '@/request/api/money'
|
||||||
import MoneyCategoryIcon from './MoneyCategoryIcon'
|
import MoneyCategoryIcon from './MoneyCategoryIcon'
|
||||||
|
|
||||||
@@ -64,13 +65,13 @@ export default function AddMoneyDrawer({
|
|||||||
const [showKeydown, setShowKeydown] = useState(false)
|
const [showKeydown, setShowKeydown] = useState(false)
|
||||||
const [keydownInput, setKeydownInput] = useState<string>('')
|
const [keydownInput, setKeydownInput] = useState<string>('')
|
||||||
const [result, setResult] = useState('0')
|
const [result, setResult] = useState('0')
|
||||||
const [date, setDate] = useState(dayjs())
|
|
||||||
|
|
||||||
const [categories, setCategories] = useState<MoneyCategoryResult>({
|
const [categories, setCategories] = useState<MoneyCategoryResult>({
|
||||||
income: [],
|
income: [],
|
||||||
expense: [],
|
expense: [],
|
||||||
})
|
})
|
||||||
|
const keyboardHeight = useKeyboardHeight()
|
||||||
|
console.log(keyboardHeight)
|
||||||
function selectCategory(item: MoneyCategory) {
|
function selectCategory(item: MoneyCategory) {
|
||||||
setSelectedCategoryId(item.id)
|
setSelectedCategoryId(item.id)
|
||||||
setShowKeydown(true)
|
setShowKeydown(true)
|
||||||
@@ -299,7 +300,6 @@ export default function AddMoneyDrawer({
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<Drawer
|
<Drawer
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
size="full"
|
size="full"
|
||||||
@@ -307,6 +307,7 @@ export default function AddMoneyDrawer({
|
|||||||
onClose={onMainDrawerClose}
|
onClose={onMainDrawerClose}
|
||||||
>
|
>
|
||||||
<DrawerBackdrop />
|
<DrawerBackdrop />
|
||||||
|
|
||||||
<DrawerContent style={{ padding: 0, flex: 1 }}>
|
<DrawerContent style={{ padding: 0, flex: 1 }}>
|
||||||
<DrawerHeader
|
<DrawerHeader
|
||||||
className="flex items-center justify-between"
|
className="flex items-center justify-between"
|
||||||
@@ -324,7 +325,6 @@ export default function AddMoneyDrawer({
|
|||||||
<Text className="text-gray-500 font-medium">取消</Text>
|
<Text className="text-gray-500 font-medium">取消</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
</DrawerHeader>
|
</DrawerHeader>
|
||||||
|
|
||||||
<DrawerBody style={{ flex: 1, paddingLeft: 16, paddingRight: 16, marginBottom: 0, backgroundColor: '#fff' }}>
|
<DrawerBody style={{ flex: 1, paddingLeft: 16, paddingRight: 16, marginBottom: 0, backgroundColor: '#fff' }}>
|
||||||
<Grid className="gap-4 mb-8" _extra={{ className: 'grid-cols-4' }}>
|
<Grid className="gap-4 mb-8" _extra={{ className: 'grid-cols-4' }}>
|
||||||
{(() => {
|
{(() => {
|
||||||
@@ -366,12 +366,9 @@ export default function AddMoneyDrawer({
|
|||||||
</DrawerBody>
|
</DrawerBody>
|
||||||
|
|
||||||
{showKeydown && (
|
{showKeydown && (
|
||||||
<View style={[{
|
<KeyboardProvider>
|
||||||
backgroundColor: '#fff',
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||||
elevation: 30,
|
<View className="p-4 h-28">
|
||||||
}]}
|
|
||||||
>
|
|
||||||
<View className="p-4">
|
|
||||||
<View className="flex flex-row items-center justify-between">
|
<View className="flex flex-row items-center justify-between">
|
||||||
<Pressable
|
<Pressable
|
||||||
className="flex flex-row items-center gap-1.5 px-2 py-1.5 rounded-md bg-gray-50 active:opacity-70"
|
className="flex flex-row items-center gap-1.5 px-2 py-1.5 rounded-md bg-gray-50 active:opacity-70"
|
||||||
@@ -387,7 +384,7 @@ export default function AddMoneyDrawer({
|
|||||||
|
|
||||||
<AInput
|
<AInput
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
value=""
|
value={keydownInput}
|
||||||
placeholder="备注"
|
placeholder="备注"
|
||||||
className="bg-[#f2f3f5] border-0"
|
className="bg-[#f2f3f5] border-0"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -395,10 +392,8 @@ export default function AddMoneyDrawer({
|
|||||||
onBlur={() => setIsFocused(false)}
|
onBlur={() => setIsFocused(false)}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
</TouchableWithoutFeedback>
|
||||||
{!isFocused && (
|
<View className="flex flex-row flex-wrap" style={{ height: 220 }}>
|
||||||
<View style={{ height: 240 }}>
|
|
||||||
<View className="flex flex-row flex-wrap h-full">
|
|
||||||
{keys.map((item, idx) => {
|
{keys.map((item, idx) => {
|
||||||
const isFirstCol = idx % 4 === 0
|
const isFirstCol = idx % 4 === 0
|
||||||
const isFirstRow = idx < 4
|
const isFirstRow = idx < 4
|
||||||
@@ -441,11 +436,16 @@ export default function AddMoneyDrawer({
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{/* {isFocused && (
|
||||||
|
<View style={{ height:
|
||||||
|
keyboardHeight + 10 - 220 }}
|
||||||
|
>
|
||||||
</View>
|
</View>
|
||||||
|
)} */}
|
||||||
|
</KeyboardProvider>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</DrawerContent>
|
</DrawerContent>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import * as SplashScreen from 'expo-splash-screen'
|
|||||||
import { StatusBar } from 'expo-status-bar'
|
import { StatusBar } from 'expo-status-bar'
|
||||||
import { RefreshCw } from 'lucide-react-native'
|
import { RefreshCw } from 'lucide-react-native'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
import { KeyboardProvider } from 'react-native-keyboard-controller'
|
||||||
import EmptyState from '@/components/common/EmptyStatus'
|
import EmptyState from '@/components/common/EmptyStatus'
|
||||||
import { GluestackUIProvider } from '@/components/ui/gluestack-ui-provider'
|
import { GluestackUIProvider } from '@/components/ui/gluestack-ui-provider'
|
||||||
import { useUserStore } from '@/store/user'
|
import { useUserStore } from '@/store/user'
|
||||||
@@ -52,6 +53,7 @@ export default function RootLayout() {
|
|||||||
}, [fontsLoaded])
|
}, [fontsLoaded])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<KeyboardProvider>
|
||||||
<GluestackUIProvider>
|
<GluestackUIProvider>
|
||||||
<ToastProvider>
|
<ToastProvider>
|
||||||
<ToastProviderWrapper>
|
<ToastProviderWrapper>
|
||||||
@@ -86,5 +88,6 @@ export default function RootLayout() {
|
|||||||
</ToastProviderWrapper>
|
</ToastProviderWrapper>
|
||||||
</ToastProvider>
|
</ToastProvider>
|
||||||
</GluestackUIProvider>
|
</GluestackUIProvider>
|
||||||
|
</KeyboardProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ const AInput = forwardRef<React.ComponentRef<typeof InputField>, AInputProps>(
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<InputField
|
<InputField
|
||||||
ref={ref} // 这里直接传递给 InputField
|
ref={ref}
|
||||||
type={isPassword ? (showPassword ? 'text' : 'password') : 'text'}
|
type={isPassword ? (showPassword ? 'text' : 'password') : 'text'}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import type { KeyboardEvent } from 'react-native'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { Keyboard } from 'react-native'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* useKeyboardHeight - 获取键盘高度的 Hooks
|
||||||
|
* @returns {number} 当前键盘高度,键盘收起时为 0
|
||||||
|
*/
|
||||||
|
export function useKeyboardHeight() {
|
||||||
|
const [keyboardHeight, setKeyboardHeight] = useState(0)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const onKeyboardShow = (e: KeyboardEvent) => {
|
||||||
|
setKeyboardHeight(e.endCoordinates.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onKeyboardHide = () => {
|
||||||
|
setKeyboardHeight(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const showSub = Keyboard.addListener('keyboardDidShow', onKeyboardShow)
|
||||||
|
const hideSub = Keyboard.addListener('keyboardDidHide', onKeyboardHide)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
showSub.remove()
|
||||||
|
hideSub.remove()
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return keyboardHeight
|
||||||
|
}
|
||||||
@@ -30,8 +30,8 @@ function isWhiteListed(url: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const alovaInstance = createAlova({
|
const alovaInstance = createAlova({
|
||||||
baseURL: 'http://192.168.5.6:8085/app',
|
// baseURL: 'http://192.168.5.6:8085/app',
|
||||||
// baseURL: 'http://192.168.1.136:8085/app',
|
baseURL: 'http://192.168.1.136:8085/app',
|
||||||
requestAdapter: axiosRequestAdapter(),
|
requestAdapter: axiosRequestAdapter(),
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
cacheFor: null,
|
cacheFor: null,
|
||||||
|
|||||||
Reference in new issue
Block a user