Showing
70 changed files
with
2240 additions
and
0 deletions
.gitignore
0 → 100644
.idea/codeStyles/Project.xml
0 → 100644
| 1 | +<component name="ProjectCodeStyleConfiguration"> | ||
| 2 | + <code_scheme name="Project" version="173"> | ||
| 3 | + <JetCodeStyleSettings> | ||
| 4 | + <option name="PACKAGES_TO_USE_STAR_IMPORTS"> | ||
| 5 | + <value> | ||
| 6 | + <package name="java.util" alias="false" withSubpackages="false" /> | ||
| 7 | + <package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" /> | ||
| 8 | + <package name="io.ktor" alias="false" withSubpackages="true" /> | ||
| 9 | + </value> | ||
| 10 | + </option> | ||
| 11 | + <option name="PACKAGES_IMPORT_LAYOUT"> | ||
| 12 | + <value> | ||
| 13 | + <package name="" alias="false" withSubpackages="true" /> | ||
| 14 | + <package name="java" alias="false" withSubpackages="true" /> | ||
| 15 | + <package name="javax" alias="false" withSubpackages="true" /> | ||
| 16 | + <package name="kotlin" alias="false" withSubpackages="true" /> | ||
| 17 | + <package name="" alias="true" withSubpackages="true" /> | ||
| 18 | + </value> | ||
| 19 | + </option> | ||
| 20 | + </JetCodeStyleSettings> | ||
| 21 | + <codeStyleSettings language="XML"> | ||
| 22 | + <indentOptions> | ||
| 23 | + <option name="CONTINUATION_INDENT_SIZE" value="4" /> | ||
| 24 | + </indentOptions> | ||
| 25 | + <arrangement> | ||
| 26 | + <rules> | ||
| 27 | + <section> | ||
| 28 | + <rule> | ||
| 29 | + <match> | ||
| 30 | + <AND> | ||
| 31 | + <NAME>xmlns:android</NAME> | ||
| 32 | + <XML_ATTRIBUTE /> | ||
| 33 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | ||
| 34 | + </AND> | ||
| 35 | + </match> | ||
| 36 | + </rule> | ||
| 37 | + </section> | ||
| 38 | + <section> | ||
| 39 | + <rule> | ||
| 40 | + <match> | ||
| 41 | + <AND> | ||
| 42 | + <NAME>xmlns:.*</NAME> | ||
| 43 | + <XML_ATTRIBUTE /> | ||
| 44 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | ||
| 45 | + </AND> | ||
| 46 | + </match> | ||
| 47 | + <order>BY_NAME</order> | ||
| 48 | + </rule> | ||
| 49 | + </section> | ||
| 50 | + <section> | ||
| 51 | + <rule> | ||
| 52 | + <match> | ||
| 53 | + <AND> | ||
| 54 | + <NAME>.*:id</NAME> | ||
| 55 | + <XML_ATTRIBUTE /> | ||
| 56 | + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||
| 57 | + </AND> | ||
| 58 | + </match> | ||
| 59 | + </rule> | ||
| 60 | + </section> | ||
| 61 | + <section> | ||
| 62 | + <rule> | ||
| 63 | + <match> | ||
| 64 | + <AND> | ||
| 65 | + <NAME>.*:name</NAME> | ||
| 66 | + <XML_ATTRIBUTE /> | ||
| 67 | + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||
| 68 | + </AND> | ||
| 69 | + </match> | ||
| 70 | + </rule> | ||
| 71 | + </section> | ||
| 72 | + <section> | ||
| 73 | + <rule> | ||
| 74 | + <match> | ||
| 75 | + <AND> | ||
| 76 | + <NAME>name</NAME> | ||
| 77 | + <XML_ATTRIBUTE /> | ||
| 78 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | ||
| 79 | + </AND> | ||
| 80 | + </match> | ||
| 81 | + </rule> | ||
| 82 | + </section> | ||
| 83 | + <section> | ||
| 84 | + <rule> | ||
| 85 | + <match> | ||
| 86 | + <AND> | ||
| 87 | + <NAME>style</NAME> | ||
| 88 | + <XML_ATTRIBUTE /> | ||
| 89 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | ||
| 90 | + </AND> | ||
| 91 | + </match> | ||
| 92 | + </rule> | ||
| 93 | + </section> | ||
| 94 | + <section> | ||
| 95 | + <rule> | ||
| 96 | + <match> | ||
| 97 | + <AND> | ||
| 98 | + <NAME>.*</NAME> | ||
| 99 | + <XML_ATTRIBUTE /> | ||
| 100 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | ||
| 101 | + </AND> | ||
| 102 | + </match> | ||
| 103 | + <order>BY_NAME</order> | ||
| 104 | + </rule> | ||
| 105 | + </section> | ||
| 106 | + <section> | ||
| 107 | + <rule> | ||
| 108 | + <match> | ||
| 109 | + <AND> | ||
| 110 | + <NAME>.*</NAME> | ||
| 111 | + <XML_ATTRIBUTE /> | ||
| 112 | + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||
| 113 | + </AND> | ||
| 114 | + </match> | ||
| 115 | + <order>ANDROID_ATTRIBUTE_ORDER</order> | ||
| 116 | + </rule> | ||
| 117 | + </section> | ||
| 118 | + <section> | ||
| 119 | + <rule> | ||
| 120 | + <match> | ||
| 121 | + <AND> | ||
| 122 | + <NAME>.*</NAME> | ||
| 123 | + <XML_ATTRIBUTE /> | ||
| 124 | + <XML_NAMESPACE>.*</XML_NAMESPACE> | ||
| 125 | + </AND> | ||
| 126 | + </match> | ||
| 127 | + <order>BY_NAME</order> | ||
| 128 | + </rule> | ||
| 129 | + </section> | ||
| 130 | + </rules> | ||
| 131 | + </arrangement> | ||
| 132 | + </codeStyleSettings> | ||
| 133 | + </code_scheme> | ||
| 134 | +</component> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
.idea/gradle.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<project version="4"> | ||
| 3 | + <component name="GradleMigrationSettings" migrationVersion="1" /> | ||
| 4 | + <component name="GradleSettings"> | ||
| 5 | + <option name="linkedExternalProjectsSettings"> | ||
| 6 | + <GradleProjectSettings> | ||
| 7 | + <option name="testRunner" value="PLATFORM" /> | ||
| 8 | + <option name="distributionType" value="DEFAULT_WRAPPED" /> | ||
| 9 | + <option name="externalProjectPath" value="$PROJECT_DIR$" /> | ||
| 10 | + <option name="gradleJvm" value="1.8" /> | ||
| 11 | + <option name="modules"> | ||
| 12 | + <set> | ||
| 13 | + <option value="$PROJECT_DIR$" /> | ||
| 14 | + <option value="$PROJECT_DIR$/app" /> | ||
| 15 | + </set> | ||
| 16 | + </option> | ||
| 17 | + <option name="resolveModulePerSourceSet" value="false" /> | ||
| 18 | + </GradleProjectSettings> | ||
| 19 | + </option> | ||
| 20 | + </component> | ||
| 21 | +</project> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
.idea/jarRepositories.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<project version="4"> | ||
| 3 | + <component name="RemoteRepositoriesConfiguration"> | ||
| 4 | + <remote-repository> | ||
| 5 | + <option name="id" value="central" /> | ||
| 6 | + <option name="name" value="Maven Central repository" /> | ||
| 7 | + <option name="url" value="https://repo1.maven.org/maven2" /> | ||
| 8 | + </remote-repository> | ||
| 9 | + <remote-repository> | ||
| 10 | + <option name="id" value="jboss.community" /> | ||
| 11 | + <option name="name" value="JBoss Community repository" /> | ||
| 12 | + <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> | ||
| 13 | + </remote-repository> | ||
| 14 | + <remote-repository> | ||
| 15 | + <option name="id" value="BintrayJCenter" /> | ||
| 16 | + <option name="name" value="BintrayJCenter" /> | ||
| 17 | + <option name="url" value="https://jcenter.bintray.com/" /> | ||
| 18 | + </remote-repository> | ||
| 19 | + <remote-repository> | ||
| 20 | + <option name="id" value="Google" /> | ||
| 21 | + <option name="name" value="Google" /> | ||
| 22 | + <option name="url" value="https://dl.google.com/dl/android/maven2/" /> | ||
| 23 | + </remote-repository> | ||
| 24 | + </component> | ||
| 25 | +</project> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
.idea/misc.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<project version="4"> | ||
| 3 | + <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK"> | ||
| 4 | + <output url="file://$PROJECT_DIR$/build/classes" /> | ||
| 5 | + </component> | ||
| 6 | + <component name="ProjectType"> | ||
| 7 | + <option name="id" value="Android" /> | ||
| 8 | + </component> | ||
| 9 | +</project> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
.idea/runConfigurations.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<project version="4"> | ||
| 3 | + <component name="RunConfigurationProducerService"> | ||
| 4 | + <option name="ignoredProducers"> | ||
| 5 | + <set> | ||
| 6 | + <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" /> | ||
| 7 | + <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" /> | ||
| 8 | + <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" /> | ||
| 9 | + </set> | ||
| 10 | + </option> | ||
| 11 | + </component> | ||
| 12 | +</project> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
app/.gitignore
0 → 100644
| 1 | +/build | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
app/build.gradle
0 → 100644
| 1 | +apply plugin: 'com.android.application' | ||
| 2 | + | ||
| 3 | +android { | ||
| 4 | + compileSdkVersion 30 | ||
| 5 | + buildToolsVersion "30.0.2" | ||
| 6 | + | ||
| 7 | + defaultConfig { | ||
| 8 | + applicationId "com.example.trusty" | ||
| 9 | + minSdkVersion 16 | ||
| 10 | + targetSdkVersion 30 | ||
| 11 | + versionCode 1 | ||
| 12 | + versionName "1.0" | ||
| 13 | + | ||
| 14 | + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
| 15 | + } | ||
| 16 | + | ||
| 17 | + buildTypes { | ||
| 18 | + release { | ||
| 19 | + minifyEnabled false | ||
| 20 | + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
| 21 | + } | ||
| 22 | + } | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +dependencies { | ||
| 26 | + implementation fileTree(dir: "libs", include: ["*.jar"]) | ||
| 27 | + implementation 'androidx.appcompat:appcompat:1.2.0' | ||
| 28 | + implementation 'androidx.constraintlayout:constraintlayout:2.0.2' | ||
| 29 | + implementation 'com.google.android.material:material:1.2.1' | ||
| 30 | + implementation 'androidx.annotation:annotation:1.1.0' | ||
| 31 | + implementation 'com.google.android.material:material:1.2.0-alpha01' | ||
| 32 | + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' | ||
| 33 | + testImplementation 'junit:junit:4.12' | ||
| 34 | + androidTestImplementation 'androidx.test.ext:junit:1.1.2' | ||
| 35 | + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' | ||
| 36 | + | ||
| 37 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
app/proguard-rules.pro
0 → 100644
| 1 | +# Add project specific ProGuard rules here. | ||
| 2 | +# You can control the set of applied configuration files using the | ||
| 3 | +# proguardFiles setting in build.gradle. | ||
| 4 | +# | ||
| 5 | +# For more details, see | ||
| 6 | +# http://developer.android.com/guide/developing/tools/proguard.html | ||
| 7 | + | ||
| 8 | +# If your project uses WebView with JS, uncomment the following | ||
| 9 | +# and specify the fully qualified class name to the JavaScript interface | ||
| 10 | +# class: | ||
| 11 | +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
| 12 | +# public *; | ||
| 13 | +#} | ||
| 14 | + | ||
| 15 | +# Uncomment this to preserve the line number information for | ||
| 16 | +# debugging stack traces. | ||
| 17 | +#-keepattributes SourceFile,LineNumberTable | ||
| 18 | + | ||
| 19 | +# If you keep the line number information, uncomment this to | ||
| 20 | +# hide the original source file name. | ||
| 21 | +#-renamesourcefileattribute SourceFile | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | + | ||
| 5 | +import androidx.test.platform.app.InstrumentationRegistry; | ||
| 6 | +import androidx.test.ext.junit.runners.AndroidJUnit4; | ||
| 7 | + | ||
| 8 | +import org.junit.Test; | ||
| 9 | +import org.junit.runner.RunWith; | ||
| 10 | + | ||
| 11 | +import static org.junit.Assert.*; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * Instrumented test, which will execute on an Android device. | ||
| 15 | + * | ||
| 16 | + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> | ||
| 17 | + */ | ||
| 18 | +@RunWith(AndroidJUnit4.class) | ||
| 19 | +public class ExampleInstrumentedTest { | ||
| 20 | + @Test | ||
| 21 | + public void useAppContext() { | ||
| 22 | + // Context of the app under test. | ||
| 23 | + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); | ||
| 24 | + assertEquals("com.example.trusty", appContext.getPackageName()); | ||
| 25 | + } | ||
| 26 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
app/src/main/AndroidManifest.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + package="com.example.trusty"> | ||
| 4 | + | ||
| 5 | + <application | ||
| 6 | + android:allowBackup="true" | ||
| 7 | + android:icon="@drawable/logo_icon" | ||
| 8 | + android:label="@string/app_name" | ||
| 9 | + android:roundIcon="@drawable/logo_icon" | ||
| 10 | + android:supportsRtl="true" | ||
| 11 | + android:theme="@style/AppTheme"> | ||
| 12 | + <activity android:name=".Comparepage"></activity> | ||
| 13 | + <activity android:name=".itempage2" /> | ||
| 14 | + <activity android:name=".itemsPage" /> | ||
| 15 | + <activity | ||
| 16 | + android:name=".ui.login.LoginActivity" | ||
| 17 | + android:label="@string/title_activity_login" /> | ||
| 18 | + <activity android:name=".MainActivity" /> | ||
| 19 | + <activity android:name=".SplashActivity"> | ||
| 20 | + <intent-filter> | ||
| 21 | + <action android:name="android.intent.action.MAIN" /> | ||
| 22 | + | ||
| 23 | + <category android:name="android.intent.category.LAUNCHER" /> | ||
| 24 | + </intent-filter> | ||
| 25 | + </activity> | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + </application> | ||
| 29 | + | ||
| 30 | +</manifest> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty; | ||
| 2 | + | ||
| 3 | +import androidx.appcompat.app.AppCompatActivity; | ||
| 4 | + | ||
| 5 | +import android.os.Bundle; | ||
| 6 | + | ||
| 7 | +public class Comparepage extends AppCompatActivity { | ||
| 8 | + | ||
| 9 | + @Override | ||
| 10 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 11 | + super.onCreate(savedInstanceState); | ||
| 12 | + setContentView(R.layout.activity_comparepage); | ||
| 13 | + } | ||
| 14 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty; | ||
| 2 | + | ||
| 3 | +import androidx.appcompat.app.AppCompatActivity; | ||
| 4 | +import android.app.Activity; | ||
| 5 | +import android.content.Intent; | ||
| 6 | +import android.os.Bundle; | ||
| 7 | +import android.view.View; | ||
| 8 | +import android.widget.Button; | ||
| 9 | + | ||
| 10 | +public class MainActivity extends AppCompatActivity { | ||
| 11 | + | ||
| 12 | + @Override | ||
| 13 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 14 | + super.onCreate(savedInstanceState); | ||
| 15 | + setContentView(R.layout.activity_main2); | ||
| 16 | + | ||
| 17 | + Button imageButton1 = (Button) findViewById(R.id.btn_1); | ||
| 18 | + imageButton1.setOnClickListener(new View.OnClickListener() { | ||
| 19 | + @Override | ||
| 20 | + public void onClick(View v) { | ||
| 21 | + Intent intent1 = new Intent(getApplicationContext(), itemsPage.class); | ||
| 22 | + startActivity(intent1); | ||
| 23 | + } | ||
| 24 | + }); | ||
| 25 | + | ||
| 26 | + Button imageButton2 = (Button) findViewById(R.id.btn_2); | ||
| 27 | + imageButton2.setOnClickListener(new View.OnClickListener() { | ||
| 28 | + @Override | ||
| 29 | + public void onClick(View v) { | ||
| 30 | + Intent intent2 = new Intent(getApplicationContext(), itempage2.class); | ||
| 31 | + startActivity(intent2); | ||
| 32 | + } | ||
| 33 | + }); | ||
| 34 | + | ||
| 35 | + Button imageButton3 = (Button) findViewById(R.id.btn_3); | ||
| 36 | + imageButton3.setOnClickListener(new View.OnClickListener() { | ||
| 37 | + @Override | ||
| 38 | + public void onClick(View v) { | ||
| 39 | + Intent intent3 = new Intent(getApplicationContext(), Comparepage.class); | ||
| 40 | + startActivity(intent3); | ||
| 41 | + } | ||
| 42 | + }); | ||
| 43 | + | ||
| 44 | + | ||
| 45 | + } | ||
| 46 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty; | ||
| 2 | + | ||
| 3 | +import android.app.Activity; | ||
| 4 | +import android.content.Intent; | ||
| 5 | +import android.os.Bundle; | ||
| 6 | +import android.os.Handler; | ||
| 7 | + | ||
| 8 | +public class SplashActivity extends Activity { | ||
| 9 | + | ||
| 10 | + @Override | ||
| 11 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 12 | + super.onCreate(savedInstanceState); | ||
| 13 | + | ||
| 14 | + setContentView(R.layout.activity_splash); | ||
| 15 | + | ||
| 16 | + Handler hd = new Handler(); | ||
| 17 | + hd.postDelayed(new splashhandler(), 3000); // 1초 후에 hd handler 실행 3000ms = 3초 | ||
| 18 | + | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + private class splashhandler implements Runnable { | ||
| 22 | + public void run() { | ||
| 23 | + startActivity(new Intent(getApplication(), MainActivity.class)); //로딩이 끝난 후, ChoiceFunction 이동 | ||
| 24 | + SplashActivity.this.finish(); // 로딩페이지 Activity stack에서 제거 | ||
| 25 | + } | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + @Override | ||
| 29 | + public void onBackPressed() { | ||
| 30 | + //초반 플래시 화면에서 넘어갈때 뒤로가기 버튼 못누르게 함 | ||
| 31 | + } | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | + | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty.data; | ||
| 2 | + | ||
| 3 | +import com.example.trusty.data.model.LoggedInUser; | ||
| 4 | + | ||
| 5 | +import java.io.IOException; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * Class that handles authentication w/ login credentials and retrieves user information. | ||
| 9 | + */ | ||
| 10 | +public class LoginDataSource { | ||
| 11 | + | ||
| 12 | + public Result<LoggedInUser> login(String username, String password) { | ||
| 13 | + | ||
| 14 | + try { | ||
| 15 | + // TODO: handle loggedInUser authentication | ||
| 16 | + LoggedInUser fakeUser = | ||
| 17 | + new LoggedInUser( | ||
| 18 | + java.util.UUID.randomUUID().toString(), | ||
| 19 | + "Jane Doe"); | ||
| 20 | + return new Result.Success<>(fakeUser); | ||
| 21 | + } catch (Exception e) { | ||
| 22 | + return new Result.Error(new IOException("Error logging in", e)); | ||
| 23 | + } | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + public void logout() { | ||
| 27 | + // TODO: revoke authentication | ||
| 28 | + } | ||
| 29 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty.data; | ||
| 2 | + | ||
| 3 | +import com.example.trusty.data.model.LoggedInUser; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * Class that requests authentication and user information from the remote data source and | ||
| 7 | + * maintains an in-memory cache of login status and user credentials information. | ||
| 8 | + */ | ||
| 9 | +public class LoginRepository { | ||
| 10 | + | ||
| 11 | + private static volatile LoginRepository instance; | ||
| 12 | + | ||
| 13 | + private LoginDataSource dataSource; | ||
| 14 | + | ||
| 15 | + // If user credentials will be cached in local storage, it is recommended it be encrypted | ||
| 16 | + // @see https://developer.android.com/training/articles/keystore | ||
| 17 | + private LoggedInUser user = null; | ||
| 18 | + | ||
| 19 | + // private constructor : singleton access | ||
| 20 | + private LoginRepository(LoginDataSource dataSource) { | ||
| 21 | + this.dataSource = dataSource; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + public static LoginRepository getInstance(LoginDataSource dataSource) { | ||
| 25 | + if (instance == null) { | ||
| 26 | + instance = new LoginRepository(dataSource); | ||
| 27 | + } | ||
| 28 | + return instance; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public boolean isLoggedIn() { | ||
| 32 | + return user != null; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public void logout() { | ||
| 36 | + user = null; | ||
| 37 | + dataSource.logout(); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + private void setLoggedInUser(LoggedInUser user) { | ||
| 41 | + this.user = user; | ||
| 42 | + // If user credentials will be cached in local storage, it is recommended it be encrypted | ||
| 43 | + // @see https://developer.android.com/training/articles/keystore | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + public Result<LoggedInUser> login(String username, String password) { | ||
| 47 | + // handle login | ||
| 48 | + Result<LoggedInUser> result = dataSource.login(username, password); | ||
| 49 | + if (result instanceof Result.Success) { | ||
| 50 | + setLoggedInUser(((Result.Success<LoggedInUser>) result).getData()); | ||
| 51 | + } | ||
| 52 | + return result; | ||
| 53 | + } | ||
| 54 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty.data; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * A generic class that holds a result success w/ data or an error exception. | ||
| 5 | + */ | ||
| 6 | +public class Result<T> { | ||
| 7 | + // hide the private constructor to limit subclass types (Success, Error) | ||
| 8 | + private Result() { | ||
| 9 | + } | ||
| 10 | + | ||
| 11 | + @Override | ||
| 12 | + public String toString() { | ||
| 13 | + if (this instanceof Result.Success) { | ||
| 14 | + Result.Success success = (Result.Success) this; | ||
| 15 | + return "Success[data=" + success.getData().toString() + "]"; | ||
| 16 | + } else if (this instanceof Result.Error) { | ||
| 17 | + Result.Error error = (Result.Error) this; | ||
| 18 | + return "Error[exception=" + error.getError().toString() + "]"; | ||
| 19 | + } | ||
| 20 | + return ""; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + // Success sub-class | ||
| 24 | + public final static class Success<T> extends Result { | ||
| 25 | + private T data; | ||
| 26 | + | ||
| 27 | + public Success(T data) { | ||
| 28 | + this.data = data; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public T getData() { | ||
| 32 | + return this.data; | ||
| 33 | + } | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + // Error sub-class | ||
| 37 | + public final static class Error extends Result { | ||
| 38 | + private Exception error; | ||
| 39 | + | ||
| 40 | + public Error(Exception error) { | ||
| 41 | + this.error = error; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + public Exception getError() { | ||
| 45 | + return this.error; | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty.data.model; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * Data class that captures user information for logged in users retrieved from LoginRepository | ||
| 5 | + */ | ||
| 6 | +public class LoggedInUser { | ||
| 7 | + | ||
| 8 | + private String userId; | ||
| 9 | + private String displayName; | ||
| 10 | + | ||
| 11 | + public LoggedInUser(String userId, String displayName) { | ||
| 12 | + this.userId = userId; | ||
| 13 | + this.displayName = displayName; | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + public String getUserId() { | ||
| 17 | + return userId; | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + public String getDisplayName() { | ||
| 21 | + return displayName; | ||
| 22 | + } | ||
| 23 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty; | ||
| 2 | + | ||
| 3 | +import androidx.appcompat.app.AppCompatActivity; | ||
| 4 | + | ||
| 5 | +import android.os.Bundle; | ||
| 6 | + | ||
| 7 | +public class itempage2 extends AppCompatActivity { | ||
| 8 | + | ||
| 9 | + @Override | ||
| 10 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 11 | + super.onCreate(savedInstanceState); | ||
| 12 | + setContentView(R.layout.activity_itempage2); | ||
| 13 | + } | ||
| 14 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty; | ||
| 2 | + | ||
| 3 | +import androidx.appcompat.app.AppCompatActivity; | ||
| 4 | + | ||
| 5 | +import android.os.Bundle; | ||
| 6 | + | ||
| 7 | +public class itemsPage extends AppCompatActivity { | ||
| 8 | + | ||
| 9 | + @Override | ||
| 10 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 11 | + super.onCreate(savedInstanceState); | ||
| 12 | + setContentView(R.layout.activity_items_page); | ||
| 13 | + } | ||
| 14 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty.ui.login; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * Class exposing authenticated user details to the UI. | ||
| 5 | + */ | ||
| 6 | +class LoggedInUserView { | ||
| 7 | + private String displayName; | ||
| 8 | + //... other data fields that may be accessible to the UI | ||
| 9 | + | ||
| 10 | + LoggedInUserView(String displayName) { | ||
| 11 | + this.displayName = displayName; | ||
| 12 | + } | ||
| 13 | + | ||
| 14 | + String getDisplayName() { | ||
| 15 | + return displayName; | ||
| 16 | + } | ||
| 17 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty.ui.login; | ||
| 2 | + | ||
| 3 | +import android.app.Activity; | ||
| 4 | + | ||
| 5 | +import androidx.lifecycle.Observer; | ||
| 6 | +import androidx.lifecycle.ViewModelProviders; | ||
| 7 | + | ||
| 8 | +import android.os.Bundle; | ||
| 9 | + | ||
| 10 | +import androidx.annotation.Nullable; | ||
| 11 | +import androidx.annotation.StringRes; | ||
| 12 | +import androidx.appcompat.app.AppCompatActivity; | ||
| 13 | + | ||
| 14 | +import android.text.Editable; | ||
| 15 | +import android.text.TextWatcher; | ||
| 16 | +import android.view.KeyEvent; | ||
| 17 | +import android.view.View; | ||
| 18 | +import android.view.inputmethod.EditorInfo; | ||
| 19 | +import android.widget.Button; | ||
| 20 | +import android.widget.EditText; | ||
| 21 | +import android.widget.ProgressBar; | ||
| 22 | +import android.widget.TextView; | ||
| 23 | +import android.widget.Toast; | ||
| 24 | + | ||
| 25 | +import com.example.trusty.R; | ||
| 26 | +import com.example.trusty.ui.login.LoginViewModel; | ||
| 27 | +import com.example.trusty.ui.login.LoginViewModelFactory; | ||
| 28 | + | ||
| 29 | +public class LoginActivity extends AppCompatActivity { | ||
| 30 | + | ||
| 31 | + private LoginViewModel loginViewModel; | ||
| 32 | + | ||
| 33 | + @Override | ||
| 34 | + public void onCreate(Bundle savedInstanceState) { | ||
| 35 | + super.onCreate(savedInstanceState); | ||
| 36 | + setContentView(R.layout.activity_login); | ||
| 37 | + loginViewModel = ViewModelProviders.of(this, new LoginViewModelFactory()) | ||
| 38 | + .get(LoginViewModel.class); | ||
| 39 | + | ||
| 40 | + final EditText usernameEditText = findViewById(R.id.username); | ||
| 41 | + final EditText passwordEditText = findViewById(R.id.password); | ||
| 42 | + final Button loginButton = findViewById(R.id.login); | ||
| 43 | + final ProgressBar loadingProgressBar = findViewById(R.id.loading); | ||
| 44 | + | ||
| 45 | + loginViewModel.getLoginFormState().observe(this, new Observer<LoginFormState>() { | ||
| 46 | + @Override | ||
| 47 | + public void onChanged(@Nullable LoginFormState loginFormState) { | ||
| 48 | + if (loginFormState == null) { | ||
| 49 | + return; | ||
| 50 | + } | ||
| 51 | + loginButton.setEnabled(loginFormState.isDataValid()); | ||
| 52 | + if (loginFormState.getUsernameError() != null) { | ||
| 53 | + usernameEditText.setError(getString(loginFormState.getUsernameError())); | ||
| 54 | + } | ||
| 55 | + if (loginFormState.getPasswordError() != null) { | ||
| 56 | + passwordEditText.setError(getString(loginFormState.getPasswordError())); | ||
| 57 | + } | ||
| 58 | + } | ||
| 59 | + }); | ||
| 60 | + | ||
| 61 | + loginViewModel.getLoginResult().observe(this, new Observer<LoginResult>() { | ||
| 62 | + @Override | ||
| 63 | + public void onChanged(@Nullable LoginResult loginResult) { | ||
| 64 | + if (loginResult == null) { | ||
| 65 | + return; | ||
| 66 | + } | ||
| 67 | + loadingProgressBar.setVisibility(View.GONE); | ||
| 68 | + if (loginResult.getError() != null) { | ||
| 69 | + showLoginFailed(loginResult.getError()); | ||
| 70 | + } | ||
| 71 | + if (loginResult.getSuccess() != null) { | ||
| 72 | + updateUiWithUser(loginResult.getSuccess()); | ||
| 73 | + } | ||
| 74 | + setResult(Activity.RESULT_OK); | ||
| 75 | + | ||
| 76 | + //Complete and destroy login activity once successful | ||
| 77 | + finish(); | ||
| 78 | + } | ||
| 79 | + }); | ||
| 80 | + | ||
| 81 | + TextWatcher afterTextChangedListener = new TextWatcher() { | ||
| 82 | + @Override | ||
| 83 | + public void beforeTextChanged(CharSequence s, int start, int count, int after) { | ||
| 84 | + // ignore | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + @Override | ||
| 88 | + public void onTextChanged(CharSequence s, int start, int before, int count) { | ||
| 89 | + // ignore | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + @Override | ||
| 93 | + public void afterTextChanged(Editable s) { | ||
| 94 | + loginViewModel.loginDataChanged(usernameEditText.getText().toString(), | ||
| 95 | + passwordEditText.getText().toString()); | ||
| 96 | + } | ||
| 97 | + }; | ||
| 98 | + usernameEditText.addTextChangedListener(afterTextChangedListener); | ||
| 99 | + passwordEditText.addTextChangedListener(afterTextChangedListener); | ||
| 100 | + passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { | ||
| 101 | + | ||
| 102 | + @Override | ||
| 103 | + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { | ||
| 104 | + if (actionId == EditorInfo.IME_ACTION_DONE) { | ||
| 105 | + loginViewModel.login(usernameEditText.getText().toString(), | ||
| 106 | + passwordEditText.getText().toString()); | ||
| 107 | + } | ||
| 108 | + return false; | ||
| 109 | + } | ||
| 110 | + }); | ||
| 111 | + | ||
| 112 | + loginButton.setOnClickListener(new View.OnClickListener() { | ||
| 113 | + @Override | ||
| 114 | + public void onClick(View v) { | ||
| 115 | + loadingProgressBar.setVisibility(View.VISIBLE); | ||
| 116 | + loginViewModel.login(usernameEditText.getText().toString(), | ||
| 117 | + passwordEditText.getText().toString()); | ||
| 118 | + } | ||
| 119 | + }); | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + private void updateUiWithUser(LoggedInUserView model) { | ||
| 123 | + String welcome = getString(R.string.welcome) + model.getDisplayName(); | ||
| 124 | + // TODO : initiate successful logged in experience | ||
| 125 | + Toast.makeText(getApplicationContext(), welcome, Toast.LENGTH_LONG).show(); | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + private void showLoginFailed(@StringRes Integer errorString) { | ||
| 129 | + Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_SHORT).show(); | ||
| 130 | + } | ||
| 131 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty.ui.login; | ||
| 2 | + | ||
| 3 | +import androidx.annotation.Nullable; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * Data validation state of the login form. | ||
| 7 | + */ | ||
| 8 | +class LoginFormState { | ||
| 9 | + @Nullable | ||
| 10 | + private Integer usernameError; | ||
| 11 | + @Nullable | ||
| 12 | + private Integer passwordError; | ||
| 13 | + private boolean isDataValid; | ||
| 14 | + | ||
| 15 | + LoginFormState(@Nullable Integer usernameError, @Nullable Integer passwordError) { | ||
| 16 | + this.usernameError = usernameError; | ||
| 17 | + this.passwordError = passwordError; | ||
| 18 | + this.isDataValid = false; | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + LoginFormState(boolean isDataValid) { | ||
| 22 | + this.usernameError = null; | ||
| 23 | + this.passwordError = null; | ||
| 24 | + this.isDataValid = isDataValid; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + @Nullable | ||
| 28 | + Integer getUsernameError() { | ||
| 29 | + return usernameError; | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + @Nullable | ||
| 33 | + Integer getPasswordError() { | ||
| 34 | + return passwordError; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + boolean isDataValid() { | ||
| 38 | + return isDataValid; | ||
| 39 | + } | ||
| 40 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty.ui.login; | ||
| 2 | + | ||
| 3 | +import androidx.annotation.Nullable; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * Authentication result : success (user details) or error message. | ||
| 7 | + */ | ||
| 8 | +class LoginResult { | ||
| 9 | + @Nullable | ||
| 10 | + private LoggedInUserView success; | ||
| 11 | + @Nullable | ||
| 12 | + private Integer error; | ||
| 13 | + | ||
| 14 | + LoginResult(@Nullable Integer error) { | ||
| 15 | + this.error = error; | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + LoginResult(@Nullable LoggedInUserView success) { | ||
| 19 | + this.success = success; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + @Nullable | ||
| 23 | + LoggedInUserView getSuccess() { | ||
| 24 | + return success; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + @Nullable | ||
| 28 | + Integer getError() { | ||
| 29 | + return error; | ||
| 30 | + } | ||
| 31 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty.ui.login; | ||
| 2 | + | ||
| 3 | +import androidx.lifecycle.LiveData; | ||
| 4 | +import androidx.lifecycle.MutableLiveData; | ||
| 5 | +import androidx.lifecycle.ViewModel; | ||
| 6 | + | ||
| 7 | +import android.util.Patterns; | ||
| 8 | + | ||
| 9 | +import com.example.trusty.data.LoginRepository; | ||
| 10 | +import com.example.trusty.data.Result; | ||
| 11 | +import com.example.trusty.data.model.LoggedInUser; | ||
| 12 | +import com.example.trusty.R; | ||
| 13 | + | ||
| 14 | +public class LoginViewModel extends ViewModel { | ||
| 15 | + | ||
| 16 | + private MutableLiveData<LoginFormState> loginFormState = new MutableLiveData<>(); | ||
| 17 | + private MutableLiveData<LoginResult> loginResult = new MutableLiveData<>(); | ||
| 18 | + private LoginRepository loginRepository; | ||
| 19 | + | ||
| 20 | + LoginViewModel(LoginRepository loginRepository) { | ||
| 21 | + this.loginRepository = loginRepository; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + LiveData<LoginFormState> getLoginFormState() { | ||
| 25 | + return loginFormState; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + LiveData<LoginResult> getLoginResult() { | ||
| 29 | + return loginResult; | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + public void login(String username, String password) { | ||
| 33 | + // can be launched in a separate asynchronous job | ||
| 34 | + Result<LoggedInUser> result = loginRepository.login(username, password); | ||
| 35 | + | ||
| 36 | + if (result instanceof Result.Success) { | ||
| 37 | + LoggedInUser data = ((Result.Success<LoggedInUser>) result).getData(); | ||
| 38 | + loginResult.setValue(new LoginResult(new LoggedInUserView(data.getDisplayName()))); | ||
| 39 | + } else { | ||
| 40 | + loginResult.setValue(new LoginResult(R.string.login_failed)); | ||
| 41 | + } | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + public void loginDataChanged(String username, String password) { | ||
| 45 | + if (!isUserNameValid(username)) { | ||
| 46 | + loginFormState.setValue(new LoginFormState(R.string.invalid_username, null)); | ||
| 47 | + } else if (!isPasswordValid(password)) { | ||
| 48 | + loginFormState.setValue(new LoginFormState(null, R.string.invalid_password)); | ||
| 49 | + } else { | ||
| 50 | + loginFormState.setValue(new LoginFormState(true)); | ||
| 51 | + } | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + // A placeholder username validation check | ||
| 55 | + private boolean isUserNameValid(String username) { | ||
| 56 | + if (username == null) { | ||
| 57 | + return false; | ||
| 58 | + } | ||
| 59 | + if (username.contains("@")) { | ||
| 60 | + return Patterns.EMAIL_ADDRESS.matcher(username).matches(); | ||
| 61 | + } else { | ||
| 62 | + return !username.trim().isEmpty(); | ||
| 63 | + } | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + // A placeholder password validation check | ||
| 67 | + private boolean isPasswordValid(String password) { | ||
| 68 | + return password != null && password.trim().length() > 5; | ||
| 69 | + } | ||
| 70 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty.ui.login; | ||
| 2 | + | ||
| 3 | +import androidx.lifecycle.ViewModel; | ||
| 4 | +import androidx.lifecycle.ViewModelProvider; | ||
| 5 | +import androidx.annotation.NonNull; | ||
| 6 | + | ||
| 7 | +import com.example.trusty.data.LoginDataSource; | ||
| 8 | +import com.example.trusty.data.LoginRepository; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * ViewModel provider factory to instantiate LoginViewModel. | ||
| 12 | + * Required given LoginViewModel has a non-empty constructor | ||
| 13 | + */ | ||
| 14 | +public class LoginViewModelFactory implements ViewModelProvider.Factory { | ||
| 15 | + | ||
| 16 | + @NonNull | ||
| 17 | + @Override | ||
| 18 | + @SuppressWarnings("unchecked") | ||
| 19 | + public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { | ||
| 20 | + if (modelClass.isAssignableFrom(LoginViewModel.class)) { | ||
| 21 | + return (T) new LoginViewModel(LoginRepository.getInstance(new LoginDataSource())); | ||
| 22 | + } else { | ||
| 23 | + throw new IllegalArgumentException("Unknown ViewModel class"); | ||
| 24 | + } | ||
| 25 | + } | ||
| 26 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
531 KB
app/src/main/res/drawable-v24/ex.png
0 → 100644
748 KB
app/src/main/res/drawable-v24/fullstar_t.png
0 → 100644
5.36 KB
| 1 | +<vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 2 | + xmlns:aapt="http://schemas.android.com/aapt" | ||
| 3 | + android:width="108dp" | ||
| 4 | + android:height="108dp" | ||
| 5 | + android:viewportWidth="108" | ||
| 6 | + android:viewportHeight="108"> | ||
| 7 | + <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"> | ||
| 8 | + <aapt:attr name="android:fillColor"> | ||
| 9 | + <gradient | ||
| 10 | + android:endX="85.84757" | ||
| 11 | + android:endY="92.4963" | ||
| 12 | + android:startX="42.9492" | ||
| 13 | + android:startY="49.59793" | ||
| 14 | + android:type="linear"> | ||
| 15 | + <item | ||
| 16 | + android:color="#44000000" | ||
| 17 | + android:offset="0.0" /> | ||
| 18 | + <item | ||
| 19 | + android:color="#00000000" | ||
| 20 | + android:offset="1.0" /> | ||
| 21 | + </gradient> | ||
| 22 | + </aapt:attr> | ||
| 23 | + </path> | ||
| 24 | + <path | ||
| 25 | + android:fillColor="#FFFFFF" | ||
| 26 | + android:fillType="nonZero" | ||
| 27 | + android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" | ||
| 28 | + android:strokeWidth="1" | ||
| 29 | + android:strokeColor="#00000000" /> | ||
| 30 | +</vector> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
532 KB
No preview for this file type
app/src/main/res/drawable-v24/login_t.png
0 → 100644
515 KB
app/src/main/res/drawable-v24/logo_icon.png
0 → 100644
31.5 KB
25.5 KB
app/src/main/res/drawable-v24/source_2.jpg
0 → 100644
51.9 KB
app/src/main/res/drawable-v24/splash_t.png
0 → 100644
126 KB
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + android:width="108dp" | ||
| 4 | + android:height="108dp" | ||
| 5 | + android:viewportWidth="108" | ||
| 6 | + android:viewportHeight="108"> | ||
| 7 | + <path | ||
| 8 | + android:fillColor="#3DDC84" | ||
| 9 | + android:pathData="M0,0h108v108h-108z" /> | ||
| 10 | + <path | ||
| 11 | + android:fillColor="#00000000" | ||
| 12 | + android:pathData="M9,0L9,108" | ||
| 13 | + android:strokeWidth="0.8" | ||
| 14 | + android:strokeColor="#33FFFFFF" /> | ||
| 15 | + <path | ||
| 16 | + android:fillColor="#00000000" | ||
| 17 | + android:pathData="M19,0L19,108" | ||
| 18 | + android:strokeWidth="0.8" | ||
| 19 | + android:strokeColor="#33FFFFFF" /> | ||
| 20 | + <path | ||
| 21 | + android:fillColor="#00000000" | ||
| 22 | + android:pathData="M29,0L29,108" | ||
| 23 | + android:strokeWidth="0.8" | ||
| 24 | + android:strokeColor="#33FFFFFF" /> | ||
| 25 | + <path | ||
| 26 | + android:fillColor="#00000000" | ||
| 27 | + android:pathData="M39,0L39,108" | ||
| 28 | + android:strokeWidth="0.8" | ||
| 29 | + android:strokeColor="#33FFFFFF" /> | ||
| 30 | + <path | ||
| 31 | + android:fillColor="#00000000" | ||
| 32 | + android:pathData="M49,0L49,108" | ||
| 33 | + android:strokeWidth="0.8" | ||
| 34 | + android:strokeColor="#33FFFFFF" /> | ||
| 35 | + <path | ||
| 36 | + android:fillColor="#00000000" | ||
| 37 | + android:pathData="M59,0L59,108" | ||
| 38 | + android:strokeWidth="0.8" | ||
| 39 | + android:strokeColor="#33FFFFFF" /> | ||
| 40 | + <path | ||
| 41 | + android:fillColor="#00000000" | ||
| 42 | + android:pathData="M69,0L69,108" | ||
| 43 | + android:strokeWidth="0.8" | ||
| 44 | + android:strokeColor="#33FFFFFF" /> | ||
| 45 | + <path | ||
| 46 | + android:fillColor="#00000000" | ||
| 47 | + android:pathData="M79,0L79,108" | ||
| 48 | + android:strokeWidth="0.8" | ||
| 49 | + android:strokeColor="#33FFFFFF" /> | ||
| 50 | + <path | ||
| 51 | + android:fillColor="#00000000" | ||
| 52 | + android:pathData="M89,0L89,108" | ||
| 53 | + android:strokeWidth="0.8" | ||
| 54 | + android:strokeColor="#33FFFFFF" /> | ||
| 55 | + <path | ||
| 56 | + android:fillColor="#00000000" | ||
| 57 | + android:pathData="M99,0L99,108" | ||
| 58 | + android:strokeWidth="0.8" | ||
| 59 | + android:strokeColor="#33FFFFFF" /> | ||
| 60 | + <path | ||
| 61 | + android:fillColor="#00000000" | ||
| 62 | + android:pathData="M0,9L108,9" | ||
| 63 | + android:strokeWidth="0.8" | ||
| 64 | + android:strokeColor="#33FFFFFF" /> | ||
| 65 | + <path | ||
| 66 | + android:fillColor="#00000000" | ||
| 67 | + android:pathData="M0,19L108,19" | ||
| 68 | + android:strokeWidth="0.8" | ||
| 69 | + android:strokeColor="#33FFFFFF" /> | ||
| 70 | + <path | ||
| 71 | + android:fillColor="#00000000" | ||
| 72 | + android:pathData="M0,29L108,29" | ||
| 73 | + android:strokeWidth="0.8" | ||
| 74 | + android:strokeColor="#33FFFFFF" /> | ||
| 75 | + <path | ||
| 76 | + android:fillColor="#00000000" | ||
| 77 | + android:pathData="M0,39L108,39" | ||
| 78 | + android:strokeWidth="0.8" | ||
| 79 | + android:strokeColor="#33FFFFFF" /> | ||
| 80 | + <path | ||
| 81 | + android:fillColor="#00000000" | ||
| 82 | + android:pathData="M0,49L108,49" | ||
| 83 | + android:strokeWidth="0.8" | ||
| 84 | + android:strokeColor="#33FFFFFF" /> | ||
| 85 | + <path | ||
| 86 | + android:fillColor="#00000000" | ||
| 87 | + android:pathData="M0,59L108,59" | ||
| 88 | + android:strokeWidth="0.8" | ||
| 89 | + android:strokeColor="#33FFFFFF" /> | ||
| 90 | + <path | ||
| 91 | + android:fillColor="#00000000" | ||
| 92 | + android:pathData="M0,69L108,69" | ||
| 93 | + android:strokeWidth="0.8" | ||
| 94 | + android:strokeColor="#33FFFFFF" /> | ||
| 95 | + <path | ||
| 96 | + android:fillColor="#00000000" | ||
| 97 | + android:pathData="M0,79L108,79" | ||
| 98 | + android:strokeWidth="0.8" | ||
| 99 | + android:strokeColor="#33FFFFFF" /> | ||
| 100 | + <path | ||
| 101 | + android:fillColor="#00000000" | ||
| 102 | + android:pathData="M0,89L108,89" | ||
| 103 | + android:strokeWidth="0.8" | ||
| 104 | + android:strokeColor="#33FFFFFF" /> | ||
| 105 | + <path | ||
| 106 | + android:fillColor="#00000000" | ||
| 107 | + android:pathData="M0,99L108,99" | ||
| 108 | + android:strokeWidth="0.8" | ||
| 109 | + android:strokeColor="#33FFFFFF" /> | ||
| 110 | + <path | ||
| 111 | + android:fillColor="#00000000" | ||
| 112 | + android:pathData="M19,29L89,29" | ||
| 113 | + android:strokeWidth="0.8" | ||
| 114 | + android:strokeColor="#33FFFFFF" /> | ||
| 115 | + <path | ||
| 116 | + android:fillColor="#00000000" | ||
| 117 | + android:pathData="M19,39L89,39" | ||
| 118 | + android:strokeWidth="0.8" | ||
| 119 | + android:strokeColor="#33FFFFFF" /> | ||
| 120 | + <path | ||
| 121 | + android:fillColor="#00000000" | ||
| 122 | + android:pathData="M19,49L89,49" | ||
| 123 | + android:strokeWidth="0.8" | ||
| 124 | + android:strokeColor="#33FFFFFF" /> | ||
| 125 | + <path | ||
| 126 | + android:fillColor="#00000000" | ||
| 127 | + android:pathData="M19,59L89,59" | ||
| 128 | + android:strokeWidth="0.8" | ||
| 129 | + android:strokeColor="#33FFFFFF" /> | ||
| 130 | + <path | ||
| 131 | + android:fillColor="#00000000" | ||
| 132 | + android:pathData="M19,69L89,69" | ||
| 133 | + android:strokeWidth="0.8" | ||
| 134 | + android:strokeColor="#33FFFFFF" /> | ||
| 135 | + <path | ||
| 136 | + android:fillColor="#00000000" | ||
| 137 | + android:pathData="M19,79L89,79" | ||
| 138 | + android:strokeWidth="0.8" | ||
| 139 | + android:strokeColor="#33FFFFFF" /> | ||
| 140 | + <path | ||
| 141 | + android:fillColor="#00000000" | ||
| 142 | + android:pathData="M29,19L29,89" | ||
| 143 | + android:strokeWidth="0.8" | ||
| 144 | + android:strokeColor="#33FFFFFF" /> | ||
| 145 | + <path | ||
| 146 | + android:fillColor="#00000000" | ||
| 147 | + android:pathData="M39,19L39,89" | ||
| 148 | + android:strokeWidth="0.8" | ||
| 149 | + android:strokeColor="#33FFFFFF" /> | ||
| 150 | + <path | ||
| 151 | + android:fillColor="#00000000" | ||
| 152 | + android:pathData="M49,19L49,89" | ||
| 153 | + android:strokeWidth="0.8" | ||
| 154 | + android:strokeColor="#33FFFFFF" /> | ||
| 155 | + <path | ||
| 156 | + android:fillColor="#00000000" | ||
| 157 | + android:pathData="M59,19L59,89" | ||
| 158 | + android:strokeWidth="0.8" | ||
| 159 | + android:strokeColor="#33FFFFFF" /> | ||
| 160 | + <path | ||
| 161 | + android:fillColor="#00000000" | ||
| 162 | + android:pathData="M69,19L69,89" | ||
| 163 | + android:strokeWidth="0.8" | ||
| 164 | + android:strokeColor="#33FFFFFF" /> | ||
| 165 | + <path | ||
| 166 | + android:fillColor="#00000000" | ||
| 167 | + android:pathData="M79,19L79,89" | ||
| 168 | + android:strokeWidth="0.8" | ||
| 169 | + android:strokeColor="#33FFFFFF" /> | ||
| 170 | +</vector> |
app/src/main/res/font/applegothic.ttf
0 → 100644
No preview for this file type
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| 4 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 5 | + android:layout_width="match_parent" | ||
| 6 | + android:layout_height="match_parent" | ||
| 7 | + android:orientation="vertical" | ||
| 8 | + tools:context=".itemsPage"> | ||
| 9 | + | ||
| 10 | + <LinearLayout | ||
| 11 | + android:layout_width="match_parent" | ||
| 12 | + android:layout_height="wrap_content" | ||
| 13 | + android:orientation="vertical" | ||
| 14 | + android:background="#3800b3" | ||
| 15 | + > | ||
| 16 | + | ||
| 17 | + <ImageView | ||
| 18 | + android:layout_width="match_parent" | ||
| 19 | + android:layout_height="116dp" | ||
| 20 | + android:src="@drawable/comp_header_t" | ||
| 21 | + app:layout_constraintBottom_toBottomOf="parent" | ||
| 22 | + tools:layout_editor_absoluteX="-14dp"></ImageView> | ||
| 23 | + | ||
| 24 | + </LinearLayout> | ||
| 25 | + | ||
| 26 | + <LinearLayout | ||
| 27 | + android:layout_width="wrap_content" | ||
| 28 | + android:layout_height="wrap_content" | ||
| 29 | + android:orientation="horizontal" | ||
| 30 | + android:background="@color/cardview_light_background"> | ||
| 31 | + | ||
| 32 | + <TextView | ||
| 33 | + android:layout_width="wrap_content" | ||
| 34 | + android:layout_height="wrap_content" | ||
| 35 | + android:layout_marginLeft="@dimen/activity_horizontal_margin" | ||
| 36 | + android:layout_marginTop="@dimen/activity_vertical_margin" | ||
| 37 | + android:layout_marginRight="@dimen/activity_vertical_margin" | ||
| 38 | + android:fontFamily="@font/applegothic" | ||
| 39 | + android:text="관심제품\n(hearts)" | ||
| 40 | + android:gravity="center" | ||
| 41 | + android:textSize="20dp"> | ||
| 42 | + | ||
| 43 | + </TextView> | ||
| 44 | + | ||
| 45 | + <ImageView | ||
| 46 | + android:layout_width="161dp" | ||
| 47 | + android:layout_height="80dp" | ||
| 48 | + android:src="@drawable/source_2"></ImageView> | ||
| 49 | + | ||
| 50 | + <ImageView | ||
| 51 | + android:layout_width="145dp" | ||
| 52 | + android:layout_height="80dp" | ||
| 53 | + android:src="@drawable/sample_item_image"></ImageView> | ||
| 54 | + | ||
| 55 | + </LinearLayout> | ||
| 56 | + | ||
| 57 | + <ScrollView | ||
| 58 | + android:layout_width="match_parent" | ||
| 59 | + android:layout_height="match_parent"> | ||
| 60 | + | ||
| 61 | + <LinearLayout | ||
| 62 | + android:layout_width="wrap_content" | ||
| 63 | + android:layout_height="wrap_content" | ||
| 64 | + android:orientation="horizontal"> | ||
| 65 | + | ||
| 66 | + <TextView | ||
| 67 | + android:layout_width="wrap_content" | ||
| 68 | + android:layout_height="wrap_content" | ||
| 69 | + android:layout_marginLeft="@dimen/activity_horizontal_margin" | ||
| 70 | + android:gravity="center" | ||
| 71 | + android:layout_marginTop="@dimen/activity_vertical_margin" | ||
| 72 | + android:fontFamily="@font/applegothic" | ||
| 73 | + android:textSize="20dp" | ||
| 74 | + android:text="가격\n\n\n태그\n\n\n별점\n\n\n유해물질\n\n\n리뷰\n\n\n항목1\n\n\n항목2\n\n\n항목3\n\n\n항목4\n\n항목5"></TextView> | ||
| 75 | + <TextView | ||
| 76 | + android:layout_width="wrap_content" | ||
| 77 | + android:layout_height="wrap_content" | ||
| 78 | + android:layout_marginLeft="55dp" | ||
| 79 | + android:gravity="center" | ||
| 80 | + android:layout_marginTop="@dimen/activity_vertical_margin" | ||
| 81 | + android:fontFamily="@font/applegothic" | ||
| 82 | + android:textSize="20dp" | ||
| 83 | + android:text="350원\n\n\n2개 일치\n\n\n4.7점\n\n\n유해물질\n없음\n\n리뷰보기\n\n\n항목1\n\n\n항목2\n\n\n항목3\n\n\n항목4\n\n항목5"></TextView> | ||
| 84 | + <TextView | ||
| 85 | + android:layout_width="wrap_content" | ||
| 86 | + android:layout_height="wrap_content" | ||
| 87 | + android:layout_marginLeft="75dp" | ||
| 88 | + android:gravity="center" | ||
| 89 | + android:layout_marginTop="@dimen/activity_vertical_margin" | ||
| 90 | + android:fontFamily="@font/applegothic" | ||
| 91 | + android:textSize="20dp" | ||
| 92 | + android:text="400원\n\n\n3개 일치\n\n\n4.6\n\n\n유해물질\n없음\n\n리뷰보기\n\n\n항목1\n\n\n항목2\n\n\n항목3\n\n\n항목4\n\n항목5"></TextView> | ||
| 93 | + </LinearLayout> | ||
| 94 | + | ||
| 95 | + </ScrollView> | ||
| 96 | + | ||
| 97 | + | ||
| 98 | +</LinearLayout> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| 4 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 5 | + android:layout_width="match_parent" | ||
| 6 | + android:layout_height="match_parent" | ||
| 7 | + android:orientation="vertical" | ||
| 8 | + tools:context=".itemsPage"> | ||
| 9 | + | ||
| 10 | + <LinearLayout | ||
| 11 | + android:layout_width="match_parent" | ||
| 12 | + android:layout_height="wrap_content" | ||
| 13 | + android:orientation="vertical" | ||
| 14 | + android:background="#3800b3"> | ||
| 15 | + | ||
| 16 | + <ImageView | ||
| 17 | + android:layout_width="match_parent" | ||
| 18 | + android:layout_height="115dp" | ||
| 19 | + android:src="@drawable/item_header_t" | ||
| 20 | + app:layout_constraintBottom_toBottomOf="parent" | ||
| 21 | + tools:layout_editor_absoluteX="-14dp"></ImageView> | ||
| 22 | + | ||
| 23 | + </LinearLayout> | ||
| 24 | + | ||
| 25 | + <LinearLayout | ||
| 26 | + android:layout_width="match_parent" | ||
| 27 | + android:layout_height="450dp" | ||
| 28 | + android:orientation="vertical"> | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + <ImageView | ||
| 32 | + android:layout_width="match_parent" | ||
| 33 | + android:layout_height="324dp" | ||
| 34 | + android:src="@drawable/source_2"> | ||
| 35 | + | ||
| 36 | + </ImageView> | ||
| 37 | + | ||
| 38 | + <LinearLayout | ||
| 39 | + android:layout_width="match_parent" | ||
| 40 | + android:layout_height="wrap_content" | ||
| 41 | + android:layout_marginTop="@dimen/activity_horizontal_margin" | ||
| 42 | + android:gravity="center|right" | ||
| 43 | + android:orientation="horizontal"> | ||
| 44 | + | ||
| 45 | + <TextView | ||
| 46 | + android:layout_width="wrap_content" | ||
| 47 | + android:layout_height="wrap_content" | ||
| 48 | + android:text="BRAND [유한킴벌리] "></TextView> | ||
| 49 | + | ||
| 50 | + <Button | ||
| 51 | + android:layout_width="67dp" | ||
| 52 | + android:layout_height="22dp" | ||
| 53 | + android:background="#E1E4C0" | ||
| 54 | + android:text="구독하기"></Button> | ||
| 55 | + | ||
| 56 | + <Button | ||
| 57 | + android:layout_width="wrap_content" | ||
| 58 | + android:layout_height="22dp" | ||
| 59 | + android:background="#FFFFFF" | ||
| 60 | + android:text="찜하기"></Button> | ||
| 61 | + | ||
| 62 | + | ||
| 63 | + </LinearLayout> | ||
| 64 | + | ||
| 65 | + <LinearLayout | ||
| 66 | + android:layout_width="match_parent" | ||
| 67 | + android:layout_height="102dp" | ||
| 68 | + android:gravity="center" | ||
| 69 | + android:orientation="vertical"> | ||
| 70 | + | ||
| 71 | + <TextView | ||
| 72 | + android:layout_width="match_parent" | ||
| 73 | + android:layout_height="wrap_content" | ||
| 74 | + android:gravity="center" | ||
| 75 | + android:text="좋은순면 중형" | ||
| 76 | + android:fontFamily="@font/applegothic" | ||
| 77 | + android:textSize="30dp"></TextView> | ||
| 78 | + | ||
| 79 | + <LinearLayout | ||
| 80 | + android:layout_width="wrap_content" | ||
| 81 | + android:layout_height="wrap_content" | ||
| 82 | + android:orientation="horizontal"> | ||
| 83 | + | ||
| 84 | + <TextView | ||
| 85 | + android:layout_width="wrap_content" | ||
| 86 | + android:layout_height="wrap_content" | ||
| 87 | + android:text="18개입"></TextView> | ||
| 88 | + | ||
| 89 | + <TextView | ||
| 90 | + android:layout_width="wrap_content" | ||
| 91 | + android:layout_height="wrap_content" | ||
| 92 | + android:text=" 5600원"></TextView> | ||
| 93 | + </LinearLayout> | ||
| 94 | + | ||
| 95 | + <LinearLayout | ||
| 96 | + android:layout_width="wrap_content" | ||
| 97 | + android:layout_height="wrap_content" | ||
| 98 | + android:orientation="horizontal"> | ||
| 99 | + | ||
| 100 | + <TextView | ||
| 101 | + android:layout_width="wrap_content" | ||
| 102 | + android:layout_height="wrap_content" | ||
| 103 | + android:layout_marginRight="@dimen/activity_horizontal_margin" | ||
| 104 | + android:text="#부드러운" | ||
| 105 | + android:textStyle="bold" | ||
| 106 | + android:textColor="#3e2e86"></TextView> | ||
| 107 | + <TextView | ||
| 108 | + android:layout_width="wrap_content" | ||
| 109 | + android:layout_height="wrap_content" | ||
| 110 | + android:text="#발암물질없는" | ||
| 111 | + android:textStyle="bold" | ||
| 112 | + android:textColor="#3e2e86"></TextView> | ||
| 113 | + | ||
| 114 | + </LinearLayout> | ||
| 115 | + | ||
| 116 | + | ||
| 117 | + </LinearLayout> | ||
| 118 | + | ||
| 119 | + </LinearLayout> | ||
| 120 | + | ||
| 121 | + <LinearLayout | ||
| 122 | + android:layout_width="376dp" | ||
| 123 | + android:layout_height="171dp" | ||
| 124 | + android:layout_margin="@dimen/activity_vertical_margin" | ||
| 125 | + android:orientation="vertical" | ||
| 126 | + > | ||
| 127 | + | ||
| 128 | + <TextView | ||
| 129 | + android:layout_width="match_parent" | ||
| 130 | + android:layout_height="wrap_content" | ||
| 131 | + android:gravity="center" | ||
| 132 | + android:text="김예희님 맞춤정보" | ||
| 133 | + android:fontFamily="@font/applegothic" | ||
| 134 | + android:textSize="18dp" | ||
| 135 | + android:textStyle="bold"></TextView> | ||
| 136 | + | ||
| 137 | + <TextView | ||
| 138 | + android:layout_width="wrap_content" | ||
| 139 | + android:layout_height="wrap_content" | ||
| 140 | + android:text="\n해당 제품은 김예희님의 선택 태그 중 1개와 일치해요 :)"></TextView> | ||
| 141 | + | ||
| 142 | + <TextView | ||
| 143 | + android:layout_width="wrap_content" | ||
| 144 | + android:layout_height="wrap_content" | ||
| 145 | + android:text="#부드러운" | ||
| 146 | + android:textStyle="italic | ||
| 147 | +"></TextView> | ||
| 148 | + | ||
| 149 | + <LinearLayout | ||
| 150 | + android:layout_width="wrap_content" | ||
| 151 | + android:layout_height="wrap_content" | ||
| 152 | + android:orientation="horizontal"> | ||
| 153 | + | ||
| 154 | + <TextView | ||
| 155 | + android:layout_width="wrap_content" | ||
| 156 | + android:layout_height="wrap_content" | ||
| 157 | + android:text="해당 제품은 20가지 주의 성분이 "></TextView> | ||
| 158 | + | ||
| 159 | + <TextView | ||
| 160 | + android:layout_width="wrap_content" | ||
| 161 | + android:layout_height="wrap_content" | ||
| 162 | + android:text="3"></TextView> | ||
| 163 | + | ||
| 164 | + <TextView | ||
| 165 | + android:layout_width="wrap_content" | ||
| 166 | + android:layout_height="wrap_content" | ||
| 167 | + android:text="개,"></TextView> | ||
| 168 | + </LinearLayout> | ||
| 169 | + | ||
| 170 | + <LinearLayout | ||
| 171 | + android:layout_width="wrap_content" | ||
| 172 | + android:layout_height="wrap_content" | ||
| 173 | + android:orientation="horizontal"> | ||
| 174 | + | ||
| 175 | + <TextView | ||
| 176 | + android:layout_width="wrap_content" | ||
| 177 | + android:layout_height="wrap_content" | ||
| 178 | + android:text="전성분은 "></TextView> | ||
| 179 | + | ||
| 180 | + <TextView | ||
| 181 | + android:layout_width="wrap_content" | ||
| 182 | + android:layout_height="wrap_content" | ||
| 183 | + android:text="1"></TextView> | ||
| 184 | + | ||
| 185 | + <TextView | ||
| 186 | + android:layout_width="wrap_content" | ||
| 187 | + android:layout_height="wrap_content" | ||
| 188 | + android:text="개"></TextView> | ||
| 189 | + | ||
| 190 | + <TextView | ||
| 191 | + android:layout_width="wrap_content" | ||
| 192 | + android:layout_height="wrap_content" | ||
| 193 | + android:text=" 있어요!"></TextView> | ||
| 194 | + </LinearLayout> | ||
| 195 | + | ||
| 196 | + </LinearLayout> | ||
| 197 | + | ||
| 198 | + <Button | ||
| 199 | + android:id="@+id/button" | ||
| 200 | + android:layout_width="match_parent" | ||
| 201 | + android:layout_height="40dp" | ||
| 202 | + android:background="#3E2E86" | ||
| 203 | + android:text="sample 구독" | ||
| 204 | + android:fontFamily="@font/applegothic" | ||
| 205 | + android:textColor="#FFFFFF" | ||
| 206 | + android:textSize="14sp"></Button> | ||
| 207 | + | ||
| 208 | +</LinearLayout> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| 4 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 5 | + android:layout_width="match_parent" | ||
| 6 | + android:layout_height="match_parent" | ||
| 7 | + android:orientation="vertical" | ||
| 8 | + tools:context=".itemsPage"> | ||
| 9 | + | ||
| 10 | + <LinearLayout | ||
| 11 | + android:layout_width="match_parent" | ||
| 12 | + android:layout_height="wrap_content" | ||
| 13 | + android:orientation="vertical" | ||
| 14 | + android:background="#3800b3"> | ||
| 15 | + | ||
| 16 | + <ImageView | ||
| 17 | + android:layout_width="match_parent" | ||
| 18 | + android:layout_height="115dp" | ||
| 19 | + android:src="@drawable/item_header_t" | ||
| 20 | + app:layout_constraintBottom_toBottomOf="parent" | ||
| 21 | + tools:layout_editor_absoluteX="-14dp"></ImageView> | ||
| 22 | + | ||
| 23 | + </LinearLayout> | ||
| 24 | + | ||
| 25 | + <LinearLayout | ||
| 26 | + android:layout_width="match_parent" | ||
| 27 | + android:layout_height="450dp" | ||
| 28 | + android:orientation="vertical"> | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + <ImageView | ||
| 32 | + android:layout_width="match_parent" | ||
| 33 | + android:layout_height="324dp" | ||
| 34 | + android:src="@drawable/sample_item_image"> | ||
| 35 | + | ||
| 36 | + </ImageView> | ||
| 37 | + | ||
| 38 | + <LinearLayout | ||
| 39 | + android:layout_width="match_parent" | ||
| 40 | + android:layout_height="wrap_content" | ||
| 41 | + android:gravity="center|right" | ||
| 42 | + android:orientation="horizontal" | ||
| 43 | + android:layout_marginTop="@dimen/activity_horizontal_margin"> | ||
| 44 | + | ||
| 45 | + <TextView | ||
| 46 | + android:layout_width="wrap_content" | ||
| 47 | + android:layout_height="wrap_content" | ||
| 48 | + android:text="BRAND [cotton] "></TextView> | ||
| 49 | + | ||
| 50 | + <Button | ||
| 51 | + android:layout_width="71dp" | ||
| 52 | + android:layout_height="22dp" | ||
| 53 | + android:background="#E1E4C0" | ||
| 54 | + android:text="구독하기"></Button> | ||
| 55 | + | ||
| 56 | + <Button | ||
| 57 | + android:layout_width="wrap_content" | ||
| 58 | + android:layout_height="22dp" | ||
| 59 | + android:background="#FFFFFF" | ||
| 60 | + android:text="찜하기"></Button> | ||
| 61 | + | ||
| 62 | + | ||
| 63 | + </LinearLayout> | ||
| 64 | + | ||
| 65 | + <LinearLayout | ||
| 66 | + android:layout_width="match_parent" | ||
| 67 | + android:layout_height="102dp" | ||
| 68 | + android:gravity="center" | ||
| 69 | + android:orientation="vertical"> | ||
| 70 | + | ||
| 71 | + <TextView | ||
| 72 | + android:layout_width="match_parent" | ||
| 73 | + android:layout_height="wrap_content" | ||
| 74 | + android:gravity="center" | ||
| 75 | + android:text="Organic Pads 중형" | ||
| 76 | + android:fontFamily="@font/applegothic" | ||
| 77 | + android:textSize="30dp"></TextView> | ||
| 78 | + | ||
| 79 | + <LinearLayout | ||
| 80 | + android:layout_width="wrap_content" | ||
| 81 | + android:layout_height="wrap_content" | ||
| 82 | + android:orientation="horizontal"> | ||
| 83 | + | ||
| 84 | + <TextView | ||
| 85 | + android:layout_width="wrap_content" | ||
| 86 | + android:layout_height="wrap_content" | ||
| 87 | + android:text="12개입"></TextView> | ||
| 88 | + | ||
| 89 | + <TextView | ||
| 90 | + android:layout_width="wrap_content" | ||
| 91 | + android:layout_height="wrap_content" | ||
| 92 | + android:text=" 7400원"></TextView> | ||
| 93 | + </LinearLayout> | ||
| 94 | + | ||
| 95 | + <LinearLayout | ||
| 96 | + android:layout_width="wrap_content" | ||
| 97 | + android:layout_height="wrap_content" | ||
| 98 | + android:orientation="horizontal"> | ||
| 99 | + | ||
| 100 | + <TextView | ||
| 101 | + android:layout_width="wrap_content" | ||
| 102 | + android:layout_height="wrap_content" | ||
| 103 | + android:layout_marginRight="@dimen/activity_horizontal_margin" | ||
| 104 | + android:text="#유기농" | ||
| 105 | + android:textStyle="bold" | ||
| 106 | + android:textColor="#3e2e86"></TextView> | ||
| 107 | + <TextView | ||
| 108 | + android:layout_width="wrap_content" | ||
| 109 | + android:layout_height="wrap_content" | ||
| 110 | + android:layout_marginRight="@dimen/activity_horizontal_margin" | ||
| 111 | + android:text="#발암물질없는" | ||
| 112 | + android:textStyle="bold" | ||
| 113 | + android:textColor="#3e2e86"></TextView> | ||
| 114 | + <TextView | ||
| 115 | + android:layout_width="wrap_content" | ||
| 116 | + android:layout_height="wrap_content" | ||
| 117 | + android:layout_marginRight="@dimen/activity_horizontal_margin" | ||
| 118 | + android:text="#TR_BEST" | ||
| 119 | + android:textStyle="bold" | ||
| 120 | + android:textColor="#3e2e86"></TextView> | ||
| 121 | + <TextView | ||
| 122 | + android:layout_width="wrap_content" | ||
| 123 | + android:layout_height="wrap_content" | ||
| 124 | + android:text="#저렴한" | ||
| 125 | + android:textStyle="bold" | ||
| 126 | + android:textColor="#3e2e86"></TextView> | ||
| 127 | + </LinearLayout> | ||
| 128 | + | ||
| 129 | + | ||
| 130 | + </LinearLayout> | ||
| 131 | + | ||
| 132 | + </LinearLayout> | ||
| 133 | + | ||
| 134 | + <LinearLayout | ||
| 135 | + android:layout_width="376dp" | ||
| 136 | + android:layout_height="171dp" | ||
| 137 | + android:layout_margin="@dimen/activity_vertical_margin" | ||
| 138 | + android:orientation="vertical" | ||
| 139 | + > | ||
| 140 | + | ||
| 141 | + <TextView | ||
| 142 | + android:layout_width="match_parent" | ||
| 143 | + android:layout_height="wrap_content" | ||
| 144 | + android:gravity="center" | ||
| 145 | + android:text="김예희님 맞춤정보" | ||
| 146 | + android:fontFamily="@font/applegothic" | ||
| 147 | + android:textSize="18dp" | ||
| 148 | + android:textStyle="bold"></TextView> | ||
| 149 | + | ||
| 150 | + <TextView | ||
| 151 | + android:layout_width="wrap_content" | ||
| 152 | + android:layout_height="wrap_content" | ||
| 153 | + android:text="\n해당 제품은 김예희님의 선택 태그 중 3개와 일치해요 :)"></TextView> | ||
| 154 | + | ||
| 155 | + <TextView | ||
| 156 | + android:layout_width="wrap_content" | ||
| 157 | + android:layout_height="wrap_content" | ||
| 158 | + android:text="#유기농 #TR_BEST #저렴한" | ||
| 159 | + android:textStyle="italic | ||
| 160 | +"></TextView> | ||
| 161 | + | ||
| 162 | + <LinearLayout | ||
| 163 | + android:layout_width="wrap_content" | ||
| 164 | + android:layout_height="wrap_content" | ||
| 165 | + android:orientation="horizontal"> | ||
| 166 | + | ||
| 167 | + <TextView | ||
| 168 | + android:layout_width="wrap_content" | ||
| 169 | + android:layout_height="wrap_content" | ||
| 170 | + android:text="해당 제품은 20가지 주의 성분이 "></TextView> | ||
| 171 | + | ||
| 172 | + <TextView | ||
| 173 | + android:layout_width="wrap_content" | ||
| 174 | + android:layout_height="wrap_content" | ||
| 175 | + android:text="1"></TextView> | ||
| 176 | + | ||
| 177 | + <TextView | ||
| 178 | + android:layout_width="wrap_content" | ||
| 179 | + android:layout_height="wrap_content" | ||
| 180 | + android:text="개,"></TextView> | ||
| 181 | + </LinearLayout> | ||
| 182 | + | ||
| 183 | + <LinearLayout | ||
| 184 | + android:layout_width="wrap_content" | ||
| 185 | + android:layout_height="wrap_content" | ||
| 186 | + android:orientation="horizontal"> | ||
| 187 | + | ||
| 188 | + <TextView | ||
| 189 | + android:layout_width="wrap_content" | ||
| 190 | + android:layout_height="wrap_content" | ||
| 191 | + android:text="전성분은 "></TextView> | ||
| 192 | + | ||
| 193 | + <TextView | ||
| 194 | + android:layout_width="wrap_content" | ||
| 195 | + android:layout_height="wrap_content" | ||
| 196 | + android:text="1"></TextView> | ||
| 197 | + | ||
| 198 | + <TextView | ||
| 199 | + android:layout_width="wrap_content" | ||
| 200 | + android:layout_height="wrap_content" | ||
| 201 | + android:text="개"></TextView> | ||
| 202 | + | ||
| 203 | + <TextView | ||
| 204 | + android:layout_width="wrap_content" | ||
| 205 | + android:layout_height="wrap_content" | ||
| 206 | + android:text=" 있어요!"></TextView> | ||
| 207 | + </LinearLayout> | ||
| 208 | + | ||
| 209 | + </LinearLayout> | ||
| 210 | + | ||
| 211 | + <Button | ||
| 212 | + android:id="@+id/button" | ||
| 213 | + android:layout_width="match_parent" | ||
| 214 | + android:layout_height="40dp" | ||
| 215 | + android:background="#3E2E86" | ||
| 216 | + android:text="sample 구독" | ||
| 217 | + android:fontFamily="@font/applegothic" | ||
| 218 | + android:textColor="#FFFFFF" | ||
| 219 | + android:textSize="14sp"></Button> | ||
| 220 | + | ||
| 221 | +</LinearLayout> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
app/src/main/res/layout/activity_login.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| 4 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 5 | + android:id="@+id/container" | ||
| 6 | + android:layout_width="match_parent" | ||
| 7 | + android:layout_height="match_parent" | ||
| 8 | + tools:context=".ui.login.LoginActivity"> | ||
| 9 | + | ||
| 10 | + <ImageView | ||
| 11 | + android:layout_width="624dp" | ||
| 12 | + android:layout_height="915dp" | ||
| 13 | + android:src="@drawable/login_t" | ||
| 14 | + app:layout_constraintBottom_toBottomOf="parent" | ||
| 15 | + app:layout_constraintEnd_toEndOf="parent" | ||
| 16 | + app:layout_constraintHorizontal_bias="0.501" | ||
| 17 | + app:layout_constraintStart_toStartOf="parent" | ||
| 18 | + app:layout_constraintTop_toTopOf="parent" | ||
| 19 | + app:layout_constraintVertical_bias="0.491" /> | ||
| 20 | + | ||
| 21 | + <EditText | ||
| 22 | + android:id="@+id/password" | ||
| 23 | + android:layout_width="234dp" | ||
| 24 | + android:layout_height="38dp" | ||
| 25 | + android:layout_marginStart="30dp" | ||
| 26 | + android:layout_marginLeft="30dp" | ||
| 27 | + android:layout_marginTop="48dp" | ||
| 28 | + android:layout_marginEnd="23dp" | ||
| 29 | + android:layout_marginRight="23dp" | ||
| 30 | + android:hint="@string/prompt_password" | ||
| 31 | + android:imeActionLabel="@string/action_sign_in_short" | ||
| 32 | + android:imeOptions="actionDone" | ||
| 33 | + android:inputType="textPassword" | ||
| 34 | + android:selectAllOnFocus="true" | ||
| 35 | + app:layout_constraintEnd_toEndOf="parent" | ||
| 36 | + app:layout_constraintHorizontal_bias="0.685" | ||
| 37 | + app:layout_constraintStart_toStartOf="parent" | ||
| 38 | + app:layout_constraintTop_toTopOf="@+id/username" /> | ||
| 39 | + | ||
| 40 | + <EditText | ||
| 41 | + android:id="@+id/username" | ||
| 42 | + android:layout_width="234dp" | ||
| 43 | + android:layout_height="38dp" | ||
| 44 | + android:layout_marginStart="28dp" | ||
| 45 | + android:layout_marginLeft="30dp" | ||
| 46 | + android:layout_marginTop="276dp" | ||
| 47 | + android:layout_marginEnd="23dp" | ||
| 48 | + android:layout_marginRight="23dp" | ||
| 49 | + android:hint="@string/prompt_email" | ||
| 50 | + android:inputType="textEmailAddress" | ||
| 51 | + android:selectAllOnFocus="true" | ||
| 52 | + app:layout_constraintEnd_toEndOf="parent" | ||
| 53 | + app:layout_constraintHorizontal_bias="0.685" | ||
| 54 | + app:layout_constraintStart_toStartOf="parent" | ||
| 55 | + app:layout_constraintTop_toTopOf="parent" /> | ||
| 56 | + | ||
| 57 | + <Button | ||
| 58 | + android:id="@+id/login" | ||
| 59 | + android:layout_width="wrap_content" | ||
| 60 | + android:layout_height="wrap_content" | ||
| 61 | + android:layout_gravity="start" | ||
| 62 | + android:layout_marginStart="48dp" | ||
| 63 | + android:layout_marginTop="16dp" | ||
| 64 | + android:layout_marginEnd="48dp" | ||
| 65 | + android:layout_marginBottom="64dp" | ||
| 66 | + android:enabled="false" | ||
| 67 | + android:lineSpacingExtra="18sp" | ||
| 68 | + android:singleLine="false" | ||
| 69 | + android:text="로그인하기" | ||
| 70 | + app:layout_constraintBottom_toBottomOf="parent" | ||
| 71 | + app:layout_constraintEnd_toEndOf="parent" | ||
| 72 | + app:layout_constraintHorizontal_bias="0.496" | ||
| 73 | + app:layout_constraintStart_toStartOf="parent" | ||
| 74 | + app:layout_constraintTop_toBottomOf="@+id/password" | ||
| 75 | + app:layout_constraintVertical_bias="0.3" /> | ||
| 76 | + | ||
| 77 | + <ProgressBar | ||
| 78 | + android:id="@+id/loading" | ||
| 79 | + android:layout_width="wrap_content" | ||
| 80 | + android:layout_height="wrap_content" | ||
| 81 | + android:layout_gravity="center" | ||
| 82 | + android:layout_marginStart="32dp" | ||
| 83 | + android:layout_marginTop="64dp" | ||
| 84 | + android:layout_marginEnd="32dp" | ||
| 85 | + android:layout_marginBottom="64dp" | ||
| 86 | + android:visibility="gone" | ||
| 87 | + app:layout_constraintBottom_toBottomOf="parent" | ||
| 88 | + app:layout_constraintEnd_toEndOf="@+id/password" | ||
| 89 | + app:layout_constraintStart_toStartOf="@+id/password" | ||
| 90 | + app:layout_constraintTop_toTopOf="parent" | ||
| 91 | + app:layout_constraintVertical_bias="0.3" /> | ||
| 92 | + | ||
| 93 | +</androidx.constraintlayout.widget.ConstraintLayout> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
app/src/main/res/layout/activity_main2.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + android:layout_width="match_parent" | ||
| 4 | + android:layout_height="match_parent" | ||
| 5 | + android:orientation="vertical"> | ||
| 6 | + | ||
| 7 | + <LinearLayout | ||
| 8 | + android:layout_width="wrap_content" | ||
| 9 | + android:layout_height="match_parent" | ||
| 10 | + android:orientation="vertical"> | ||
| 11 | + <LinearLayout | ||
| 12 | + android:layout_width="wrap_content" | ||
| 13 | + android:orientation="vertical" | ||
| 14 | + android:layout_height="wrap_content" | ||
| 15 | + android:background="#3800b3"> | ||
| 16 | + <ImageView | ||
| 17 | + android:layout_width="match_parent" | ||
| 18 | + android:layout_height="114dp" | ||
| 19 | + android:src="@drawable/item_header_t"> | ||
| 20 | + </ImageView> | ||
| 21 | + </LinearLayout> | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + <LinearLayout | ||
| 25 | + android:layout_width="match_parent" | ||
| 26 | + android:layout_height="match_parent" | ||
| 27 | + android:gravity="center" | ||
| 28 | + android:orientation="vertical"> | ||
| 29 | + | ||
| 30 | + <Button | ||
| 31 | + android:id="@+id/btn_1" | ||
| 32 | + android:layout_width="match_parent" | ||
| 33 | + android:layout_height="100dp" | ||
| 34 | + android:layout_marginTop="@dimen/activity_vertical_margin" | ||
| 35 | + android:background="#7D7FF6" | ||
| 36 | + android:text="브랜드 [cotton]" | ||
| 37 | + android:textColor="#FFFFFF" | ||
| 38 | + android:textSize="20dp"></Button> | ||
| 39 | + | ||
| 40 | + <Button | ||
| 41 | + android:id="@+id/btn_2" | ||
| 42 | + android:layout_width="match_parent" | ||
| 43 | + android:layout_height="100dp" | ||
| 44 | + android:layout_marginTop="5dp" | ||
| 45 | + android:background="#7D7FF6" | ||
| 46 | + android:text="브랜드 [유한킴벌리]" | ||
| 47 | + android:textColor="#FFFFFF" | ||
| 48 | + android:textSize="20dp"></Button> | ||
| 49 | + | ||
| 50 | + <Button | ||
| 51 | + android:id="@+id/btn_3" | ||
| 52 | + android:layout_width="match_parent" | ||
| 53 | + android:layout_height="100dp" | ||
| 54 | + android:layout_marginTop="5dp" | ||
| 55 | + android:background="#7D7FF6" | ||
| 56 | + android:text="제품비교" | ||
| 57 | + android:textColor="#FFFFFF" | ||
| 58 | + android:textSize="20dp"></Button> | ||
| 59 | + </LinearLayout> | ||
| 60 | + | ||
| 61 | + </LinearLayout> | ||
| 62 | + | ||
| 63 | +</LinearLayout> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
app/src/main/res/layout/activity_splash.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| 4 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 5 | + android:layout_width="match_parent" | ||
| 6 | + android:layout_height="match_parent" | ||
| 7 | + tools:context=".SplashActivity"> | ||
| 8 | + | ||
| 9 | + <ImageView | ||
| 10 | + android:layout_width="match_parent" | ||
| 11 | + android:layout_height="match_parent" | ||
| 12 | + android:background="#FFFFFF" | ||
| 13 | + android:src="@drawable/splash_t"></ImageView> | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +</LinearLayout> | ||
| 17 | + |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| 4 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 5 | + android:layout_width="match_parent" | ||
| 6 | + android:layout_height="match_parent" | ||
| 7 | + tools:context=".ViewPagerActivity"> | ||
| 8 | + | ||
| 9 | + <com.google.android.material.tabs.TabLayout | ||
| 10 | + android:id="@+id/tap_layout" | ||
| 11 | + android:layout_width="409dp" | ||
| 12 | + android:layout_height="wrap_content" | ||
| 13 | + app:layout_constraintEnd_toEndOf="parent" | ||
| 14 | + app:layout_constraintStart_toStartOf="parent" | ||
| 15 | + app:layout_constraintTop_toTopOf="parent"> | ||
| 16 | + | ||
| 17 | + <com.google.android.material.tabs.TabItem | ||
| 18 | + android:layout_width="wrap_content" | ||
| 19 | + android:layout_height="wrap_content" | ||
| 20 | + android:text="제품현황" /> | ||
| 21 | + | ||
| 22 | + <com.google.android.material.tabs.TabItem | ||
| 23 | + android:layout_width="wrap_content" | ||
| 24 | + android:layout_height="wrap_content" | ||
| 25 | + android:text="제품비교" /> | ||
| 26 | + | ||
| 27 | + <com.google.android.material.tabs.TabItem | ||
| 28 | + android:layout_width="wrap_content" | ||
| 29 | + android:layout_height="wrap_content" | ||
| 30 | + android:text="마이페이지" /> | ||
| 31 | + </com.google.android.material.tabs.TabLayout> | ||
| 32 | + | ||
| 33 | + <androidx.constraintlayout.widget.ConstraintLayout | ||
| 34 | + android:id="@+id/const_vp" | ||
| 35 | + android:layout_width="0dp" | ||
| 36 | + android:layout_height="0dp" | ||
| 37 | + app:layout_constraintBottom_toBottomOf="parent" | ||
| 38 | + app:layout_constraintEnd_toEndOf="parent" | ||
| 39 | + app:layout_constraintStart_toStartOf="parent" | ||
| 40 | + app:layout_constraintTop_toBottomOf="@+id/tap_layout"> | ||
| 41 | + | ||
| 42 | + <androidx.viewpager2.widget.ViewPager2 | ||
| 43 | + android:id="@+id/viewpager" | ||
| 44 | + android:layout_width="match_parent" | ||
| 45 | + android:layout_height="match_parent" /> | ||
| 46 | + </androidx.constraintlayout.widget.ConstraintLayout> | ||
| 47 | +</androidx.constraintlayout.widget.ConstraintLayout> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| 3 | + <background android:drawable="@drawable/ic_launcher_background" /> | ||
| 4 | + <foreground android:drawable="@drawable/ic_launcher_foreground" /> | ||
| 5 | +</adaptive-icon> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| 3 | + <background android:drawable="@drawable/ic_launcher_background" /> | ||
| 4 | + <foreground android:drawable="@drawable/ic_launcher_foreground" /> | ||
| 5 | +</adaptive-icon> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
app/src/main/res/mipmap-hdpi/ic_launcher.png
0 → 100644
3.51 KB
5.21 KB
app/src/main/res/mipmap-mdpi/ic_launcher.png
0 → 100644
2.57 KB
3.31 KB
4.81 KB
7.3 KB
7.72 KB
11.6 KB
10.4 KB
16.2 KB
app/src/main/res/values/colors.xml
0 → 100644
app/src/main/res/values/dimens.xml
0 → 100644
app/src/main/res/values/strings.xml
0 → 100644
| 1 | +<resources> | ||
| 2 | + <string name="app_name">TRUSTY</string> | ||
| 3 | + <string name="title_activity_login">LoginActivity</string> | ||
| 4 | + <string name="prompt_email">Email</string> | ||
| 5 | + <string name="prompt_password">Password</string> | ||
| 6 | + <string name="action_sign_in">Sign in or register</string> | ||
| 7 | + <string name="action_sign_in_short">Sign in</string> | ||
| 8 | + <string name="welcome">"Welcome !"</string> | ||
| 9 | + <string name="invalid_username">Not a valid username</string> | ||
| 10 | + <string name="invalid_password">Password must be >5 characters</string> | ||
| 11 | + <string name="login_failed">"Login failed"</string> | ||
| 12 | +</resources> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
app/src/main/res/values/styles.xml
0 → 100644
| 1 | +<resources> | ||
| 2 | + <!-- Base application theme. --> | ||
| 3 | + <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> | ||
| 4 | + <!-- Customize your theme here. --> | ||
| 5 | + <item name="colorPrimary">@color/colorPrimary</item> | ||
| 6 | + <item name="colorPrimaryDark">@color/colorPrimaryDark</item> | ||
| 7 | + <item name="colorAccent">@color/colorAccent</item> | ||
| 8 | + <!-- No Title Bar--> | ||
| 9 | + <item name="windowActionBar">false</item> | ||
| 10 | + <item name="windowNoTitle">true</item> | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + </style> | ||
| 14 | + | ||
| 15 | +</resources> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +package com.example.trusty; | ||
| 2 | + | ||
| 3 | +import org.junit.Test; | ||
| 4 | + | ||
| 5 | +import static org.junit.Assert.*; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * Example local unit test, which will execute on the development machine (host). | ||
| 9 | + * | ||
| 10 | + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> | ||
| 11 | + */ | ||
| 12 | +public class ExampleUnitTest { | ||
| 13 | + @Test | ||
| 14 | + public void addition_isCorrect() { | ||
| 15 | + assertEquals(4, 2 + 2); | ||
| 16 | + } | ||
| 17 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
build.gradle
0 → 100644
| 1 | +// Top-level build file where you can add configuration options common to all sub-projects/modules. | ||
| 2 | +buildscript { | ||
| 3 | + repositories { | ||
| 4 | + google() | ||
| 5 | + jcenter() | ||
| 6 | + } | ||
| 7 | + dependencies { | ||
| 8 | + classpath "com.android.tools.build:gradle:4.0.1" | ||
| 9 | + | ||
| 10 | + // NOTE: Do not place your application dependencies here; they belong | ||
| 11 | + // in the individual module build.gradle files | ||
| 12 | + } | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +allprojects { | ||
| 16 | + repositories { | ||
| 17 | + google() | ||
| 18 | + jcenter() | ||
| 19 | + } | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +task clean(type: Delete) { | ||
| 23 | + delete rootProject.buildDir | ||
| 24 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
gradle.properties
0 → 100644
| 1 | +# Project-wide Gradle settings. | ||
| 2 | +# IDE (e.g. Android Studio) users: | ||
| 3 | +# Gradle settings configured through the IDE *will override* | ||
| 4 | +# any settings specified in this file. | ||
| 5 | +# For more details on how to configure your build environment visit | ||
| 6 | +# http://www.gradle.org/docs/current/userguide/build_environment.html | ||
| 7 | +# Specifies the JVM arguments used for the daemon process. | ||
| 8 | +# The setting is particularly useful for tweaking memory settings. | ||
| 9 | +org.gradle.jvmargs=-Xmx2048m | ||
| 10 | +# When configured, Gradle will run in incubating parallel mode. | ||
| 11 | +# This option should only be used with decoupled projects. More details, visit | ||
| 12 | +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects | ||
| 13 | +# org.gradle.parallel=true | ||
| 14 | +# AndroidX package structure to make it clearer which packages are bundled with the | ||
| 15 | +# Android operating system, and which are packaged with your app"s APK | ||
| 16 | +# https://developer.android.com/topic/libraries/support-library/androidx-rn | ||
| 17 | +android.useAndroidX=true | ||
| 18 | +# Automatically convert third-party libraries to use AndroidX | ||
| 19 | +android.enableJetifier=true | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
gradle/wrapper/gradle-wrapper.jar
0 → 100644
No preview for this file type
gradle/wrapper/gradle-wrapper.properties
0 → 100644
gradlew
0 → 100644
| 1 | +#!/usr/bin/env sh | ||
| 2 | + | ||
| 3 | +############################################################################## | ||
| 4 | +## | ||
| 5 | +## Gradle start up script for UN*X | ||
| 6 | +## | ||
| 7 | +############################################################################## | ||
| 8 | + | ||
| 9 | +# Attempt to set APP_HOME | ||
| 10 | +# Resolve links: $0 may be a link | ||
| 11 | +PRG="$0" | ||
| 12 | +# Need this for relative symlinks. | ||
| 13 | +while [ -h "$PRG" ] ; do | ||
| 14 | + ls=`ls -ld "$PRG"` | ||
| 15 | + link=`expr "$ls" : '.*-> \(.*\)$'` | ||
| 16 | + if expr "$link" : '/.*' > /dev/null; then | ||
| 17 | + PRG="$link" | ||
| 18 | + else | ||
| 19 | + PRG=`dirname "$PRG"`"/$link" | ||
| 20 | + fi | ||
| 21 | +done | ||
| 22 | +SAVED="`pwd`" | ||
| 23 | +cd "`dirname \"$PRG\"`/" >/dev/null | ||
| 24 | +APP_HOME="`pwd -P`" | ||
| 25 | +cd "$SAVED" >/dev/null | ||
| 26 | + | ||
| 27 | +APP_NAME="Gradle" | ||
| 28 | +APP_BASE_NAME=`basename "$0"` | ||
| 29 | + | ||
| 30 | +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
| 31 | +DEFAULT_JVM_OPTS="" | ||
| 32 | + | ||
| 33 | +# Use the maximum available, or set MAX_FD != -1 to use that value. | ||
| 34 | +MAX_FD="maximum" | ||
| 35 | + | ||
| 36 | +warn () { | ||
| 37 | + echo "$*" | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +die () { | ||
| 41 | + echo | ||
| 42 | + echo "$*" | ||
| 43 | + echo | ||
| 44 | + exit 1 | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +# OS specific support (must be 'true' or 'false'). | ||
| 48 | +cygwin=false | ||
| 49 | +msys=false | ||
| 50 | +darwin=false | ||
| 51 | +nonstop=false | ||
| 52 | +case "`uname`" in | ||
| 53 | + CYGWIN* ) | ||
| 54 | + cygwin=true | ||
| 55 | + ;; | ||
| 56 | + Darwin* ) | ||
| 57 | + darwin=true | ||
| 58 | + ;; | ||
| 59 | + MINGW* ) | ||
| 60 | + msys=true | ||
| 61 | + ;; | ||
| 62 | + NONSTOP* ) | ||
| 63 | + nonstop=true | ||
| 64 | + ;; | ||
| 65 | +esac | ||
| 66 | + | ||
| 67 | +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||
| 68 | + | ||
| 69 | +# Determine the Java command to use to start the JVM. | ||
| 70 | +if [ -n "$JAVA_HOME" ] ; then | ||
| 71 | + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||
| 72 | + # IBM's JDK on AIX uses strange locations for the executables | ||
| 73 | + JAVACMD="$JAVA_HOME/jre/sh/java" | ||
| 74 | + else | ||
| 75 | + JAVACMD="$JAVA_HOME/bin/java" | ||
| 76 | + fi | ||
| 77 | + if [ ! -x "$JAVACMD" ] ; then | ||
| 78 | + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||
| 79 | + | ||
| 80 | +Please set the JAVA_HOME variable in your environment to match the | ||
| 81 | +location of your Java installation." | ||
| 82 | + fi | ||
| 83 | +else | ||
| 84 | + JAVACMD="java" | ||
| 85 | + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
| 86 | + | ||
| 87 | +Please set the JAVA_HOME variable in your environment to match the | ||
| 88 | +location of your Java installation." | ||
| 89 | +fi | ||
| 90 | + | ||
| 91 | +# Increase the maximum file descriptors if we can. | ||
| 92 | +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then | ||
| 93 | + MAX_FD_LIMIT=`ulimit -H -n` | ||
| 94 | + if [ $? -eq 0 ] ; then | ||
| 95 | + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | ||
| 96 | + MAX_FD="$MAX_FD_LIMIT" | ||
| 97 | + fi | ||
| 98 | + ulimit -n $MAX_FD | ||
| 99 | + if [ $? -ne 0 ] ; then | ||
| 100 | + warn "Could not set maximum file descriptor limit: $MAX_FD" | ||
| 101 | + fi | ||
| 102 | + else | ||
| 103 | + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | ||
| 104 | + fi | ||
| 105 | +fi | ||
| 106 | + | ||
| 107 | +# For Darwin, add options to specify how the application appears in the dock | ||
| 108 | +if $darwin; then | ||
| 109 | + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | ||
| 110 | +fi | ||
| 111 | + | ||
| 112 | +# For Cygwin, switch paths to Windows format before running java | ||
| 113 | +if $cygwin ; then | ||
| 114 | + APP_HOME=`cygpath --path --mixed "$APP_HOME"` | ||
| 115 | + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | ||
| 116 | + JAVACMD=`cygpath --unix "$JAVACMD"` | ||
| 117 | + | ||
| 118 | + # We build the pattern for arguments to be converted via cygpath | ||
| 119 | + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | ||
| 120 | + SEP="" | ||
| 121 | + for dir in $ROOTDIRSRAW ; do | ||
| 122 | + ROOTDIRS="$ROOTDIRS$SEP$dir" | ||
| 123 | + SEP="|" | ||
| 124 | + done | ||
| 125 | + OURCYGPATTERN="(^($ROOTDIRS))" | ||
| 126 | + # Add a user-defined pattern to the cygpath arguments | ||
| 127 | + if [ "$GRADLE_CYGPATTERN" != "" ] ; then | ||
| 128 | + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | ||
| 129 | + fi | ||
| 130 | + # Now convert the arguments - kludge to limit ourselves to /bin/sh | ||
| 131 | + i=0 | ||
| 132 | + for arg in "$@" ; do | ||
| 133 | + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | ||
| 134 | + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | ||
| 135 | + | ||
| 136 | + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | ||
| 137 | + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | ||
| 138 | + else | ||
| 139 | + eval `echo args$i`="\"$arg\"" | ||
| 140 | + fi | ||
| 141 | + i=$((i+1)) | ||
| 142 | + done | ||
| 143 | + case $i in | ||
| 144 | + (0) set -- ;; | ||
| 145 | + (1) set -- "$args0" ;; | ||
| 146 | + (2) set -- "$args0" "$args1" ;; | ||
| 147 | + (3) set -- "$args0" "$args1" "$args2" ;; | ||
| 148 | + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||
| 149 | + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||
| 150 | + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||
| 151 | + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||
| 152 | + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||
| 153 | + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||
| 154 | + esac | ||
| 155 | +fi | ||
| 156 | + | ||
| 157 | +# Escape application args | ||
| 158 | +save () { | ||
| 159 | + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done | ||
| 160 | + echo " " | ||
| 161 | +} | ||
| 162 | +APP_ARGS=$(save "$@") | ||
| 163 | + | ||
| 164 | +# Collect all arguments for the java command, following the shell quoting and substitution rules | ||
| 165 | +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" | ||
| 166 | + | ||
| 167 | +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong | ||
| 168 | +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then | ||
| 169 | + cd "$(dirname "$0")" | ||
| 170 | +fi | ||
| 171 | + | ||
| 172 | +exec "$JAVACMD" "$@" |
gradlew.bat
0 → 100644
| 1 | +@if "%DEBUG%" == "" @echo off | ||
| 2 | +@rem ########################################################################## | ||
| 3 | +@rem | ||
| 4 | +@rem Gradle startup script for Windows | ||
| 5 | +@rem | ||
| 6 | +@rem ########################################################################## | ||
| 7 | + | ||
| 8 | +@rem Set local scope for the variables with windows NT shell | ||
| 9 | +if "%OS%"=="Windows_NT" setlocal | ||
| 10 | + | ||
| 11 | +set DIRNAME=%~dp0 | ||
| 12 | +if "%DIRNAME%" == "" set DIRNAME=. | ||
| 13 | +set APP_BASE_NAME=%~n0 | ||
| 14 | +set APP_HOME=%DIRNAME% | ||
| 15 | + | ||
| 16 | +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
| 17 | +set DEFAULT_JVM_OPTS= | ||
| 18 | + | ||
| 19 | +@rem Find java.exe | ||
| 20 | +if defined JAVA_HOME goto findJavaFromJavaHome | ||
| 21 | + | ||
| 22 | +set JAVA_EXE=java.exe | ||
| 23 | +%JAVA_EXE% -version >NUL 2>&1 | ||
| 24 | +if "%ERRORLEVEL%" == "0" goto init | ||
| 25 | + | ||
| 26 | +echo. | ||
| 27 | +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
| 28 | +echo. | ||
| 29 | +echo Please set the JAVA_HOME variable in your environment to match the | ||
| 30 | +echo location of your Java installation. | ||
| 31 | + | ||
| 32 | +goto fail | ||
| 33 | + | ||
| 34 | +:findJavaFromJavaHome | ||
| 35 | +set JAVA_HOME=%JAVA_HOME:"=% | ||
| 36 | +set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||
| 37 | + | ||
| 38 | +if exist "%JAVA_EXE%" goto init | ||
| 39 | + | ||
| 40 | +echo. | ||
| 41 | +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||
| 42 | +echo. | ||
| 43 | +echo Please set the JAVA_HOME variable in your environment to match the | ||
| 44 | +echo location of your Java installation. | ||
| 45 | + | ||
| 46 | +goto fail | ||
| 47 | + | ||
| 48 | +:init | ||
| 49 | +@rem Get command-line arguments, handling Windows variants | ||
| 50 | + | ||
| 51 | +if not "%OS%" == "Windows_NT" goto win9xME_args | ||
| 52 | + | ||
| 53 | +:win9xME_args | ||
| 54 | +@rem Slurp the command line arguments. | ||
| 55 | +set CMD_LINE_ARGS= | ||
| 56 | +set _SKIP=2 | ||
| 57 | + | ||
| 58 | +:win9xME_args_slurp | ||
| 59 | +if "x%~1" == "x" goto execute | ||
| 60 | + | ||
| 61 | +set CMD_LINE_ARGS=%* | ||
| 62 | + | ||
| 63 | +:execute | ||
| 64 | +@rem Setup the command line | ||
| 65 | + | ||
| 66 | +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||
| 67 | + | ||
| 68 | +@rem Execute Gradle | ||
| 69 | +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | ||
| 70 | + | ||
| 71 | +:end | ||
| 72 | +@rem End local scope for the variables with windows NT shell | ||
| 73 | +if "%ERRORLEVEL%"=="0" goto mainEnd | ||
| 74 | + | ||
| 75 | +:fail | ||
| 76 | +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | ||
| 77 | +rem the _cmd.exe /c_ return code! | ||
| 78 | +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | ||
| 79 | +exit /b 1 | ||
| 80 | + | ||
| 81 | +:mainEnd | ||
| 82 | +if "%OS%"=="Windows_NT" endlocal | ||
| 83 | + | ||
| 84 | +:omega |
settings.gradle
0 → 100644
-
Please register or login to post a comment