Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lab1, first pull request. #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

463 changes: 463 additions & 0 deletions .idea/dbnavigator.xml

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,38 @@
# AndroidOracle
# AndroidOracle

## Preview
1. This project uses jdk 8;
2. Navigation is built on fragments;

## Features
☑️Main screen with buttons:
- Ask a question,
- Settings,
- Quit;

<br>☑️Settings screen that allows you to edit user information:
- name (text field),
- last name (text field),
- date of birth (display in text, change the date using DatePickerDialog),
- gender (RadioButton);

<br>☑️Screen for questions:
- the user enters a question and clicks the "Generate" button,
- the program responds with one of the following options: "Yes", "No", "Of course", "Maybe", "Are you sure?", "Great", "Wonderful", "Right?", "Maybe we should not?", "Please, repeat", "No more words, silence", "Are you sleeping now?", "Don't know", "Who cares"
- the answer is generated based on the following data: entered question, information about user, current date.
- for the same input data, the answer must be the same.

## Launch guide
To run this project you will need to install this project in phone with Android Operating System.

## Program testing
### Main Menu
![Main Menu](app/src/main/res/img/main.jpg)
![Main Menu](app/src/main/res/img/main_land.jpg)
### Settings
![Settings](app/src/main/res/img/setting.jpg)
![Settings](app/src/main/res/img/setting_land.jpg)
### Ask a question
![Ask a question](app/src/main/res/img/ask_a_question.jpg)
![Ask a question](app/src/main/res/img/ask_a_question_done.jpg)
![Ask a question](app/src/main/res/img/ask_a_question_done_land.jpg)
12 changes: 6 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ android {
buildToolsVersion "30.0.2"

defaultConfig {
applicationId "ua.gura.com.example.andriodoracle"
applicationId "ua.gura.com.example.androidoracle"
minSdkVersion 19
targetSdkVersion 30
versionCode 1
Expand All @@ -30,10 +30,10 @@ android {

dependencies {

implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package ua.gura.com.example.andriodoracle;
package ua.gura.com.example.androidoracle;

import android.content.Context;

Expand All @@ -21,6 +21,6 @@ public class ExampleInstrumentedTest {
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("ua.gura.com.example.andriodoracle", appContext.getPackageName());
assertEquals("ua.gura.com.example.androidoracle", appContext.getPackageName());
}
}
4 changes: 2 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ua.gura.com.example.andriodoracle">
package="ua.gura.com.example.androidoracle">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AndriodOracle">
android:theme="@style/Theme.AndroidOracle">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down

This file was deleted.

153 changes: 153 additions & 0 deletions app/src/main/java/ua/gura/com/example/androidoracle/MainActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package ua.gura.com.example.androidoracle;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

import android.os.Bundle;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import ua.gura.com.example.androidoracle.contract.AppContract;
import ua.gura.com.example.androidoracle.contract.ResponseListener;
import ua.gura.com.example.androidoracle.fragments.MenuFragment;
import ua.gura.com.example.androidoracle.fragments.QuestionFragment;
import ua.gura.com.example.androidoracle.fragments.SettingFragment;
import ua.gura.com.example.androidoracle.model.User;

public class MainActivity extends AppCompatActivity
implements AppContract {
public static final String TAG =
MainActivity.class.getSimpleName();
private Map<String, List<ListenerInfo<?>>> listeners =
new HashMap<>();

@Override
protected void onCreate(@Nullable Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
launchFragment(null, new MenuFragment());
}
}

@Override
public void onBackPressed() {
cancel();
}

@Override
public void toSettingScreen(Fragment target,
User user) {
launchFragment(target,
SettingFragment.newInstance(user));
}

@Override
public void toResultsScreen(Fragment target,
User user) {
launchFragment(target, QuestionFragment.newInstance(user));
}

@Override
public void cancel() {
int count = getSupportFragmentManager()
.getBackStackEntryCount();
if (count <= 1) {
finish();
} else {
getSupportFragmentManager().popBackStack();
}
}

@Override
public <T> void publish(T results) {
Fragment currentFragment = getCurrentFragment();
if (currentFragment == null) {
Log.e(TAG, "Can't find the current fragment");
return;
}
Fragment targetFragment =
currentFragment.getTargetFragment();
if (targetFragment == null) {
Log.e(TAG, "Fragment " + currentFragment +
" doesn't have a target");
return;
}
String tag = targetFragment.getTag();
if (tag == null) {
Log.e(TAG, "Target fragment exists but doesn't have a tag: " + targetFragment);
return;
}
List<ListenerInfo<?>> listeners =
this.listeners.get(tag);
if (listeners != null) {
Iterator<ListenerInfo<?>> it = listeners.iterator();
while (it.hasNext() &&
!it.next().tryPublish(results));
}
}
@Override
public <T> void registerListener(Fragment fragment,
Class<T> clazz,
ResponseListener<T> listener) {
if (fragment.getTag() == null) {
Log.e(TAG, "Fragment '" + fragment +
"' doesn't have a tag");
return;
}
List<ListenerInfo<?>> listeners =
this.listeners.get(fragment.getTag());
if (listeners == null) {
listeners = new ArrayList<>();
this.listeners.put(fragment.getTag(), listeners);
}
listeners.add(new ListenerInfo<>(clazz, listener));
}
@Override
public void unregisterListeners(Fragment fragment) {
if (fragment.getTag() == null) {
Log.e(TAG, "Fragment '" + fragment +
"' doesn't have a tag");
return;
}
this.listeners.remove(fragment.getTag());
}
private void launchFragment(@Nullable Fragment target,
Fragment fragment) {
if (target != null) {
fragment.setTargetFragment(target, 0);
}
String tag = UUID.randomUUID().toString();
getSupportFragmentManager().beginTransaction()
.addToBackStack(null)
.replace(R.id.fragmentContainer, fragment, tag)
.commit();
}
private Fragment getCurrentFragment() {
return getSupportFragmentManager()
.findFragmentById(R.id.fragmentContainer);
}
private static class ListenerInfo<T> {
Class<T> clazz;
ResponseListener<T> listener;
private ListenerInfo(Class<T> clazz,
ResponseListener<T> listener) {
this.clazz = clazz;
this.listener = listener;
}
boolean tryPublish(Object result) {
if (result.getClass().equals(clazz)) {
listener.onResults((T) result);
return true;
}
return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package ua.gura.com.example.androidoracle.contract;

import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import ua.gura.com.example.androidoracle.model.User;

public interface AppContract {
/**
* Launch options screen
* @param target fragment that launches options screen
* @param user data about the User to be displayed
*/
void toSettingScreen(Fragment target,
@Nullable User user);
/**
* Launch results screen
* @param target fragment that launches results screen
* @param user data used for calculating variant
*/
void toResultsScreen(Fragment target, User user);
/**
* Exit from the current screen
*/
void cancel();
/**
* Publish results to the target screen
*/
<T> void publish(T data);
/**
* Listen for results from other screens
*/
<T> void registerListener(Fragment fragment, Class<T> clazz,
ResponseListener<T> listener);
/**
* Stop listening for results from other screens
*/
void unregisterListeners(Fragment fragment);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ua.gura.com.example.androidoracle.contract;

public interface ResponseListener<T> {
void onResults(T results);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ua.gura.com.example.androidoracle.fragments;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import ua.gura.com.example.androidoracle.contract.AppContract;
import ua.gura.com.example.androidoracle.contract.ResponseListener;

public class BaseFragment extends Fragment {

private AppContract appContract;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
this.appContract = (AppContract) context;
}
@Override
public void onDetach() {
super.onDetach();
this.appContract.unregisterListeners(this);
this.appContract = null;
}
final AppContract getAppContract() {
return appContract;
}
final <T> void registerListener(Class<T> clazz,
ResponseListener<T> listener) {
getAppContract().registerListener(this, clazz, listener);
}
}
Loading