土曜日, 5月 24, 2025
ホームニュースChatGPTChatGPT × ReactNativeで作る「読書要約アプリ」開発ノート ~おすすめ機能を作る(その4)~|ヒロヒロ

ChatGPT × ReactNativeで作る「読書要約アプリ」開発ノート ~おすすめ機能を作る(その4)~|ヒロヒロ


オススメ機能の左右スワップ時の処理とレイアウト調整を行う。

動作確認結果

おすすめ機能で、左右スワップ時の処理とレイアウトの設定を行い、
下記の動きとなった。

残対応:オススメの精度が低いので、次作業はChatGPTのチューニング

実際の対応は下記。

実処理

左右スワップ時の処理

onSwipedLeft、onSwipedRightで定義。
最後のインデックスになった場合、画面を閉じるよう設定。

<Swiper cards={books.recommendations} renderCard={recommendation => { return ( <View style={styles.card}> <Image style={styles.bookcover} source={require('../resource/bookcover.png')}></Image> <View style={styles.bookInfo}> : : : onSwipedLeft={(cardIndex: number) => { if (cardIndex === BOOK_CARD_STACK_SIZE - 1) { navigation.goBack(); } }} onSwipedRight={(cardIndex: number) => { saveRecommendBook(books.recommendations[cardIndex]); if (cardIndex === BOOK_CARD_STACK_SIZE - 1) {            navigation.goBack();        }    }}

レイアウトの設定

本の画像をChatGPTから作ってもらい、画像の上にデータを載せる

const BOOK_CARD_STACK_SIZE = 5; export default function RecomendScreen({navigation}: any) { const [books, setBooks] = useState(null); const [bookIndex, setBookIndex] = useState(0); useEffect(() => { const fetchData = async () => { let books = await getBooksHighRating(); let response = await recomendBooksToChatGPT(books); console.log(JSON.parse(response)); setBooks(JSON.parse(response)); }; fetchData(); }, []); return ( <View style={styles.container}> {books ? ( <Swiper cards={books.recommendations} renderCard={recommendation => { return ( <View style={styles.card}> <Image style={styles.bookcover} source={require('../resource/bookcover.png')}></Image> <View style={styles.bookInfo}> <View style={styles.titleArea}> <Text style={styles.title}>{recommendation.title}</Text> </View> <View style={styles.authorArea}> <Text style={styles.author}>{recommendation.author}</Text> </View> <View style={styles.explanationArea}> <Text style={styles.text1}> ジャンル: {recommendation.genre} </Text> <Text style={styles.text2}>{recommendation.reason}</Text> </View> </View> </View> ); }} backgroundColor={'transparent'} cardIndex={bookIndex} onSwipedLeft={(cardIndex: number) => { console.log(cardIndex); if (cardIndex === BOOK_CARD_STACK_SIZE - 1) { navigation.goBack(); } }} onSwipedRight={(cardIndex: number) => { saveRecommendBook(books.recommendations[cardIndex]); console.log(cardIndex); if (cardIndex === BOOK_CARD_STACK_SIZE - 1) { navigation.goBack(); } }} disableBottomSwipe disableTopSwipe useViewOverflow={true} stackSize={BOOK_CARD_STACK_SIZE} animateOverlayLabelsOpacity showSecondCard={true} overlayLabels={{ left: { title: 'スキップ', style: { label: { backgroundColor: 'rgba(255, 0, 0, 0.4)', color: 'white', fontSize: 34, borderRadius: 10, width: Dimensions.get('window').width * 0.9, height: Dimensions.get('window').height * 0.65, textAlign: 'right', textAlignVertical: 'center', position: 'absolute', top: -50, left: 0, }, wrapper: { flexDirection: 'column', borderRadius: 10, alignItems: 'center', justifyContent: 'center', marginTop: 20, marginLeft: 0, width: Dimensions.get('window').width * 0.9, height: Dimensions.get('window').height * 0.65, position: 'absolute', }, }, }, right: { title: 'ストック', style: { label: { backgroundColor: 'rgba(0, 128, 0, 0.4)', color: 'white', fontSize: 34, borderRadius: 10, width: Dimensions.get('window').width * 0.9, height: Dimensions.get('window').height * 0.65, textAlign: 'left', textAlignVertical: 'center', position: 'absolute', top: -50, left: 0, }, wrapper: { flexDirection: 'column', borderRadius: 10, alignItems: 'center', justifyContent: 'center', marginTop: 20, marginLeft: 0, width: Dimensions.get('window').width * 0.9, height: Dimensions.get('window').height * 0.65, position: 'absolute', }, }, }, }} /> ) : null} </View> );} const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, bookcover: { width: '100%', height: Dimensions.get('window').height * 0.65, position: 'absolute', }, card: { width: '100%', height: Dimensions.get('window').height * 0.65, elevation: 4, borderRadius: 12, zIndex: 5, }, bookInfo: { width: '100%', justifyContent: 'center', alignItems: 'center', alignContent: 'center', paddingVertical: 100, paddingTop: 100, }, titleArea: { width: '70%', }, title: { fontSize: 22, paddingLeft: 15, marginBottom: 15, overflow: 'scroll', }, authorArea: { width: '70%', }, author: { fontSize: 15, paddingLeft: 15, marginBottom: 25, }, explanationArea: { borderRadius: 16, width: '67%', backgroundColor: '#dfefff', borderStyle: 'dashed', borderWidth: 2, padding: 0.5, borderColor: '#f08080', shadowColor: '#000', shadowOffset: {width: 0, height: 4}, shadowOpacity: 0.1, shadowRadius: 6, }, text1: { fontSize: 15, paddingTop: 15, paddingLeft: 15, marginBottom: 8, }, text2: { fontSize: 15, paddingTop: 5, paddingLeft: 15, marginBottom: 8,  },});



続きを読む

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -

インモビ転職