LoginSignup
0
0

カレンダーにマーキングする

Posted at

実装した機能

カレンダーに目覚ましチャレンジが成功した場合、マーキングする。

※2024/01/04の青円の印がマーキング後のイメージです。

image.png

使ったもの

カレンダー react-native-calendars
ナビゲーター react-navigation

やったこと

UI

カレンダーの表示 画面の上半分をカレンダー表示にしたかった
デザインはシンプルにデフォルトを利用している。
下半分は別機能に利用するため、残しておきたかった。

const HistoryScreen = () => {
    return (
        <View style={styles.container}>
              {/* 上部:カレンダー */}
              <View style={styles.calendarContainer}>
                <Calendar
                  markedDates={markedDates}
                  // その他のプロパティ
                />
              </View>
            </View>
      );
    };

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  calendarContainer: {
    // カレンダーコンポーネントのスタイル
  },
export default HistoryScreen;

react-native-calendars

テストとして、ダミーデータでマーキングできるか確認してみた

    const markedDates = {
    "2023-12-01": { selected: true, marked: true, dotColor: "green" }, // 今日
    "2023-11-30": { selected: true, marked: true, dotColor: "green" }, // 昨日
  };

image.png

画面間のデータの受け渡し

次にアラームを止めた際に、historyScreen.jsにデータが流れるようにした

  1. App.js でナビゲータを設定

    import * as React from "react";
    import { View, Text, SafeAreaView } from "react-native";
    import { NavigationContainer } from "@react-navigation/native";
    import { createStackNavigator } from "@react-navigation/stack";
    
    import HistoryScreen from "./screens/HistoryScreen";
    import AlarmScreen from "./screens/AlarmScreen";
    
    const Stack = createStackNavigator();
    
    export default function App() {
      return (
        <NavigationContainer>
          <Stack.Navigator>
            <Stack.Screen name="History" component={HistoryScreen} />
            <Stack.Screen name="Alarm" component={AlarmScreen} />
          </Stack.Navigator>
        </NavigationContainer>
      );
    }
    
    
  2. AlarmScreen.jsで引値を設定

    // AlarmScreen.js
    
    import React, { useState, useEffect } from 'react';
    import { View, Text, TouchableOpacity, Switch, StyleSheet, Image, Button } from 'react-native';
    import { Audio } from 'expo-av';
    import DateTimePicker from '@react-native-community/datetimepicker';
    import Modal from 'react-native-modal';
    
    const AlarmScreen = ({ navigation }) => {
      // ... 他のコード
    
      const stopAlarm = async () => {
        if (sound) {
          clearInterval(alarmIntervalId); // インターバルの停止
          await sound.unloadAsync();
    
          // アラームが止まった情報をHistoryScreenに送信
          navigation.navigate('History', { alarmStopped: true });
        }
      };
    
      // ... 他のコード
    };
    
    export default AlarmScreen;
    
    
  3. History.jsの更新

    routeを引数として、AlarmScreenから渡されたパラメータを利用した。
    routeの中身は、以下の通り。

    {"key": "History-XXXXXXXXXXXXX", "name": "History", "params": {"alarmStopped": true}, "path": undefined}
    

    alarmStoppedをトリガーに、カレンダーにマーキングする処理を実装した。

    // HistoryScreen.js
    
    import React, { useState, useEffect } from 'react';
    import { View, Text, StyleSheet, FlatList } from 'react-native';
    import { Calendar } from 'react-native-calendars';
    
    const HistoryScreen = ({ route }) => {
      const [markedDates, setMarkedDates] = useState({});
    
      useEffect(() => {
        // アラームが止まった情報があればカレンダーを更新
        if (route.params?.alarmStopped) {
          updateCalendar(); // カレンダー更新関数の呼び出し
        }
      }, [route.params?.alarmStopped]);
    
      const updateCalendar = () => {
        const currentDate = new Date();
        const formattedDate = `${currentDate.getFullYear()}-${currentDate.getMonth() + 1}-${currentDate.getDate()}`;
    
        // カレンダーの日付を更新
        setMarkedDates((prevMarkedDates) => {
          return {
            ...prevMarkedDates,
            [formattedDate]: { selected: true, marked: true, dotColor: 'green' },
          };
        });
      };
    
      // ... 他のコード
    };
    
    export default HistoryScreen;
    
    

詰まったところ
カレンダーの日付フォーマットがyyyy-mm-dd指定だった。
getMonthで取ると 1月→1 表示になってしまった
そこでpadStart(2, "0")でゼロパディングした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0