Documente Academic
Documente Profesional
Documente Cultură
LL1 PAM Globa-Vladislav
LL1 PAM Globa-Vladislav
UI Kit
Lucrare de laborator nr.1
Disciplina: Programarea Aplicațiilor Mobile
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.
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.
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