Sunteți pe pagina 1din 16

Ministerul Educației, Culturii și Cercetării

Universitatea Tehnică a Moldovei


Facultatea Calculatoare, Informatică şi Microelectronică
Departamentul Ingineria Software și Automatică

UI Kit
Lucrare de laborator nr.1
Disciplina: Programarea Aplicațiilor Mobile

Studenta gr. TI-181: Globa Vladislav


Conducător: Rusu Cristian

Chișinău 2020
Obiective
Dezvoltarea unei aplicații pe una din platformele stabilite la Laboratorul Nr.0, utilizând mediul de
dezvoltare corespunzător acesteia.
Scopul
De prezentat o aplicație ce rulează pe un dispozitiv sau emulator, ce va conține pe interfața sa,
următoarele elemente:
1. 4 butoane (ce vor executa condițiile de mai jos);
2. 1 TextBox (pentru input);
3. Radio butoane (pentru camera față, spate).
Condiții
De utilizat componentele UI pentru a realiza următoarele condiții:
1. De creat un notification pe ecranul dispozitivului care se va trata peste 10s;
2. De utilizat browserul intern al dispozitivului, pentru a inițializa o căutare în Google,
conform cuvântului cheie introdus în TextBox;
3. De rulat evenimentul de lucru a camerei frontale și/sau spate la selectarea unuia din cele 2 radio
butoane propuse;
4. De tratat evenimentul de captare a pozei executate cu una din cele doua camere, și de afișat într-o
altă Activitate;
De citit:
 Intent
 Activități
 Când folosim create/destroit
 De ce se pune on în față
 Evenimente în Android
 Fire de execuție
 Metode de folosire a firelor de execuție
Crearea unei aplicații cu ajutorul Visual Studio Code.

Figura 1 – Interfața Aplicației Mobile


Aplicația Mobilă are mai multe componente UI.
Creăm un notification pe ecranul dispozitivului care se va trata peste 10s.

Figura 2 – Push Notification cu tratare pe ecran după 10 secunde


Figura 3 – TextBox și SEARCH Button
Figura 4 – Rezultatul căutării
Rularea evenimentul de lucru a camerei frontale și/sau spate.

Figura 5 – Butonul Flip pentru a alege sensul camerei.


Tratarea evenimentul de captare a pozei executate cu una din cele doua camere.

Figura 6 – Camera Frontală.

Codul propriu zis:


import React, {useState, useRef, useEffect} from "react";
import {
    StyleSheet,
    Dimensions,
    View,
    Text,
    TouchableOpacity,
    SafeAreaView, Button, Modal, Alert, Linking, TextInput
} from "react-native";
import {Camera} from "expo-camera";
import {Video} from "expo-av";
import {WebView} from "react-native-webview";

const WINDOW_HEIGHT = Dimensions.get("window").height;
const closeButtonSize = Math.floor(WINDOW_HEIGHT * 0.032);
const captureSize = Math.floor(WINDOW_HEIGHT * 0.09);
export default function App() {
    const [hasPermission, setHasPermission] = useState(null);
    const [cameraType, setCameraType] = useState(Camera.Constants.Type.back);
    const [isPreview, setIsPreview] = useState(false);
    const [isCameraReady, setIsCameraReady] = useState(false);
    const [isVideoRecording, setIsVideoRecording] = useState(false);
    const [videoSource, setVideoSource] = useState(null);
    const [camera, setCamera] = useState(false)
    const [modal, setModal] = useState(false)
    const [search, setSearch] = useState(null)
    const [value, onChangeText] = useState(null);
    const cameraRef = useRef();

    const handleSearch = () => {
        if (!value) {
            return Alert.alert(
                "Atenție",
                "Input-ul este gol, doriti sa continuati ?",
                [
                    {text: "Anulează", onPress: () => console.log("Cancel")},
                    {text: "OK", onPress: () => Linking.openURL(`https://www.google.com/sea
rch?q=${value}`)}
                ],
                {cancelable: false}
            );
        }
        return Linking.openURL(`https://www.google.com/search?q=${value}`)
    }

    const showModal = () => {
        setModal(true)
        setTimeout(() => {
            setModal(false)
        }, 10000)
    }

    useEffect(() => {
        (async () => {
            const {status} = await Camera.requestPermissionsAsync();
            setHasPermission(status === "granted");
        })();
    }, []);
    const onCameraReady = () => {
        setIsCameraReady(true);
    };
    const takePicture = async () => {
        if (cameraRef.current) {
            const options = {quality: 0.5, base64: true, skipProcessing: true};
            const data = await cameraRef.current.takePictureAsync(options);
            const source = data.uri;
            if (source) {
                await cameraRef.current.pausePreview();
                setIsPreview(true);
                console.log("picture source", source);
            }
        }
    };
    const recordVideo = async () => {
        if (cameraRef.current) {
            try {
                const videoRecordPromise = cameraRef.current.recordAsync();
                if (videoRecordPromise) {
                    setIsVideoRecording(true);
                    const data = await videoRecordPromise;
                    const source = data.uri;
                    if (source) {
                        setIsPreview(true);
                        console.log("video source", source);
                        setVideoSource(source);
                    }
                }
            } catch (error) {
                console.warn(error);
            }
        }
    };
    const stopVideoRecording = () => {
        if (cameraRef.current) {
            setIsPreview(false);
            setIsVideoRecording(false);
            cameraRef.current.stopRecording();
        }
    };
    const switchCamera = () => {
        if (isPreview) {
            return;
        }
        setCameraType((prevCameraType) =>
            prevCameraType === Camera.Constants.Type.back
                ? Camera.Constants.Type.front
                : Camera.Constants.Type.back
        );
    };
    const cancelPreview = async () => {
        await cameraRef.current.resumePreview();
        setIsPreview(false);
        setVideoSource(null);
    };

    const toggleCamera = () => setCamera(!camera)

    const renderCancelPreviewButton = () => (
        <TouchableOpacity onPress={cancelPreview} style={styles.closeButton}>
            <View style={[styles.closeCross, {transform: [{rotate: "45deg"}]}]}/>
            <View
                style={[styles.closeCross, {transform: [{rotate: "-45deg"}]}]}
            />
        </TouchableOpacity>
    );
    const renderVideoPlayer = () => (
        <Video
            source={{uri: videoSource}}
            shouldPlay={true}
            style={styles.media}
        />
    );
    const renderVideoRecordIndicator = () => (
        <View style={styles.recordIndicatorContainer}>
            <View style={styles.recordDot}/>
            <Text style={styles.recordTitle}>{"Recording..."}</Text>
        </View>
    );
    const renderCaptureControl = () => (
        <View style={styles.control}>
            <TouchableOpacity disabled={!isCameraReady} onPress={toggleCamera}>
                <Text style={styles.text}>Înapoi</Text>
            </TouchableOpacity>
            <TouchableOpacity
                activeOpacity={0.7}
                disabled={!isCameraReady}
                onLongPress={recordVideo}
                onPressOut={stopVideoRecording}
                onPress={takePicture}
                style={styles.capture}
            />
            <TouchableOpacity disabled={!isCameraReady} onPress={switchCamera}>
                <Text style={styles.text}>Flip</Text>
            </TouchableOpacity>
        </View>
    );
    if (hasPermission === null) {
        return <View/>;
    }
    if (hasPermission === false) {
        return <Text style={styles.text}>No access to camera</Text>;
    }
    return (
        <View style={{position: "relative"}}>
            {search && <WebView source={{uri: `https://www.google.com/search?q=$
{value}`}}/>}
            {!camera && <View style={styles.inputControl}>
                <TextInput
                    style={styles.textInput}
                    onChangeText={text => onChangeText(text)}
                    value={value}
                />
                {search ?
                    <Button
                        title={"back"}
                        onPress={handleSearch}
                    />
                    : <Button title="Go" onPress={handleSearch}/>}

            </View>}
            {!camera && <Button title="deschide camera" onPress={toggleCamera}/>}
            {!camera && <Button title='deschide dialog' onPress={showModal}/>}

            <Modal
                animationType="slide"
                transparent
                visible={modal}
                onRequestClose={() => {
                    console.log('Modal has been closed.');
                }}>
                <View style={{
                    flex: 1,
                    backgroundColor: 'gray',
                    justifyContent: 'center',
                    alignItems: 'center',
                    margin: 25
                }}>
                    <Text style={{fontSize: 16, color: 'white'}}>Numarati 10 secunde</Text>
                </View>
            </Modal>

            {camera && <SafeAreaView>
                <Camera
                    ref={cameraRef}
                    style={styles.container}
                    type={cameraType}
                    flashMode={Camera.Constants.FlashMode.on}
                    onCameraReady={onCameraReady}
                    onMountError={(error) => {
                        console.log("cammera error", error);
                    }}
                />
                <View style={styles.container}>
                    {isVideoRecording && renderVideoRecordIndicator()}
                    {videoSource && renderVideoPlayer()}
                    {isPreview && renderCancelPreviewButton()}
                    {!videoSource && !isPreview && renderCaptureControl()}
                </View>
            </SafeAreaView>}
        </View>
    );
}
const styles = StyleSheet.create({
    container: {
        position: "absolute",
        height: 670,
        width: "100%"
    },
    closeButton: {
        position: "absolute",
        top: 35,
        left: 15,
        height: closeButtonSize,
        width: closeButtonSize,
        borderRadius: Math.floor(closeButtonSize / 2),
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "#c4c5c4",
        opacity: 0.7,
        zIndex: 2,
    },
    media: {
        top: 0, left: 0, bottom: 0, position: "absolute", right: 0
    },
    closeCross: {
        width: "68%",
        height: 1,
        backgroundColor: "black",
    },
    control: {
        position: "absolute",
        flexDirection: "row",
        bottom: 38,
        width: "100%",
        alignItems: "center",
        justifyContent: "center",
    },
    capture: {
        backgroundColor: "#f5f6f5",
        height: captureSize,
        width: captureSize,
        borderRadius: Math.floor(captureSize / 2),
        marginHorizontal: 31,
    },
    recordIndicatorContainer: {
        flexDirection: "row",
        position: "absolute",
        top: 25,
        alignSelf: "center",
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "transparent",
        opacity: 0.7,
    },
    recordTitle: {
        fontSize: 14,
        color: "#ffffff",
        textAlign: "center",
    },
    recordDot: {
        borderRadius: 3,
        height: 6,
        width: 6,
        backgroundColor: "#ff0000",
        marginHorizontal: 5,
    },
    text: {
        color: "#fff",
    },
    inputControl: {
        width: 200,
        display: "flex",
        alignSelf: "center",
        flexDirection: "row",
        alignItems: "center",
        marginTop: 30
    },
    textInput: {
        height: 40,
        borderColor: 'gray',
        borderWidth: 1,
        width: 200,
        display: "flex",
        alignItems: "center",
        borderRadius: 4,
        padding: 4
    }
});

Întrebări de control:
 Intent – o descriere abstractă a unei operații care trebuie efectuată; oferă o facilitate pentru a efectua
legarea în timp scurt a executării între cod în diferite aplicații; o structură de date pasivă care conține
o descriere abstractă a unei acțiuni care trebuie executată.
 Activitate – o componentă a aplicației Android ce oferă o interfață grafică cu care utilizatorul poate
să interacționeze.
 Când folosim create/destroit
 on – pentru că sunt evenimente de tip handler.
 Evenimente – o modalitate utilă de a colecta date despre interacțiunea unui utilizator cu
componentele interactive ale aplicațiilor.

Event Handler Event Listener & Description

OnClickListener()
onClick() This is called when the user either clicks or touches or focuses
upon any widget like button, text, image etc. You will use
onClick() event handler to handle such event.

OnLongClickListener()
This is called when the user either clicks or touches or focuses
onLongClick() upon any widget like button, text, image etc. for one or more
seconds. You will use onLongClick() event handler to handle
such event.
OnFocusChangeListener()

onFocusChange() This is called when the widget looses its focus ie. user goes
away from the view item. You will use onFocusChange() event
handler to handle such event.

OnFocusChangeListener()

onKey() This is called when the user is focused on the item and presses
or releases a hardware key on the device. You will use onKey()
event handler to handle such event.

OnTouchListener()

onTouch() This is called when the user presses the key, releases the key,
or any movement gesture on the screen. You will use
onTouch() event handler to handle such event.

OnMenuItemClickListener()
onMenuItemClick() This is called when the user selects a menu item. You will use
onMenuItemClick() event handler to handle such event.

onCreateContextMenuItemListener()
onCreateContextMenu(
) This is called when the context menu is being built(as the result
of a sustained "long click)

 Fire de execuție într-un program. Mașina virtuală Java permite unei aplicații să aibă mai multe fire
de execuție care rulează concomitent. Fiecare fir are prioritate. Firele cu prioritate mai mare sunt
executate în preferință pentru firele cu prioritate mai mică.
 Metode de folosire a firelor de execuție:
1. Publics methods
2. Protected methods
3. Inherited methods

S-ar putea să vă placă și

  • Amoo 2
    Amoo 2
    Document8 pagini
    Amoo 2
    AlionaCrigan
    Încă nu există evaluări
  • Caietul de Sarcini (Producție)
    Caietul de Sarcini (Producție)
    Document4 pagini
    Caietul de Sarcini (Producție)
    AlionaCrigan
    100% (1)
  • Ferestre de Dialog
    Ferestre de Dialog
    Document58 pagini
    Ferestre de Dialog
    AlionaCrigan
    Încă nu există evaluări
  • Practica - in Productie
    Practica - in Productie
    Document32 pagini
    Practica - in Productie
    AlionaCrigan
    Încă nu există evaluări
  • Raport Practica
    Raport Practica
    Document27 pagini
    Raport Practica
    AlionaCrigan
    Încă nu există evaluări
  • Practica În Producție
    Practica În Producție
    Document19 pagini
    Practica În Producție
    AlionaCrigan
    Încă nu există evaluări
  • Somipp 1
    Somipp 1
    Document6 pagini
    Somipp 1
    AlionaCrigan
    Încă nu există evaluări
  • Lab 1
    Lab 1
    Document2 pagini
    Lab 1
    AlionaCrigan
    Încă nu există evaluări
  • Raspuns Lab 1
    Raspuns Lab 1
    Document4 pagini
    Raspuns Lab 1
    AlionaCrigan
    Încă nu există evaluări
  • Amoo 4
    Amoo 4
    Document5 pagini
    Amoo 4
    AlionaCrigan
    Încă nu există evaluări
  • Amoo 5
    Amoo 5
    Document5 pagini
    Amoo 5
    AlionaCrigan
    Încă nu există evaluări
  • Amoo 1
    Amoo 1
    Document8 pagini
    Amoo 1
    AlionaCrigan
    Încă nu există evaluări