From 0632cbe671b9c7fc3fa012038984f98df2aedf09 Mon Sep 17 00:00:00 2001 From: Mitch Tabian Date: Sun, 28 May 2017 08:27:05 -0700 Subject: [PATCH 001/122] Create README.md --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..266b939 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ + + +

Android Instagram Clone Course

+

A step-by-step guide to build your own Instagram Clone

+

Watch it here: Instagram Clone Course

+
+

The course outline is still not "set in stone." I'll be building it in modules so you can have check points if you want to take a break +and come back to it in the future. At this point I'm guessing there will be 30-50 videos.

+ +

We'll start by building almost the entire interface and then move onto the back-end.

+

The back-end will be almost 100% Firebase as that will make it simply for the purposes of this course.

+

If this were a real production app I would probably use: + +

+

+ +

That would require a TON more code. Setting up the server/website alone would probably be another 20 videos or so. So to keep +things simple and condensed I will just use Firebase for everything. After all this is an Android Course, not a web development course.

From 4541852e603c7b0eeb8fba27d5f997936257ee02 Mon Sep 17 00:00:00 2001 From: Mitch Tabian Date: Sun, 28 May 2017 08:28:50 -0700 Subject: [PATCH 002/122] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 266b939..2b0aee1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

Android Instagram Clone Course

A step-by-step guide to build your own Instagram Clone

-

Watch it here: Instagram Clone Course

+

Watch it here: Instagram Clone Course


The course outline is still not "set in stone." I'll be building it in modules so you can have check points if you want to take a break and come back to it in the future. At this point I'm guessing there will be 30-50 videos.

@@ -15,7 +15,7 @@ and come back to it in the future. At this point I'm guessing there will be 30-5
  • Firebase for user management and authentication
  • Amazon Web Services to store images and videos
  • A server (website) SQL database for saving all other data. Take a look -here for an outline of what +here for an outline of what the database would roughly look like if you did that. (SQLite is probably fine)
  • From 52b925ee90bd1ea592a8ecd64d6c566e637731f0 Mon Sep 17 00:00:00 2001 From: Mitch Tabian Date: Sun, 28 May 2017 08:29:24 -0700 Subject: [PATCH 003/122] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2b0aee1..2819627 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

    Android Instagram Clone Course

    A step-by-step guide to build your own Instagram Clone

    -

    Watch it here: Instagram Clone Course

    +

    Watch it here: Instagram Clone Course


    The course outline is still not "set in stone." I'll be building it in modules so you can have check points if you want to take a break and come back to it in the future. At this point I'm guessing there will be 30-50 videos.

    @@ -15,7 +15,7 @@ and come back to it in the future. At this point I'm guessing there will be 30-5
  • Firebase for user management and authentication
  • Amazon Web Services to store images and videos
  • A server (website) SQL database for saving all other data. Take a look -here for an outline of what +here for an outline of what the database would roughly look like if you did that. (SQLite is probably fine)
  • From c7c49c5d7f9d3766fd7abb7524218018a85186c4 Mon Sep 17 00:00:00 2001 From: Mitch Tabian Date: Sun, 28 May 2017 08:30:57 -0700 Subject: [PATCH 004/122] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2819627..2b0aee1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

    Android Instagram Clone Course

    A step-by-step guide to build your own Instagram Clone

    -

    Watch it here: Instagram Clone Course

    +

    Watch it here: Instagram Clone Course


    The course outline is still not "set in stone." I'll be building it in modules so you can have check points if you want to take a break and come back to it in the future. At this point I'm guessing there will be 30-50 videos.

    @@ -15,7 +15,7 @@ and come back to it in the future. At this point I'm guessing there will be 30-5
  • Firebase for user management and authentication
  • Amazon Web Services to store images and videos
  • A server (website) SQL database for saving all other data. Take a look -here for an outline of what +here for an outline of what the database would roughly look like if you did that. (SQLite is probably fine)
  • From 34db038434aec9f72da128252d86cb37258593ec Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 28 May 2017 12:05:17 -0700 Subject: [PATCH 005/122] Source Code --- .gitignore | 54 ++------- .idea/compiler.xml | 22 ++++ .idea/copyright/profiles_settings.xml | 3 + .idea/gradle.xml | 18 +++ .idea/misc.xml | 46 ++++++++ .idea/modules.xml | 9 ++ .idea/runConfigurations.xml | 12 ++ app/.gitignore | 1 + app/build.gradle | 34 ++++++ app/proguard-rules.pro | 25 ++++ build.gradle | 23 ++++ gradle.properties | 17 +++ gradlew | 160 ++++++++++++++++++++++++++ gradlew.bat | 90 +++++++++++++++ settings.gradle | 1 + 15 files changed, 469 insertions(+), 46 deletions(-) create mode 100644 .idea/compiler.xml create mode 100644 .idea/copyright/profiles_settings.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/runConfigurations.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore index cd2946a..39fb081 100644 --- a/.gitignore +++ b/.gitignore @@ -1,47 +1,9 @@ -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# Windows shortcuts -*.lnk - -# ========================= -# Operating System Files -# ========================= - -# OSX -# ========================= - +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries .DS_Store -.AppleDouble -.LSOverride - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk +/build +/captures +.externalNativeBuild diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..96cc43e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..7ac24c7 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..5d19981 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e46670c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ff131cf --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,34 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.0" + defaultConfig { + applicationId "tabian.com.instagramclone" + minSdkVersion 18 + targetSdkVersion 25 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + exclude group: 'com.android.support', module: 'support-annotations' + }) + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support.constraint:constraint-layout:1.0.2' + testCompile 'junit:junit:4.12' + + //Design library for Coordinator Layout and Toolbars + compile 'com.android.support:design:25.3.1' + +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..048bf76 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,25 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:\Users\User\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..b78a0b8 --- /dev/null +++ b/build.gradle @@ -0,0 +1,23 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.1' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..aac7c9b --- /dev/null +++ b/gradle.properties @@ -0,0 +1,17 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..9d82f78 --- /dev/null +++ b/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..e7b4def --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':app' From 2cac213283ceafe3b1c627096065bd11f80d4161 Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 28 May 2017 12:09:59 -0700 Subject: [PATCH 006/122] Source Code --- .../ExampleInstrumentedTest.java | 26 ++++++++++ app/src/main/AndroidManifest.xml | 21 ++++++++ .../com/instagramclone/HomeActivity.java | 15 ++++++ app/src/main/res/layout/activity_home.xml | 46 ++++++++++++++++++ .../layout/layout_bottom_navigation_view.xml | 21 ++++++++ .../res/layout/layout_center_viewpager.xml | 19 ++++++++ app/src/main/res/layout/layout_top_tabs.xml | 26 ++++++++++ app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3418 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 4208 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2206 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2555 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4842 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 6114 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7718 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10056 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10486 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 14696 bytes app/src/main/res/values/colors.xml | 6 +++ app/src/main/res/values/strings.xml | 3 ++ app/src/main/res/values/styles.xml | 11 +++++ .../com/instagramclone/ExampleUnitTest.java | 17 +++++++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes gradle/wrapper/gradle-wrapper.properties | 6 +++ 23 files changed, 217 insertions(+) create mode 100644 app/src/androidTest/java/tabian/com/instagramclone/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/tabian/com/instagramclone/HomeActivity.java create mode 100644 app/src/main/res/layout/activity_home.xml create mode 100644 app/src/main/res/layout/layout_bottom_navigation_view.xml create mode 100644 app/src/main/res/layout/layout_center_viewpager.xml create mode 100644 app/src/main/res/layout/layout_top_tabs.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/test/java/tabian/com/instagramclone/ExampleUnitTest.java create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties diff --git a/app/src/androidTest/java/tabian/com/instagramclone/ExampleInstrumentedTest.java b/app/src/androidTest/java/tabian/com/instagramclone/ExampleInstrumentedTest.java new file mode 100644 index 0000000..34a5f93 --- /dev/null +++ b/app/src/androidTest/java/tabian/com/instagramclone/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package tabian.com.instagramclone; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("tabian.com.instagramclone", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b705a69 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/tabian/com/instagramclone/HomeActivity.java b/app/src/main/java/tabian/com/instagramclone/HomeActivity.java new file mode 100644 index 0000000..3ce6ba1 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/HomeActivity.java @@ -0,0 +1,15 @@ +package tabian.com.instagramclone; + +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; + +public class HomeActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + + } +} diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml new file mode 100644 index 0000000..a1d7632 --- /dev/null +++ b/app/src/main/res/layout/activity_home.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/layout_bottom_navigation_view.xml b/app/src/main/res/layout/layout_bottom_navigation_view.xml new file mode 100644 index 0000000..0df267e --- /dev/null +++ b/app/src/main/res/layout/layout_bottom_navigation_view.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_center_viewpager.xml b/app/src/main/res/layout/layout_center_viewpager.xml new file mode 100644 index 0000000..8654e43 --- /dev/null +++ b/app/src/main/res/layout/layout_center_viewpager.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_top_tabs.xml b/app/src/main/res/layout/layout_top_tabs.xml new file mode 100644 index 0000000..a286d52 --- /dev/null +++ b/app/src/main/res/layout/layout_top_tabs.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..cde69bcccec65160d92116f20ffce4fce0b5245c GIT binary patch literal 3418 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..efc028a636dd690a51db5a525cf781a5a7daba68 GIT binary patch literal 2555 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..3af2608a4492ef9ae63a77ec3305aedda89594cb GIT binary patch literal 6114 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..324e72cdd7480cb983fa1bcc7ce686e51ef87fe7 GIT binary patch literal 7718 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..9bec2e623103ac9713b00cad8502a057c1efda61 GIT binary patch literal 10056 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 ek+^GN3bv-?^>(QkVinb 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 + + #3F51B5 + #303F9F + #FF4081 + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..82efcf8 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + InstagramClone + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..0eb88fe --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/app/src/test/java/tabian/com/instagramclone/ExampleUnitTest.java b/app/src/test/java/tabian/com/instagramclone/ExampleUnitTest.java new file mode 100644 index 0000000..4562211 --- /dev/null +++ b/app/src/test/java/tabian/com/instagramclone/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package tabian.com.instagramclone; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..13372aef5e24af05341d49695ee84e5f9b594659 GIT binary patch literal 53636 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ⅅ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 H-+%o-(+5aQ literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..17b6f1f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sun May 28 11:18:14 PDT 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip From 0f0377337204105604e23f08d3939b5be1556684 Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 28 May 2017 12:24:32 -0700 Subject: [PATCH 007/122] part2 - Toolbars and NavigationView --- .../res/drawable/white_grey_border_bottom.xml | 24 +++++++++++++++++++ .../res/drawable/white_grey_border_top.xml | 24 +++++++++++++++++++ .../layout/layout_bottom_navigation_view.xml | 3 ++- app/src/main/res/layout/layout_top_tabs.xml | 3 ++- app/src/main/res/values/colors.xml | 3 +++ 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/drawable/white_grey_border_bottom.xml create mode 100644 app/src/main/res/drawable/white_grey_border_top.xml diff --git a/app/src/main/res/drawable/white_grey_border_bottom.xml b/app/src/main/res/drawable/white_grey_border_bottom.xml new file mode 100644 index 0000000..7c05061 --- /dev/null +++ b/app/src/main/res/drawable/white_grey_border_bottom.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/white_grey_border_top.xml b/app/src/main/res/drawable/white_grey_border_top.xml new file mode 100644 index 0000000..2bbd8e3 --- /dev/null +++ b/app/src/main/res/drawable/white_grey_border_top.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_bottom_navigation_view.xml b/app/src/main/res/layout/layout_bottom_navigation_view.xml index 0df267e..d8f2252 100644 --- a/app/src/main/res/layout/layout_bottom_navigation_view.xml +++ b/app/src/main/res/layout/layout_bottom_navigation_view.xml @@ -9,7 +9,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/bottomNavViewBar" - android:background="@color/colorPrimary"> + android:background="@drawable/white_grey_border_top" + > diff --git a/app/src/main/res/layout/layout_top_tabs.xml b/app/src/main/res/layout/layout_top_tabs.xml index a286d52..057bbfd 100644 --- a/app/src/main/res/layout/layout_top_tabs.xml +++ b/app/src/main/res/layout/layout_top_tabs.xml @@ -12,7 +12,8 @@ + android:id="@+id/tabs" + android:background="@drawable/white_grey_border_bottom"> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 3ab3e9c..226a646 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,4 +3,7 @@ #3F51B5 #303F9F #FF4081 + + #bfbfbf + #fff From 69743899065c2b921f99dde9a2aabb5c8f8adc70 Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 28 May 2017 12:52:23 -0700 Subject: [PATCH 008/122] part3 - Customizing the BottomNavigationView --- app/build.gradle | 3 ++ .../com/instagramclone/HomeActivity.java | 17 +++++++++ .../Utils/BottomNavigationViewHelper.java | 22 ++++++++++++ app/src/main/res/drawable-hdpi/ic_alert.png | Bin 0 -> 620 bytes app/src/main/res/drawable-hdpi/ic_android.png | Bin 0 -> 674 bytes app/src/main/res/drawable-hdpi/ic_circle.png | Bin 0 -> 1040 bytes app/src/main/res/drawable-hdpi/ic_house.png | Bin 0 -> 357 bytes app/src/main/res/drawable-hdpi/ic_search.png | Bin 0 -> 724 bytes app/src/main/res/drawable-mdpi/ic_alert.png | Bin 0 -> 423 bytes app/src/main/res/drawable-mdpi/ic_android.png | Bin 0 -> 467 bytes app/src/main/res/drawable-mdpi/ic_circle.png | Bin 0 -> 644 bytes app/src/main/res/drawable-mdpi/ic_house.png | Bin 0 -> 238 bytes app/src/main/res/drawable-mdpi/ic_search.png | Bin 0 -> 496 bytes app/src/main/res/drawable-xhdpi/ic_alert.png | Bin 0 -> 683 bytes .../main/res/drawable-xhdpi/ic_android.png | Bin 0 -> 806 bytes app/src/main/res/drawable-xhdpi/ic_circle.png | Bin 0 -> 1298 bytes app/src/main/res/drawable-xhdpi/ic_house.png | Bin 0 -> 326 bytes app/src/main/res/drawable-xhdpi/ic_search.png | Bin 0 -> 922 bytes app/src/main/res/drawable-xxhdpi/ic_alert.png | Bin 0 -> 1097 bytes .../main/res/drawable-xxhdpi/ic_android.png | Bin 0 -> 1302 bytes .../main/res/drawable-xxhdpi/ic_circle.png | Bin 0 -> 2141 bytes app/src/main/res/drawable-xxhdpi/ic_house.png | Bin 0 -> 575 bytes .../main/res/drawable-xxhdpi/ic_search.png | Bin 0 -> 1500 bytes .../layout/layout_bottom_navigation_view.xml | 9 ++--- .../main/res/menu/bottom_navigation_menu.xml | 34 ++++++++++++++++++ build.gradle | 1 + 26 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java create mode 100644 app/src/main/res/drawable-hdpi/ic_alert.png create mode 100644 app/src/main/res/drawable-hdpi/ic_android.png create mode 100644 app/src/main/res/drawable-hdpi/ic_circle.png create mode 100644 app/src/main/res/drawable-hdpi/ic_house.png create mode 100644 app/src/main/res/drawable-hdpi/ic_search.png create mode 100644 app/src/main/res/drawable-mdpi/ic_alert.png create mode 100644 app/src/main/res/drawable-mdpi/ic_android.png create mode 100644 app/src/main/res/drawable-mdpi/ic_circle.png create mode 100644 app/src/main/res/drawable-mdpi/ic_house.png create mode 100644 app/src/main/res/drawable-mdpi/ic_search.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_alert.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_android.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_circle.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_house.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_search.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_alert.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_android.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_circle.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_house.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_search.png create mode 100644 app/src/main/res/menu/bottom_navigation_menu.xml diff --git a/app/build.gradle b/app/build.gradle index ff131cf..4c045c8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,4 +31,7 @@ dependencies { //Design library for Coordinator Layout and Toolbars compile 'com.android.support:design:25.3.1' + //BottomNavigationViewEx library + compile 'com.github.ittianyu:BottomNavigationViewEx:1.1.9' + } diff --git a/app/src/main/java/tabian/com/instagramclone/HomeActivity.java b/app/src/main/java/tabian/com/instagramclone/HomeActivity.java index 3ce6ba1..461898c 100644 --- a/app/src/main/java/tabian/com/instagramclone/HomeActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/HomeActivity.java @@ -4,12 +4,29 @@ import android.os.Bundle; import android.util.Log; +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; + public class HomeActivity extends AppCompatActivity { + private static final String TAG = "HomeActivity"; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: starting."); + + setupBottomNavigationView(); + } + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); } } diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java b/app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java new file mode 100644 index 0000000..5800a01 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java @@ -0,0 +1,22 @@ +package tabian.com.instagramclone.Utils; + +import android.util.Log; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +/** + * Created by User on 5/28/2017. + */ + +public class BottomNavigationViewHelper { + + private static final String TAG = "BottomNavigationViewHel"; + + public static void setupBottomNavigationView(BottomNavigationViewEx bottomNavigationViewEx){ + Log.d(TAG, "setupBottomNavigationView: Setting up BottomNavigationView"); + bottomNavigationViewEx.enableAnimation(false); + bottomNavigationViewEx.enableItemShiftingMode(false); + bottomNavigationViewEx.enableShiftingMode(false); + bottomNavigationViewEx.setTextVisibility(false); + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_alert.png b/app/src/main/res/drawable-hdpi/ic_alert.png new file mode 100644 index 0000000000000000000000000000000000000000..78cadb5935fe3d4b535d40bd505e92a60bf10eb5 GIT binary patch literal 620 zcmV-y0+aoTP)B&hOi$yJJ=C(?uGKvbF@p8F5mCNOhK+SwU|C-5Us)=ewn9K)3R&BKsyS|_rhsQsd*S+3DlMh3!9cCKpQif%Gs|< z8fm3csadRlP|ogbORmJe$^z|6763HfyA~m20ifRpz)$!N05{%n5zC$dP{m?#-FE=k zIrnq{;O3|z{!euQz_lkTLg-E=+n})CVF9pC;`J3k+^9&Q_k*$xE#~q#ua77@6$*vA zHUN62-8NBZMF4I9&;*vmtayhVR#?CV3V`Qatm|3fn+VQB+~oD;ou9P##W8=Z(R@#bSVIkM9+oo*^IhTFKF<&V z&itR1@Dxsln5VdZIV3I>Lw}rWGdO>PTk)Y=w;~KuDXHA%RVK-x$#SY zAMymRAU`e3S`I}VIS|)q8U??v2q7z>dm!+Gg^^z+O=`cJqWXE5AxOFa0000GWkLlevn;VsplTtxzZ|Q9m`pv7xdt0k~O*kXG5IPLcgj3TrH|e^NOePoU zdhdMJ7)4`*A3%h}H0XDay%kT8%@?7?p1B?wdAng&{YVS2K63IwW?k?$deq0psK{r? z1-?VfexJD!`Y@G}w=8RgX7Alarpw?*`j;Jvc*A;9CV&P#aubV2qtm%uZl1_|3S8zR z9*@t$mUHh=mFuh`lDG*Fu_^2aegY76V9Se6`Fws^x&R`$<3$ee^LLS5Hk;j&E`SC< z54&&$0#8){+G;vx}> z1{IcY!QXeCDX|?zWWmXUT&lu2041-~+#M$OI18-gSj2sq2+G6oI)IS!HYYl?==PW@ z0dN^CXwLnn(4E*8-}Ts}BB}&{2X9AbsmPQTpap0FT7VXy1!w_UfEMr{1+aAbmGfX* zWjc*h7%!bhTF*Nrx~mRVPQ9k0`at8y!?UrfS(Sa5K>c&yb{~}jFec%^=7AHMlSi1c zN?T%KtD&MUl)^v(s?qMckI)XEq%6x?Q&Ql?Lb9vTUQx@gLW`=_utPx@Hol8fR*}mu z?1l=9T7VXy1!w_5N|D0cDRge5;EPS5oMqtLMt1Ydon+@WKciKozVx`y>i_@%07*qo IM6N<$g2R|INdN!< literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_circle.png b/app/src/main/res/drawable-hdpi/ic_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..a9887ae3d9d3c967636d0db0f6372ae13cca78ea GIT binary patch literal 1040 zcmV+r1n>KaP)qAdxg`{S(Hf8N@QOoSktfj%1hIzD>Cn4bZPL@& zW1tPok=6->lgtU{P^wfa_hgX*O>jXiuMu#<1ywk)<>u+bmW+KZ;(p%+ZNfUh=p-R_ zQ4O1<;6OM~ajhF+9N<%^O5{_)Dypb3zU{hr6b_)+$%?IlZW=T%99R!hxx+fZp}Z+< znbX8yJxusS>3|F)^b?v%4b8E^Ae*3uNC$xBw(&NAU;@}zL^TQA@>W7q5n-Hfd2s%M z7%J+yj~MF&Sgg=<=$pt~HQQeNHL*-)r#~WSX8xU!$pKDeZ$EL09^2{wALm3n;9HMe zLWsVdaGcx3M8A!~v}0fhffo&`1uNTQP!kg4UB#eUOyWbjG{di zNvwiVNu=J5v5;*z6G{X2p1HP-Q8>U*-3P~@+8PcrO%uO+CsL#Fbkq*uq972N<1l(7 zPGQd%e}_P)aoZtmSWj&J*L5VL+H%NP7FLrxuy}u%JN!;{@w|!aDee(o00_L zE;f{6QnF^?F8kVWQW`&tD;op-SP8A1VRhR?z>wH3=ww106ekmR!gVINStL8etZ>`H zB==A!T#6mD-U?3Aa!bACa#^fC351i+_4*lT2e=cE1T40f!1#@KZ1lRI?6UD$jcn&_ zi7nB|W=xMR+ng2~02*H$$$x18v8WS0;N1fo!UZ4cZ~OlhW`5+yLSlbL{`E zWTXO%UEqGA!A*agrN!^+xOYOMGSoPa;EBP&-j&Iu8+-Zu*Uw-5Qd_YO<^P=k0000< KMNUMnLSTaD?CuT# literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_house.png b/app/src/main/res/drawable-hdpi/ic_house.png new file mode 100644 index 0000000000000000000000000000000000000000..602f5b11f48a8f6931466313ce23ff130dd02fc9 GIT binary patch literal 357 zcmV-r0h<1aP)ST2JaYhGYLfp;+W@qN1#9s|QM9RqZX5tu$+c($~+sSpIlzmcT~<`s`1~{(mnfpv&u))iH9Hvf{b(r8-F2)LTNd400000NkvXXu0mjf DBomLz literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_search.png b/app/src/main/res/drawable-hdpi/ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..1ae7e11e53fa784708c67cda886c805dd831c397 GIT binary patch literal 724 zcmV;_0xSKAP)^9zD#W}+p|?j%3;hM!=2E3khE~*~AfnayZ~Z>lBk8bh zZf7@L*n#CNCwq41oB3vDCqdxFix)30N-UjDKPZ(-8^vO=RVWm`lrj^ZRS7)wxDwUdtLc60VE(ZYr!E*=Co3m2>9u9v$ zM9JSAL)LUby}Q;euT!3$AlDHGb^IPrCXDG@(()L0#@&e2!gr@)ueQ+? z3+g-^v_9udq0@L%dLfg^+&2aQxqC}k?CrD`BmD%3b(8$>h~RrZ?VbqUx&Ux!62RBN z!zz`^as&WYgjYWqivv|X!-LKz30^78ULvb~Z!{V=oCaX*dV!6<4Q31+z7)ZpaY3Qa zCMk5G_#i7iiy$@EMPg`~4B~B3{@+Y%Eh=m+jY8o^QI>xeL0K5t6q&wCyb~_(O%luu zUUdPyaHleUnFD||d6{GJ83%+?zAe3JtxLn<`74c_K`)tP?DDtk_WCjFeEc zIAh}u#kROcC>F!}O-*L&&jQ4M>GgVZ3`!2phk+-EOT5(#ToIioW<{roX?QK^Gzkb# zCkN;hI7uf3=vCm7gq~32W#FK&57}_e@)AVg#fuj&PRKtIztTW|%bK4600005wwsukBmwbE5H>b8j;E{T>gwveFv~$07z#7=^z^vt<^VG@ zGeu+vfUu#Vp*%f;T?ZK4)JzBF4l%MF z05munPY|adg;F{$b->&aK}iU7Q0f4nx;AoCJ`aIJMwA1fYPraYe_U}6!oZ+)Msk2F zvK)GvFgG_BC)oj}rlzvEd`v{nNk>ZuQp3UlZO|GJh8>V{ixaXOP;EQa9Y9GU9CZM# z9MFa<&Z*)6pe7S?DI95yO~jUd8tKFSk2Ik`f;`?r1rD}-gk zCAZTESr~T1&VJvwui1%ZRVYG;^C*h$!!TT&eFlVuFGJGoqiV}MV}$O|HV zU`MRv0FGx77mb8MaKu9Hx^9d1{|_8{EHJ}o4e5aT3g096tr`me(5bS-0qjXL^8xiK zz9+^4O2{f1#`ZY`jOP_VTgP$wBQa;GeGp|7+sCZig%t=)tbo%dY~s+8Qxt>Ko7}rE z)VuNuPEAY(u{~gZOYEUm1j6f~a;>ho1fafA4(EaH!4ZnnEu(-t^(r?48Uc-fMu097 zc9ckX!6=}oVB5OqU;!PM^bWvYJkQ(U5|CxtCfcv^jp-3roqX`!AR!rYBqZzfuG5z2 zazI^NfkXAlqjevhIpe#<*x#y-u8z)Tf`7btohp7lb+dTjP002ov JPDHLkV1g~5&Qt&Z literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_circle.png b/app/src/main/res/drawable-mdpi/ic_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..b5c19604bc180466806ef073571d04b832d9d8cd GIT binary patch literal 644 zcmV-~0(^#1iRx1Ciz_KiB&vo5utJShW*yGtomD;v_Ov-La*;BjS{!AizHz(>59hIiI zR;%sPfg_?-n&JdQR*vJ`Lv}6YK@imGuvj^KLBEgmdrck*K-d#aX#b}0z7ky&Qr@9O z!b^78GoFQExSb}`?RIyF&j&A)dnd!(T*^tH&Xv>uAr3c{C)r(+yW>U}d&2kq1MYUZ z^i|OilHoTz97Z`oLSuIGNOQ|7;tujW?=+2%djg4>b^8;U?I<^$+mR3Kb}d~vWKQ60 zZHW?7pIO_^N>UR8gb_aD?dce$rLivC^BMq8$`S=wr6wPX{n(^TO$`v2n@Ijd*lsqP z=V_Tw|IeU=6FrL<=nT~NYGMMcn8DSg_&e-CPkA>rg<+;-qEuJFJZx(XfO~)409^>+ zvW~KVj*LH2->YuU48f+85DiS5gu+cP5;kYE*;ZKwprl0?{RTLll>_Dlw=4rVFNPW| z6cfXT1dKAEShVOLD8^)!6{`n!aHwlWqB^F)2~BewvhzkJz5GzdOStT^XgfwVG3BxG zh}LK{EItFm6L|&_f&CGaUt+w=WxW`!xDj(Crmi}W?dYO>a)xph*o>F(#6lf3ffI1A zNJI~NJWCj0V~lreO~%LxB&Mtm)3F=|0o+RaK0t{ACnQ*Wx2g(R_!WJ$qKeBAbwww#;9fona%NBRj+A)%t5?7<$<9lY|oZcx5M;DsWC%(&BOW z2m52ihYckOPH$W;P4Qzm+&o>Pa?)$2Bxj!RNdLlAlUEIa>;bnPNNnOOP*wWBI3d7U jtUtZrRDV;T!2_Td{EoeDnI+K+^Z&vmO(29EM?^5pry}7$e_}hguv> z2z+LCJ4VhN^O1QLw6aGYOu(ip?QPqh))D|OmQ_8XT#;*VbS2#goXRtYH^U0T%OYZ* z$b|tN0aYR3S}|`nS>&d4j-VktIZ|BbO97teSvnD@3jybf>(*Ev%?u@kKVzJmO`vKeh0%Ys>_R#%Sfd}~g8nfB}($Esk% z*sVw&QJDGV#E9>y{75WaVEjL$B1B#cB0*<>4v_)Jnlz()M@6*R5fc%ARs=m{hq@)A mhH9GZ+S6X;VUvviH@*S%Lfx?1eZWls0000&(vXb{mVav9YnSiM3|4IhfDqONL<_xButaY<5vw0L5Z) z*$n{Z!zFFgA1S`&0YD>>NKELWdw|*<{Kl#F?dAgbHMK_?L)COoL-d1J(GD=~;p@r> zkH_O92>iHL;Wi+S;6t+4`890kJH$k|PqC+5%P0`~29VNFBdFmsG&!_+Z{zs&x0P#CMgWokQhOzei zj72NQNW|Cc^-%=y?lb6&bv%OLGYj65$>eYp>0kAmxJs`a--A2(pV06@n__LxG^0 z_`o5kDBcVq2mmdWodE=K7N@es*x2N-a=E;Un*8$Obgf=H0Ceo_<-)Yqf0}@}3lF=x zQ*FzDE><{Qr=^=7^uGeF=Ysa_l1p^=Yh002ovPDHLkV1h;lLHqy! literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_android.png b/app/src/main/res/drawable-xhdpi/ic_android.png new file mode 100644 index 0000000000000000000000000000000000000000..dfca3a36fd1f2229b29af91267a6f2c3a7edb3de GIT binary patch literal 806 zcmV+>1KIqEP)LT<fjWo0Dwdi_bIQfZgVH#R+x*T-SX7qqkE)=xa0@!-Ya&vR13*VVF(l z(4jQOqs|u9VR01dnqd$+a9~Gi6~}Y$_n_jpQyf1Mly$$TwwWp$_@Y;wh=LY*GO@Gs4(XDefNcxS?AXE zr=yJV%3v9*rUiha1z+7!kfu1z`dbD7eB)yLNJ4jRkz$DKDva|T@4mPRG3xWVtAe*R zuY2N)=_#){jQ`K30Fd9nVF>&%1pv=J<^bT*Ab>Lt0KRx@cDI$>YfD5#Yxf?3jhHi00e*l5C8%|0GJY$c!Cyxo&kW=@dPdYylGL1 kCusBMO-tH%f@y#L4s~6nAS}m#UjP6A07*qoM6N<$f-C-NIsgCw literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_circle.png b/app/src/main/res/drawable-xhdpi/ic_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..63e9ac914f2734644e4de0f49d638507043f0798 GIT binary patch literal 1298 zcmV+t1?~EYP)q}Ho5Wm|y?O_BxEQ(}JY(ZDoU3X~%l_(5RQCFl8LljL?H0)c-`m9v6eD~irKR6#Y zn{)2#oV$1B4jk@9y>n*f%io~LI${`NfZ91{!=6JyKtJZ)=h`{QKcZ|R#QS_OKK16M_zG!flH#BVxf z*umN$E$JqlRiS0Pqod;*F+M;<{?^F&KMS~FD)D&yYN(he;xe?hOfk*~;s*&k6_!(< zbV>XXJ&W{Qq~~WWywh5tb?j0Y<7Lx^bUOWj2wro*@UdXBlkB**SS((U;Vcvi7s-b_ zCZTrG-_FuECl2th&^Px2WuCnIGa_==hPW*v?oC5O!%eUIw70k4B0O+@J2pbtq4gxF zldq%A_7%kJlW^YB^Rliz6N$tXL;=EkpmLDLg+LoTRGmEi{!2cezhhAI?$Z8WRhnST z9CEqbb=rJgwmHI+%D#00_MrU+RX)LpVhl^!$eAWf7dg479yN1NmMm#81wu9?VSd4@%@c8-7=kCf`UII{ zgkSO-er|9fPvqn^KD0`k07|06fh06m`8oYwPO_x3uYH=8RsjHzCvddl=bpn2?1*tL zKj{u|DQp5jvLwkEH$2r7ve|5-iPJYF0HLwnl86xZLgahyCa0rZWl8|JJ8%~$RF=FD zxym4#))ZQe2tfFPSqAr#TLN#JOnOWT09R=)TXm(m^Z{%Cq+<8OE&$XMBsoF7uM`t; zR#$b_qySJ<;VMfgx%CeNDy(1wdlz=a7E+&V#|oAB;V7S}|9 zV|4mG>IpUnSY+t$_Z0?lEv|$xC@yhFzLGdnmlvGs>8iLIPK9eZ+R>?Yj0D9FNtr1h zb^%C|xKr1cIIitw7YV{307(d3_HwECz-Ymtjvl=!0iX@XrNJ1|aE+|Fxj7**gU+xD z0KG`x_J5`Wv&H4?VJwNE7b&54({uDf?3C06y22&^G-M^T_V}_X*gZq+FO;9cA^}mBj`#?PJcj0g{4|CpzzM4P~++Uq0S2~-1B7v8W`cx5n2&j zU&=belzHW>G6B+C#ic2ubFUa_!HmQdPRbz!FfVJ5V{l9RhN4TnDboaD4#p=sMR@L0 z3`neLQ+*~mdPJM-DK?+;6CE7hQ5F<40lS!9GkO9jFLR->G(;j#@S7}^0&t-vr8-rU` zm_YoWz_7|eYG54s{!pm@Z$K0!`gM-ai%FGU%q&@z0!Ua;R6%9Q$y7PR^eTolFsTy6 z1ZohWvj){>5gO5V7)1w4wBbgDYGeAd5%URF1QA3KK?LUEFGAagQa8mE4FCWD07*qo IM6N<$f{i~>(f|Me literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_house.png b/app/src/main/res/drawable-xhdpi/ic_house.png new file mode 100644 index 0000000000000000000000000000000000000000..3bba0b3812d552badd58d9722da5e8ebb0f38d20 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEVC405aSW-r^>&swSF?cxo2|pb z{_K>*niRz+OtGcGFGP2}GTilwwd%Ip3UBUf_NUs7CoFYkmpyb}gcWE8!vX(2-`fS6 z!Xtbyzd6ggM4m7A_CC=teMUwO2L>hvo|n7cE!o81VJHWb%YVJ-Qp2iM=bkZLdiQFf zlEU5Bw(SkmCp0Yo`F;JT4~L7+z18{75a;U zcEO~ji_wI4VG@HcL}-=WpA7;H3@i!>-%NHaU-$a<36?T3W%IhNyX<~P*c_KOOI@?~ z*MBCEOTfw)7-x%a_{PZ2qQJn&5#e&+d&e22FUO0PpVR)gR}SQvZKv3eWlLXBpK$6j Oi0kR<=d#Wzp$Pzgl7998 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_search.png b/app/src/main/res/drawable-xhdpi/ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..39ab8a592539a05769ce6cdc00a785212afeb331 GIT binary patch literal 922 zcmV;L17-Y)P)=hHFGHuGuTrVhSLiSN zzMf1bSD~Nr`YE&&i^Wdu7~qy=9Zw_@4*;|Y{o_`NkW40XgNPeeiyweBE6~kefOjfB z{|#iMh6+3^ej1x^3<8`XVu46C9y~Uipt$xDd>aX$;_>(qqrqd7TU|hGKwrSE??Z0^ z&{h1rOL>Cg-USIOkx1l_ao}^g+!-g!Q`RT2-P{;NjDd)0BFf=e?~O{11WFb20MkM? zFZa4(fDGYtH5CbXZ`v3F0CGlQsWoggK49%oRS`>GXF|pw>a!n3#O#*Lt`m9#kaU>$(W|!EC1NbG6CU8&kRn z*kF#Pai0lz!w^u_Rr_;ibH-=VmzZ_ub$P%Vb1dEVne-0~>2ta~VB6yn&;QO4P}V{K zti8mX0`L4^k$(@II5L^a5%gl8~Le-&5B3m z@3P|3HET*U^qNB>v)b>~m@E(QUlib1O=^x(E_m+H#C&U6)>*d?qtHPJjXO<~@P0aA zlGv`g;xOuJ;r&HulEOyS2&GC=-KqPI_%s5&(`Xdp@#9BP~QFgI-3 zgVY7`6r)JU=kv$h3^@9n4ADTP#r(Zw6ba zpTlWzxGl^U9sa*$VrmG&YL}?D4=}%7f^X35kiJ{M+&}JgAUcclx&Qzn(_{>4SPujM9fj$dxC`PqftrKMOM>2hNKy=IH@)0-{gUHweWd59w z`D?*|C@t-SV~Rz_J{)GgC&uBJLX}FTT?AkyC;Hh|OW+$*4~hf1?`TAAC##F-y@b7K>ZqxJR~aH^`W2)us;uL7#6O z$Ejk1MH4JC1tdmZ|x zm(yat2f~u;x)r0%=YNp8{Li$R-`5k)m^!{cNwJt#^F6UZ=XuOD^Y@6`hpRdSo$m+B zvUVC_KHo5>ZhcP|^F48kPCu_b04@u2IY2i6e9o0h#nQg6Lou&m>tBcPMeDK!rJl>G z%LqJDA!EL86k-&kx{lP*wzxKA35iULoNqRp2Pt-M6qGU!GX%wdb4JTvAafHXfEhi% z+6_bCo)E+Qpsri%-^>+9QvlF0r?guBC{n?aK>!wcVVF+Ew(~KKN)iDe{&rKR(a&Q8 z0o>Ka|9p%lBneVdx4O@Re5|1dM6F zr(DEDY$oXO=p4RE?SN zJW34&k#;7sV!pR0B%Y44l6F#=jH1+JO1e?b^tKiKL7v# z03cQcef}z|5j%jO&tGLVau5VTkg5xQK|FZ%r|I z>1dg+88AP_bi{AfW)Na{%8PY-ypIs4De>Y3q@58dFLq}igXs_iK~nk$j=U{YN4*cJ P00000NkvXXu0mjfuy^!w literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_android.png b/app/src/main/res/drawable-xxhdpi/ic_android.png new file mode 100644 index 0000000000000000000000000000000000000000..d3e1c312f48eee4ac0751ab667c2d2dc73237a24 GIT binary patch literal 1302 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>V7cq*;uunK>+RfVe_=2^x_c}Zvwro|gs@+~%`>go z9@{VYZaL|G>%V`GZs<)pZSk-@k7Jc;?`^u2D^%iH- zha0CE;sk#D30he)@xS|X+vSg&GVFKUyC=5GQ(*t4@9$rH-t4q+!otUu`?dvdRi3w3 z-z#zcWRZm}_NC4fRx9V}b6nx6-G8Fs$!Dgl=AOL{-?fV}KdvnM_Hst?B#lKXGF1*0 zN7>#SdhzxP`^!DyE4vr|efjs52A6Nj*2lrJdpj=uNcoYxu21H~{;HpHk}2k|gbrL4 zvNfNY@pv-hGFRmrJl2$VmfD*#d~mtjkbOaX$&)jY(|=p0&tz&y4_~XrYQrjXC1cKqXt)HWtm&VB7G^h#H|5MMGC2FgH}KP$ z_!XU1t1Nw%8Xla(%OK{<>Ja)oTAJYsFWZJZXXy>u1`Y4GF=WhG5ymj#d7@7UJ5%GA zNgMRfKY8*bGK~Ma{d(6Kijz%O*xs0|-(g#_Z1V5cBw;2mcoiqQ+BRLC*%fwpj^A?j(3*-P%R1|#89QVxZ*v9Tl8#Bu>`e;&^JRBzvngxCD=E|4 z&e^$=z)VIiP;g;*Ge`T89($?V-KOGq^-QD69dyl z<96iyX5)>mF4^kp`NzWPxUMDVtwmeJ9^A^xnElnFM8f`xcGc7$>rP2upR~!-pJicG zemeiUZI&TXE38#_IzHPm|4+h4VFj7*J5PQ5|5r*%n$cr-dzxjk*S82!`-w&ujHP#1 zD>`iVyI}vg{93TnJ!u)k*IPd_tnj#JWSBOAqq6dD*AJnP_^U_~8u|8-<5$-hD@v54>6V#H(B$zH8r>t9U=DvtH&cQRlALc`yHX3FqzeYDN2HFS}lUe?oWTkGC`Qtm@ozZ%upg ow=5@P!tRgOpLWmZth26X3{yCJfNS>u4ImplUHx3vIVCg!0G*XnumAu6 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_circle.png b/app/src/main/res/drawable-xxhdpi/ic_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..1308866a9ca69fcf86ad85fac001dd9f4946ce22 GIT binary patch literal 2141 zcmV-j2%`6iP)-(68xs-O^%GK~!y>wJ&DJua8a z3-r5dbp5)oukY08=;+%4lLiQ{LR~P3&kJNIz=e**GzDe}k@_U|YFGJn`)}z$OS8PhBEiAO=p^2-cD}HZzXh9yihz zV-=eL!aUR33klR-deLeUJ6`idEYkg%%xP1E_z&pi<{%J#L;PVvn}~6T9%kH|hE!%KUVl>gwuxD^gHw0o(Lxb8=x&U{Jxo&1)HKBe!Zus=Tmx2(ZSM+^!$^sH)y`Unjpec@8tqnnxDWe zV2JoSz1S4kh$F-qF9i#PC)MCIEO?Bupi`U|PVCj-E}wc}~}JDe_m1(|UJx?1aROH3&}~Edt1gHS7t$ zH&IzfHHoklJ4=PL3fhAX+ks`8GUPX^tK*vN^-in~JX%;;5>_m5Cu}2yt=qQ421mP! zmf7qTop*&7H5TNPrTPv{R@2xOKid|#PG$0xzqZ@U@b`-Bt8&;UD;AR;f8f@rzCul4(Qt8@__(&M-J+!HsiY03_Qv3 z!oQJv`mt*j*b@RE(cq-ShM+asobb9Nc;aw3_(A|a1yz9v(>D3PaxxfaaaiFV5dd7_ zval&1TYG820NEu1e3nB3bgEqOFi5S)0XUfiO0UJ0W$Y6HI1;$2!i^P=faLpu(=9G9 ztWN~sQ*d9vO?2Ooq;k=?lve^E15ZOWkL>?=AW*qt@;tbUfuv>zA@~H1ZB>pD+y%`( zpIzD7+8lyS0&W&;ct00alW-=Rwn2wjg2JCKjk;uy;5QMTzhojfA&4bSC{m=1s}Gk2 zNq^jgg}BI+wwV!alJCQbUCJESND2yv`qotecN70l)(F6XntfGZDpHh;eL!^;&&6-@ zN&rre-%}J4KynRZMKeDO<+Ugc_RR-eKg|a)`ZPZg4^{`&InNCVsaH{n6Vjn zs7PrT#D+f13jx4#HL~N*T77YqPsn;2hTjAzYNY9GSTAEmQMEvTO&2u*z7c@^KhFeQ z+_XM1GQBjCbHB?v0nk=Kqb|;VeFV3ksY$26WrA+f1mJcIb*YLTjR;-ozG8V2{pMCi z2~d>Su(ec_qkxMv>QadkS%9BsjR5Fvp;0Zl;k*+7N>6nV|KsXt%W z2HTVNL|s)hGxN3DZy7hbe!^QPH1XNaxn=HEbNb7ibG$#PB^c6_XQw~07OY1O3n zGu#$QHt^#nv$supPlHg230(=eeso@j8pY?YAm1brEwPhe z!j29QV%lM3t%zcBlnt38zQNM%D5L>cpgn9RKa;hkNARm~CR|H|b+n*_7GB&a9|eNI z^-*yUwIisg5qtaZa^BG#GVqWF2^N5;6xaxmf`NPd4Fu!(^(EG5)^s`_Dp<}7^hHhc zmzRoctZiG)V#dcCo^vi}o$sxF#DV()4HdEgtRXG<`0bb@I{eP3hToew@ZgSUMnK0n zP{CQw^d}M7r$3<)TaC3a1A^LiEWv9)c#{O{H#$8?9U>k*@W%4~MZH!|dAaNQRB+gE z3)U}s;HB>4JTVAsw8p8hhqY!4=`f;@%?AFSI(Im9h6IU}E!haSW-r^>)r}ufq-k4$<-~ z+Fc7O4)SX(y>Mj9%ctC5F3u0Q|AqTVf+)*uF1wC@YmF~Vb6To<>~7}W;)HunH_n|* z+jKd{OBHA$6f{g-e&_YqZL`j%sUEp-f1Rbl>AI~^cQdy}&E$DzdSQpW=Z1xsU%ok| zP&Dy_Xi|?#h(H4aivj~9hXVtX00V=Aen;E{@k=JQ(~`c(6zH$GpSS({Sr(5^=bdVq zE_qCP61*r)&0$@`=?SboDlrjUJDeSgay1hg8lId~`59H?BBO7g(s*X8wGdoE8F{kvz+>(Am#*9gVz|NZ&)g^g3W>O#(c{mBT6F9rsi Z54`7Je>^?!o#z&ipr@;!%Q~loCICv^@_PUP literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_search.png b/app/src/main/res/drawable-xxhdpi/ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..47a9170b0077bce6b4faf40bd927cc1378fc0573 GIT binary patch literal 1500 zcmV<21ta>2P)mLX2l;${ zV_#q2p8o#+(*pwoS1|q=92|U#zppv){1ZNhaT%k6_m}Z^L#0w#tP-qI=!HUIGX#4Q zg1m>n(-8Q-E(4!?gU|g9#U0P(a$inNOe|8#%IJXg?t<{HVZ3t{dWte;jCXYNH&o13 z0O4$h#olO?(5nr6|13P~I=xF3@xS0dhH!qUg=XsT2*!>Rpt=v+TKJ_>X&nTAvsHqx z<_+a?`O~%(K7!*82;rp<;V)1GGpOxtCH!Ks*o%vwYCvFpWyVaM-}St=x3{NlEWbwK z^D`GP_L@v-3&v+0_pEnN17hQNKh-CJuE6U)7ZAJ0?pR@n9H-Eduk^psT1uLqlIlX&{6!>Z5MY zR2Ad8Ft_Pe(4x1@hcv(d?J+g(w#dwmg_`#-!Q>wb7x$}g7w2M4@PY@SDqxG0diu2f zdGp+z77O?q($}>i($4{@0G5RShkSoI=JG6UuH0h|P63$sd4Ya@%8;@AE*MKCL=Q;K zFz|XILu-|Ng0cLSgtmnVtC)ut`wBz2Nqb zh0Nk5JYaQJ<~lq)ye2JUg90A2oF0_|a6zlGGFKXdpn%EX6p%(iT;gYmf;bm}g6;=L zK~fOL=**C}?i3U-9$XNXs-UpC!30!+{UY!(Y$X1{t=G7wT}$O_=D*iDO$i2bde zTcJ?+-opAvlh6-xum!}TCuq8r)lu$(u^?#Cma;nu9i}mB+@d$=Q7f_yHVE5v$I<$u zXv`uIXuq*-O>AZ}6n^7d%htr1*jm*)Alx5qkC*ZcKqGsF%vs|@679^ZQ=Lj;gW3EZ zcj%D5)CemCsD2WlK>^tRhkPhP)256U_eZJSw-bI%K8tje;a@AV{ z55ICe!}X3qnl#2LD%Tf0np7&4R&wCE&-t8r?PtE%Mey_KkIe#D#joI?*CsKZC+0=g zdoI{e3cYE{mR=kV|2^YiQoz^|r6(}k$-*&J%;QB`hDPO52~pl_f`=v8^5N^CHh%jK z59P6oFO9P36G|!FkJuGkYGp;#2Z((D*eu$oq z(iB3fVgT*x>iUF(kIhQCu0_+FC)g^XE$GNo`TT^^k^hCF(vfdZP&!gNQYalM9VwKK zl#UciM@mPEdg+K~CKA18wI4b%J+OyV0UqecDCmev%L5&8`;$RfCFFsQ_*gR_PjsZT z;}N{ioTi + - + app:menu="@menu/bottom_navigation_menu"> - + diff --git a/app/src/main/res/menu/bottom_navigation_menu.xml b/app/src/main/res/menu/bottom_navigation_menu.xml new file mode 100644 index 0000000..6a80d54 --- /dev/null +++ b/app/src/main/res/menu/bottom_navigation_menu.xml @@ -0,0 +1,34 @@ + +

    + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index b78a0b8..f1bed3e 100644 --- a/build.gradle +++ b/build.gradle @@ -15,6 +15,7 @@ buildscript { allprojects { repositories { jcenter() + maven { url "https://jitpack.io" } } } From b42ec4471f1a63c8d6463783b23ca558c12381c4 Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 28 May 2017 13:16:50 -0700 Subject: [PATCH 009/122] part4 - BottomNavigationView Activities --- app/src/main/AndroidManifest.xml | 4 ++ .../com/instagramclone/HomeActivity.java | 11 ++++ .../com/instagramclone/LikesActivity.java | 46 +++++++++++++++++ .../com/instagramclone/ProfileActivity.java | 46 +++++++++++++++++ .../com/instagramclone/SearchActivity.java | 46 +++++++++++++++++ .../com/instagramclone/ShareActivity.java | 46 +++++++++++++++++ .../Utils/BottomNavigationViewHelper.java | 50 +++++++++++++++++++ 7 files changed, 249 insertions(+) create mode 100644 app/src/main/java/tabian/com/instagramclone/LikesActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone/ProfileActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone/SearchActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone/ShareActivity.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b705a69..8185c42 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,6 +16,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/tabian/com/instagramclone/HomeActivity.java b/app/src/main/java/tabian/com/instagramclone/HomeActivity.java index 461898c..1e687dd 100644 --- a/app/src/main/java/tabian/com/instagramclone/HomeActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/HomeActivity.java @@ -1,8 +1,12 @@ package tabian.com.instagramclone; +import android.content.Context; +import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; @@ -11,6 +15,9 @@ public class HomeActivity extends AppCompatActivity { private static final String TAG = "HomeActivity"; + private static final int ACTIVITY_NUM = 0; + + private Context mContext = HomeActivity.this; @Override protected void onCreate(Bundle savedInstanceState) { @@ -28,5 +35,9 @@ private void setupBottomNavigationView(){ Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); } } diff --git a/app/src/main/java/tabian/com/instagramclone/LikesActivity.java b/app/src/main/java/tabian/com/instagramclone/LikesActivity.java new file mode 100644 index 0000000..ee07e8e --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/LikesActivity.java @@ -0,0 +1,46 @@ +package tabian.com.instagramclone; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; + +/** + * Created by User on 5/28/2017. + */ + +public class LikesActivity extends AppCompatActivity{ + private static final String TAG = "LikesActivity"; + private static final int ACTIVITY_NUM = 3; + + private Context mContext = LikesActivity.this; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: started."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/ProfileActivity.java b/app/src/main/java/tabian/com/instagramclone/ProfileActivity.java new file mode 100644 index 0000000..68079e8 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/ProfileActivity.java @@ -0,0 +1,46 @@ +package tabian.com.instagramclone; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; + +/** + * Created by User on 5/28/2017. + */ + +public class ProfileActivity extends AppCompatActivity{ + private static final String TAG = "ProfileActivity"; + private static final int ACTIVITY_NUM = 4; + + private Context mContext = ProfileActivity.this; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: started."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/SearchActivity.java b/app/src/main/java/tabian/com/instagramclone/SearchActivity.java new file mode 100644 index 0000000..50e7d3d --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/SearchActivity.java @@ -0,0 +1,46 @@ +package tabian.com.instagramclone; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; + +/** + * Created by User on 5/28/2017. + */ + +public class SearchActivity extends AppCompatActivity{ + private static final String TAG = "SearchActivity"; + private static final int ACTIVITY_NUM = 1; + + private Context mContext = SearchActivity.this; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: started."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/ShareActivity.java b/app/src/main/java/tabian/com/instagramclone/ShareActivity.java new file mode 100644 index 0000000..846b4b1 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/ShareActivity.java @@ -0,0 +1,46 @@ +package tabian.com.instagramclone; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; + +/** + * Created by User on 5/28/2017. + */ + +public class ShareActivity extends AppCompatActivity{ + private static final String TAG = "ShareActivity"; + private static final int ACTIVITY_NUM = 2; + + private Context mContext = ShareActivity.this; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: started."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java b/app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java index 5800a01..fd93866 100644 --- a/app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java +++ b/app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java @@ -1,9 +1,21 @@ package tabian.com.instagramclone.Utils; +import android.content.Context; +import android.content.Intent; +import android.support.annotation.NonNull; +import android.support.design.widget.BottomNavigationView; import android.util.Log; +import android.view.MenuItem; import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; +import tabian.com.instagramclone.HomeActivity; +import tabian.com.instagramclone.LikesActivity; +import tabian.com.instagramclone.ProfileActivity; +import tabian.com.instagramclone.R; +import tabian.com.instagramclone.SearchActivity; +import tabian.com.instagramclone.ShareActivity; + /** * Created by User on 5/28/2017. */ @@ -19,4 +31,42 @@ public static void setupBottomNavigationView(BottomNavigationViewEx bottomNaviga bottomNavigationViewEx.enableShiftingMode(false); bottomNavigationViewEx.setTextVisibility(false); } + + public static void enableNavigation(final Context context, BottomNavigationViewEx view){ + view.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()){ + + case R.id.ic_house: + Intent intent1 = new Intent(context, HomeActivity.class);//ACTIVITY_NUM = 0 + context.startActivity(intent1); + break; + + case R.id.ic_search: + Intent intent2 = new Intent(context, SearchActivity.class);//ACTIVITY_NUM = 1 + context.startActivity(intent2); + break; + + case R.id.ic_circle: + Intent intent3 = new Intent(context, ShareActivity.class);//ACTIVITY_NUM = 2 + context.startActivity(intent3); + break; + + case R.id.ic_alert: + Intent intent4 = new Intent(context, LikesActivity.class);//ACTIVITY_NUM = 3 + context.startActivity(intent4); + break; + + case R.id.ic_android: + Intent intent5 = new Intent(context, ProfileActivity.class);//ACTIVITY_NUM = 4 + context.startActivity(intent5); + break; + } + + + return false; + } + }); + } } From 1cbeb887a4e8cab0e319b50d3506cf2977813723 Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 28 May 2017 13:50:31 -0700 Subject: [PATCH 010/122] part5 - Organizing Things and Tab-Prep --- app/src/main/AndroidManifest.xml | 10 ++-- .../instagramclone/Home/CameraFragment.java | 26 ++++++++++ .../com/instagramclone/Home/HomeActivity.java | 43 ++++++++++++++++ .../com/instagramclone/Home/HomeFragment.java | 26 ++++++++++ .../instagramclone/Home/MessagesFragment.java | 26 ++++++++++ .../instagramclone/Likes/LikesActivity.java | 47 ++++++++++++++++++ .../Profile/ProfileActivity.java | 47 ++++++++++++++++++ .../instagramclone/Search/SearchActivity.java | 47 ++++++++++++++++++ .../instagramclone/Share/ShareActivity.java | 47 ++++++++++++++++++ .../Utils/BottomNavigationViewHelper.java | 10 ++-- .../main/res/drawable-hdpi/ic_action_name.png | Bin 0 -> 771 bytes app/src/main/res/drawable-hdpi/ic_arrow.png | Bin 0 -> 488 bytes app/src/main/res/drawable-hdpi/ic_camera.png | Bin 0 -> 602 bytes .../main/res/drawable-mdpi/ic_action_name.png | Bin 0 -> 553 bytes app/src/main/res/drawable-mdpi/ic_arrow.png | Bin 0 -> 339 bytes app/src/main/res/drawable-mdpi/ic_camera.png | Bin 0 -> 386 bytes .../res/drawable-xhdpi/ic_action_name.png | Bin 0 -> 1011 bytes app/src/main/res/drawable-xhdpi/ic_arrow.png | Bin 0 -> 501 bytes app/src/main/res/drawable-xhdpi/ic_camera.png | Bin 0 -> 740 bytes .../res/drawable-xxhdpi/ic_action_name.png | Bin 0 -> 1526 bytes app/src/main/res/drawable-xxhdpi/ic_arrow.png | Bin 0 -> 969 bytes .../main/res/drawable-xxhdpi/ic_camera.png | Bin 0 -> 1295 bytes app/src/main/res/layout/activity_home.xml | 2 +- app/src/main/res/layout/fragment_camera.xml | 14 ++++++ app/src/main/res/layout/fragment_home.xml | 14 ++++++ app/src/main/res/layout/fragment_messages.xml | 14 ++++++ 26 files changed, 362 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/tabian/com/instagramclone/Home/CameraFragment.java create mode 100644 app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone/Home/HomeFragment.java create mode 100644 app/src/main/java/tabian/com/instagramclone/Home/MessagesFragment.java create mode 100644 app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone/Search/SearchActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone/Share/ShareActivity.java create mode 100644 app/src/main/res/drawable-hdpi/ic_action_name.png create mode 100644 app/src/main/res/drawable-hdpi/ic_arrow.png create mode 100644 app/src/main/res/drawable-hdpi/ic_camera.png create mode 100644 app/src/main/res/drawable-mdpi/ic_action_name.png create mode 100644 app/src/main/res/drawable-mdpi/ic_arrow.png create mode 100644 app/src/main/res/drawable-mdpi/ic_camera.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_name.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_arrow.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_camera.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_name.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_arrow.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_camera.png create mode 100644 app/src/main/res/layout/fragment_camera.xml create mode 100644 app/src/main/res/layout/fragment_home.xml create mode 100644 app/src/main/res/layout/fragment_messages.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8185c42..67b6bc8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,17 +9,17 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> - + - - - - + + + + \ No newline at end of file diff --git a/app/src/main/java/tabian/com/instagramclone/Home/CameraFragment.java b/app/src/main/java/tabian/com/instagramclone/Home/CameraFragment.java new file mode 100644 index 0000000..c48a04c --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Home/CameraFragment.java @@ -0,0 +1,26 @@ +package tabian.com.instagramclone.Home; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import tabian.com.instagramclone.R; + +/** + * Created by User on 5/28/2017. + */ + +public class CameraFragment extends Fragment { + private static final String TAG = "CameraFragment"; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_camera, container, false); + + return view; + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java new file mode 100644 index 0000000..c2a43b8 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java @@ -0,0 +1,43 @@ +package tabian.com.instagramclone.Home; + +import android.content.Context; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone.R; +import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; + +public class HomeActivity extends AppCompatActivity { + + private static final String TAG = "HomeActivity"; + private static final int ACTIVITY_NUM = 0; + + private Context mContext = HomeActivity.this; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: starting."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Home/HomeFragment.java b/app/src/main/java/tabian/com/instagramclone/Home/HomeFragment.java new file mode 100644 index 0000000..f0a61d7 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Home/HomeFragment.java @@ -0,0 +1,26 @@ +package tabian.com.instagramclone.Home; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import tabian.com.instagramclone.R; + +/** + * Created by User on 5/28/2017. + */ + +public class HomeFragment extends Fragment { + private static final String TAG = "HomeFragment"; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_home, container, false); + + return view; + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Home/MessagesFragment.java b/app/src/main/java/tabian/com/instagramclone/Home/MessagesFragment.java new file mode 100644 index 0000000..ba55046 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Home/MessagesFragment.java @@ -0,0 +1,26 @@ +package tabian.com.instagramclone.Home; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import tabian.com.instagramclone.R; + +/** + * Created by User on 5/28/2017. + */ + +public class MessagesFragment extends Fragment { + private static final String TAG = "MessagesFragment"; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_messages, container, false); + + return view; + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java b/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java new file mode 100644 index 0000000..87b1927 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java @@ -0,0 +1,47 @@ +package tabian.com.instagramclone.Likes; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone.R; +import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; + +/** + * Created by User on 5/28/2017. + */ + +public class LikesActivity extends AppCompatActivity{ + private static final String TAG = "LikesActivity"; + private static final int ACTIVITY_NUM = 3; + + private Context mContext = LikesActivity.this; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: started."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java new file mode 100644 index 0000000..439ba64 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java @@ -0,0 +1,47 @@ +package tabian.com.instagramclone.Profile; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone.R; +import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; + +/** + * Created by User on 5/28/2017. + */ + +public class ProfileActivity extends AppCompatActivity{ + private static final String TAG = "ProfileActivity"; + private static final int ACTIVITY_NUM = 4; + + private Context mContext = ProfileActivity.this; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: started."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Search/SearchActivity.java b/app/src/main/java/tabian/com/instagramclone/Search/SearchActivity.java new file mode 100644 index 0000000..8766abd --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Search/SearchActivity.java @@ -0,0 +1,47 @@ +package tabian.com.instagramclone.Search; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone.R; +import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; + +/** + * Created by User on 5/28/2017. + */ + +public class SearchActivity extends AppCompatActivity{ + private static final String TAG = "SearchActivity"; + private static final int ACTIVITY_NUM = 1; + + private Context mContext = SearchActivity.this; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: started."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Share/ShareActivity.java b/app/src/main/java/tabian/com/instagramclone/Share/ShareActivity.java new file mode 100644 index 0000000..27552d3 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Share/ShareActivity.java @@ -0,0 +1,47 @@ +package tabian.com.instagramclone.Share; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone.R; +import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; + +/** + * Created by User on 5/28/2017. + */ + +public class ShareActivity extends AppCompatActivity{ + private static final String TAG = "ShareActivity"; + private static final int ACTIVITY_NUM = 2; + + private Context mContext = ShareActivity.this; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: started."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java b/app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java index fd93866..59417f7 100644 --- a/app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java +++ b/app/src/main/java/tabian/com/instagramclone/Utils/BottomNavigationViewHelper.java @@ -9,12 +9,12 @@ import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; -import tabian.com.instagramclone.HomeActivity; -import tabian.com.instagramclone.LikesActivity; -import tabian.com.instagramclone.ProfileActivity; +import tabian.com.instagramclone.Home.HomeActivity; +import tabian.com.instagramclone.Likes.LikesActivity; +import tabian.com.instagramclone.Profile.ProfileActivity; import tabian.com.instagramclone.R; -import tabian.com.instagramclone.SearchActivity; -import tabian.com.instagramclone.ShareActivity; +import tabian.com.instagramclone.Search.SearchActivity; +import tabian.com.instagramclone.Share.ShareActivity; /** * Created by User on 5/28/2017. diff --git a/app/src/main/res/drawable-hdpi/ic_action_name.png b/app/src/main/res/drawable-hdpi/ic_action_name.png new file mode 100644 index 0000000000000000000000000000000000000000..3c23c894efd7ccbdb2a2618c3496508d3f1f48fb GIT binary patch literal 771 zcmV+e1N{7nP)d1o7qJVTRJ;@`2@aJ~fw;G;c`z_)@t4@bY9fU!~dY_%2qZjgR)7W_XH_>4y$`PIP}FhcjycNREp z31`5058TrV5gGIFUz5L!3Im}8Cbk&}GBM!RR0uq%m%O^Md9%iw+T7eqbW2V)Ob z_$JzCGWvG}k{Pr#Sq^>!c$cIlvxN2r4sq%Fvtl4%A{s$iYfvUH(MH7pzOS6#^S%nC z7n}9=5akVWWT@vRNNqkC^#K)5qKzyrIZ;_vP zNzB*{;Em>+X?`zAQ~=Qyk|Y_ znh@NTUdS39hVMVQObG+{$b@8%w0?6jJZ$L(uV313_nQ)pN+JdoC#+4Ym)?VXpJP!5 zu2peJO@Z__`nrNLzy`X&c@x~9C111X+aCQ-4bzi08vNk*+M3!7e*Pf literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_arrow.png b/app/src/main/res/drawable-hdpi/ic_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..aa0da6643c808784e83e7cbfe97221480a122641 GIT binary patch literal 488 zcmVP)>q2DVCrZmy}rS9IQvU{&7FUOMY0y!E}2EZ7Y1MA=bT!QC> z1>zHOAB<+T%AH^cOn?Qj4UWOB=8RPZE1=iJL#nH|p{(K)s2hHXufR0zUgC5#Sj8h+ z#kz%KRBBTG?=LjrAL*{h2->!2qmh#PS}3@TpuR+g7JZk>Ha!$1^!oTvoq==VGTq0_ z+|fC~J@8vOqvwA;ubCT*MHU$eivwGdkg_%~k>rw!^DSTjtR$HO4b#q_0+xdFHZ$O4 zoem~|v?8(pFlxG zz#~EDZF)h@r!j1(3itq0egd|EDPaMVpeCqWz(TP{7!$zi`T!eL8OS0Ppo#fqQ57)2 z@*89&;F*#DHWGAjpp$8kU4`&ki-5L=gH@c9E`S4%j@mUXpwB(|IL80bW$i0a=hi1A z!%3@v8Q0#KW4FN4XAk@AniElyNNlYF_^#LpaNa4Rrr7;eyx%wdaWpYu@wt(W3UPOA|;N^=3|1+kMQ^@WM%v(#`q4vB+Q2=!8@lv omcqm~Niuqe8d+qKMYcBk1;nI~%8K7i(f|Me07*qoM6N<$g7!`k1^@s6 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_action_name.png b/app/src/main/res/drawable-mdpi/ic_action_name.png new file mode 100644 index 0000000000000000000000000000000000000000..a9ca9481e51bcbf9765a4789a103a8a47dcbc0ab GIT binary patch literal 553 zcmV+^0@nSBP)8xl6sR0WGBEbK@SQU8ENe?UEgsD`z$B1K;wKgxIK zPTT2CA9HV~D?Q1V+GUWkVvSWM6ei~v4D%z^#H3t7+BzB3M4FD z9U(dwj89zF&QjU&GuA0i!t{Av-`p_XgyEb^0?Rf6UBI+>|5PE67KRfF!3^`vY`SsS ze+WNMcy9y7q_j3nzzn*GmQLW6H<)q)F^NFD83cT`JfA|>FMhoUbU)JCPBRD?e7x4L^mjo_I{{M$vG!6U zxLKU@dKyvnPB?&*IK!TATT0Br9M#bYRfka@A2Qay;W~S#)Q3@_sSq7&yW9~S2%onq z+e1=5{TjmiinD;Rbrk~-zrz)V3(+BTlfZ~W1Yo;g3{I4Uu0xfzmlu`3OKFl9uS4C+@gaK-mt`4 z=R9_oL;)3v_LROo3FM9M$OE1*#RoPv0e&z*%E<#RkU<%3^o>_e)cK9Q#02kXB5wDv zti-QyO3d(rlJ3_~s%Dh|&erTlfM2}gM)$|atU0awbL^>Rw*i#ZEE_=7JXBe;(*UC8 lmLD~r`&;gN&EbV-y?+H>;ZIJ6MKS;Y002ovPDHLkV1oOdm(~CP literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_camera.png b/app/src/main/res/drawable-mdpi/ic_camera.png new file mode 100644 index 0000000000000000000000000000000000000000..2dfba8f62b3d914ebf48cf03565795f53fb5a9aa GIT binary patch literal 386 zcmV-|0e$|7P)!UyZiN~G!?Q@R z9ENA1nE^606^MCoS40pcV8<7{2Y{Fzsy2_B4)BGlF(4v==|a^83@Zm@4RjQ& zLP~@&c+^EACBn7T&W7$tYGbfu!zd(qFItoXpx{+TD~JrR6hx{}2hpS`J^&2~MlAXn zp@r2!dQ?WMpb66#inF1G72Rq>npDT;baa3Tt|r+EI#|98SCb3`_<%SQ+5+yRG6tEM g0kvZkjDo=f00Uu_x=?HJ%>V!Z07*qoM6N<$g6YPVFaQ7m literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_action_name.png b/app/src/main/res/drawable-xhdpi/ic_action_name.png new file mode 100644 index 0000000000000000000000000000000000000000..d6c4b6fc2d710276da43d8c1ad5a8e6871d27862 GIT binary patch literal 1011 zcmVt+mh>5iNqRDnhM@94MkE^{a{semoRE9;y~Rsfb#uB8pmy;Dgo& zt5$ueQf#m7akO50o_~~+Y{YXno7>yX-ew^Kzn9%?X6Bb)*oI0cHE`UHX|$~) zZ0Gl(qN0Y*|HUt~F&*Z}FS;n6#cB8$aRt#6GN_J+s52`ep;P^u7f<_HeAk7jiy#gy zMI1yMrd;e=t42<$wmLiqz*$2okuyv76!yGDL18Kbhq5vKs2 zsZjpG*6GuluX1k$(02E2@5h5Hcd~j-V*+|?@8?tykhKwTH39;LBr#xRS<4HKG+A>3 zl6*gh3hnlw?g^IemII)lS{Nq+Xz<+6Gr4iZPo7=o@Yx9OyFEbv+7duVx?7UI+LM@J zY`;-Y0<5GcTP1Qn4mOKE^vu3P>x$3jLWkepQhT@L8nxq{Z|iq zU+c09bW0p5VIRHNrr!3=R_3Jpck~RhEFRk+z$?iXC;OfrYkx@6-kotE0C@RYv+{aQ&`i!tx8>57e!myg{4&pl{x>J2fU;Y9ib2~Wh0Z;p4X#Ci75Fm zNG_dhE7Z^Ve3&EeEPPtia6tpdi#*`9L=l1MR(J{xc+S^kfiICTQQ$G>CF(wdSWk=? hF=E7s5hF%?$R8}8v(hf#ECT=l002ovPDHLkV1fqc(ewZS literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_arrow.png b/app/src/main/res/drawable-xhdpi/ic_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..e08a36c19859f39eb4806b2876906b5cfcd38a94 GIT binary patch literal 501 zcmV5iko@Km(i-x5xQBLTL}lw+F}ekj;Z*d)UmQNczn0joI7a zD%b;O;0}D06mSI=K#ju(%x-|gUc=9AKX6wPYBW#0cq{V~!qmz`R| zEKLbD_bq^3&3y@ATXUBJf~dI*0YTNgN&!LE{J#R;!EwknFDu{~Y{yXZP6b?prI>17 rL_l8isYF;B5^Ao|Xfzs)Ms~gcm|TTHfQYw200000NkvXXu0mjf^P$Y^-}+UT&W-~QlW*5S7@jOJxC#4 z*vnK}MfOMaT{yFeGc)hLxijzH>pAe-Jl>p{@0*!>?>TpJISB~~35nF=I#@_Zx2xhi zzz^^@A>Y9z*Ti20y9UGu?0_~`#J7Mi2E_+_0_SWO-vriD5FbzkXKNuW5AJ~nF}zDr ze86%A*P*WUstMt@Kq&)JY4I8KS1W!H{Bc-(z;AG0S9~it_CS2VPtdGmz!Q(e2Mp;L zFzcZKZ*&ZJ>!AS)Vt_>k9MSZ;N|Z7fbZc(FH}Delf;#4$>bE{n0DC?ea6q$4qsIBw za(4_Ix^BQaXir#GZn|o~qM^b?63K2Hmi0x=X*yfhhj5;8NO9MQZ`#nncP zaRU*r!=VcXjE0QxQ{be6K)3i^;W-;IVzr zZCWSfBhK4JO_d$rx5mm;JFE~}hVQm)j*0;Z4Vd%LfEgVFo_c7&h>iglz%P%)s~x2l z-9^ZwoFAXbDGh_wuEg%9G$&`pSL#P33RRZ&kc$r;L0xNiNJ%XrAt50lAt50lf%pg6 WA6CQ5_0M7e0000u(iB6rY{q1)&yVXdxyf1R{|Vixty|&=LrS1SE~}nFb>vh5!OpjE3MN22CojQW})- zQlXVsppYscNTHVYmOqL!vr|QSXLe@q?(EF&`6VZO=yrPM{N{P)oC6^U1OkCTAP@)y z0)apv5C}was0CR~DBTTm9OM!Sfh_bKgy@22PAB3XjId>zr(^Wqd}4NH~hd`f?WZ)zMjEEVVawN5fJcqgUa6zTDSoO0}}Rs_sC~n4FQDjb(Oz= zV1t005&|xGbh)aQfL_V>50L;pOa-0qYY^}^_x2(I(wl6F8#DaZbopBWI`@I@w<-#y z{nFcQK?z_Zv6VlVGxu@$h(0V%BoBqrdO^0scg+T_kU%1;gGiwWm;-I^g}-sn@X=%d zes>E=doa&f8HK;Q2ni5fvYu_v z5=~-jo6pF&1`)estIR+N37CvV9%G*_0qod0yDBYn9vk|43Q=(rI$k1`;{B0;Ntg%i z{hF}xyGT+c$O;l2&DQ9x(DtJ$jn8t|HjpIKrwSIHUN2H(|1vcE4fx&7B#o^7j0un> z>GhLzlk{EySDle1#<3(x63#I355U@w_u(7TH1T0saw7#;Tz#11ywqyoXsUFj( z&6ucDJa({Us42(hU!aKOV||}%YZP=v1W}c8X#5&pJy%_-#~NB9Zk^u{e+qZ#o_snZ z9`@JTR_K&QxvxCT1S;~BqoOvf*T`EO8QC0G6I|r6@#jMye$sf>%&1ITm`EL6Etl1m z4l5B(^}y(C)-L1As7}NNrTel}c8YfNStyT0n$J;?!;Z-jQ5A8>@L?zOK~*d2E*GtM zcfU(F|Jp)TP!C7Gb8Z*59PO+kW6=jGLmxkPeJ^WLR+#mB$?>5m?Z0l~Ht}##_I$*% z|2yVg;(je`DOlujJHMEPGvki%C6yhM5grV{-l8e}7IfYO@(Mv95C{YUfj}S-2m}Iw cKp+yrQ>#-{oHUJffB*mh07*qoM6N<$f)o(6?EnA( literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_arrow.png b/app/src/main/res/drawable-xxhdpi/ic_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..33a55ed35c9b28a0adc6823b4a9c83b229c1a3d3 GIT binary patch literal 969 zcmV;)12+7LP)v@BbGtjsD2k#eilQirq9}@@D5{|7sc zFW_>NuSM`E{0DvypN5yhEnJ#%0n|N@!`I**E>9Q$zK7sljHhq_>Jm>M;8XB2##8wK zit#iEZy<;;0CLyhC-82#mCIN@03XCV##1-|#dx|Z@k9jx;BVT)@D9dP7yv$qJf2wY z0sv@M?lyAC!vOI8SY}U*r$7Me-t6f(+?8@Xg#yqlp4O!ZLIVK5Qw*gRPY%GC5&*^1 z)5#R#sY4>5uGHqsodfVwF#z-BE*1c0%Ux^$%$2*C0hlOvRsi_r?pRFmWC?)p9}-V% zwS%w z8lNT(%7uND&FohKAoAH$r>1zC122&=@mBZ@ zwJ_$*)Sat)rn!qXjz1jqTeA6AVpw4J&C&8Eckwg$i)>s|nf~_)?pn`ijhWUaS$rRU zl{LP&`yKHpB9EDBYA1@&F>_NIdTEz)0xQlp=shiJ88br;f1!a53{4J`b<7 zFanMRKuzXL`(uomnVRr;1ToWV^-Yt;-&FnCOt-Z+P0av|Dq4Iun>lDLX0!uvF>@Q< zZ2fN61RyU>11ZFeHUQCw~!-Chy^7c=hDm2-@l@&UM*ImDPL7eGFn>F4s42Oyu#T*wUmY@k_f@I#r+ rv~f8oilQirq9}@@D2k#e>fiMj49@G)wfD1x00000NkvXXu0mjfQUSvA literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_camera.png b/app/src/main/res/drawable-xxhdpi/ic_camera.png new file mode 100644 index 0000000000000000000000000000000000000000..4958ef1a38c358b97a37c6a8ffef96f1d0b385cf GIT binary patch literal 1295 zcmV+q1@QWbP)mm zga|FxBI?K1ALX1lH$k{_@9fO%?49#XJ}**ty61a$=FFKN6@tZLu~;k?i^cL@HNbqs z)Nq*ptrTzwm@rHiwZ-~N7?|(C55s%~_HwxY)GpwYh2RH#1h#P4e`$l|;0F|ewY~>` z9q_gS!4DV*T6_)ua^OV;gC8&kEb%S)^}tgHf*&vn)Kz03Yk|2jX#^fP6#RfYK!d{P zskNP}W1pD=9s;iv^6>W#20x&n@OfU*3)M&6s~H`p4Q6x4f$6$~KO4Bl z0glWSV5Uw3&H_^$*vOQC6S{)G!cvJKX?y{ib-n!@P&H2KNHa${kjmTz(&ZR14|vUi zROUG_ryK(oP|=Emsm25?0*=xRKQ9LbHc7^kcwq&z;Ap2_E=n4>a?^Iqbdx*H-EQcmotq}>5@7vd=s2E zV2TFYI158Ns2jOX#jd-wSd<600<&T~Z_x0V;Jg7BBlh`=DZl?1;h9A;BO7r{xaz9` zZ)k@^n9!Uq`q{Y8$13jr2wl`tgDI-h2J}eUuA#TSROa~7FBxA_G*9r#fY*|~I!(dX z)m~2WO{g<8V|LbnBa(KzG-oK^gnUbSpDzYr^>TGcn~jQnz6{(zwJ@aJHUkAbCk=Qk z$$W+lW+gdEM)b@F19Fl)-{cJSousNdd+i6iJs&H29^~S8= z@WnQT-z`ONa9YIQ)`&m9N0>i=UNxI@3yLPFYBzONygB!;Z^BVw_Fm64Wjwa7UZ}bQ z8YLQ-vj&2X1NlY42Q(t5kljMhZB)1eugB0tEAfZ)UQ*ejC1%%zT@7yj!X0>(ylNpa z$5bb&irPzS2J2}8RZqWTGyNN;sJQRwv2f%3aH0=tmuQW-DD0j2VgsrSHh>La1IjXB z9;JjFOf~Ro=CUqq!aV#D2U3}PLc<-RBOFL&26Rl}S2>*KxeV5}mg%aaoELm?Yup3q zd7XtU97t|)U?X!a=E6|qqSml*`-(6ZN+x+>@Jf3uh_#XtV^m>$=Q)_`KcRK#HNxWG zDZ_^9XtL%ra|Qo#I2Mb=VzF2(7K_DVu~;k?i^XEOt)Gh9LpDK%q(1-v002ovPDHLk FV1g_YTlfF~ literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index a1d7632..ad7a57d 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -5,7 +5,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="tabian.com.instagramclone.HomeActivity"> + tools:context="tabian.com.instagramclone.Home.HomeActivity"> + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..2300656 --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_messages.xml b/app/src/main/res/layout/fragment_messages.xml new file mode 100644 index 0000000..7ca935b --- /dev/null +++ b/app/src/main/res/layout/fragment_messages.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file From 37a7d8091e96bc0316a7f456b4451fb279d797b5 Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 28 May 2017 15:15:05 -0700 Subject: [PATCH 011/122] part6 - SectionsPagerAdapter (Home Tabs) --- .../com/instagramclone/Home/HomeActivity.java | 23 ++++++++++ .../Home/SectionsPagerAdapter.java | 43 +++++++++++++++++++ app/src/main/res/layout/layout_top_tabs.xml | 4 +- 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/tabian/com/instagramclone/Home/SectionsPagerAdapter.java diff --git a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java index c2a43b8..69b4db7 100644 --- a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java @@ -1,11 +1,14 @@ package tabian.com.instagramclone.Home; import android.content.Context; +import android.support.design.widget.TabLayout; +import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; +import android.widget.TableLayout; import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; @@ -26,6 +29,26 @@ protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "onCreate: starting."); setupBottomNavigationView(); + setupViewPager(); + } + + /** + * Responsible for adding the 3 tabs: Camera, Home, Messages + */ + private void setupViewPager(){ + SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager()); + adapter.addFragment(new CameraFragment()); //index 0 + adapter.addFragment(new HomeFragment()); //index 1 + adapter.addFragment(new MessagesFragment()); //index 2 + ViewPager viewPager = (ViewPager) findViewById(R.id.container); + viewPager.setAdapter(adapter); + + TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); + tabLayout.setupWithViewPager(viewPager); + + tabLayout.getTabAt(0).setIcon(R.drawable.ic_camera); + tabLayout.getTabAt(1).setIcon(R.drawable.ic_action_name); + tabLayout.getTabAt(2).setIcon(R.drawable.ic_arrow); } /** diff --git a/app/src/main/java/tabian/com/instagramclone/Home/SectionsPagerAdapter.java b/app/src/main/java/tabian/com/instagramclone/Home/SectionsPagerAdapter.java new file mode 100644 index 0000000..7f3f55e --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Home/SectionsPagerAdapter.java @@ -0,0 +1,43 @@ +package tabian.com.instagramclone.Home; + +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by User on 5/28/2017. + */ + +/** + * Class that stores fragments for tabs + */ +public class SectionsPagerAdapter extends FragmentPagerAdapter { + + private static final String TAG = "SectionsPagerAdapter"; + + private final List mFragmentList = new ArrayList<>(); + + + public SectionsPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + return mFragmentList.get(position); + } + + + @Override + public int getCount() { + return mFragmentList.size(); + } + + public void addFragment(Fragment fragment){ + mFragmentList.add(fragment); + } + +} diff --git a/app/src/main/res/layout/layout_top_tabs.xml b/app/src/main/res/layout/layout_top_tabs.xml index 057bbfd..07e69ca 100644 --- a/app/src/main/res/layout/layout_top_tabs.xml +++ b/app/src/main/res/layout/layout_top_tabs.xml @@ -9,14 +9,14 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - - + From 82996f0a25b98340d4b249eafc904495ea3989ee Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 28 May 2017 15:39:15 -0700 Subject: [PATCH 012/122] part7 - Profile Toolbar and Menu --- .../Profile/ProfileActivity.java | 31 ++++++++++++++- app/src/main/res/layout/activity_profile.xml | 15 ++++++++ .../res/layout/snippet_top_prolfilebar.xml | 38 +++++++++++++++++++ app/src/main/res/menu/profile_menu.xml | 8 ++++ app/src/main/res/values/colors.xml | 1 + 5 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/layout/activity_profile.xml create mode 100644 app/src/main/res/layout/snippet_top_prolfilebar.xml create mode 100644 app/src/main/res/menu/profile_menu.xml diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java index 439ba64..b54d45d 100644 --- a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java @@ -4,6 +4,7 @@ import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.Menu; import android.view.MenuItem; @@ -26,10 +27,30 @@ public class ProfileActivity extends AppCompatActivity{ @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_home); + setContentView(R.layout.activity_profile); Log.d(TAG, "onCreate: started."); - setupBottomNavigationView(); + //setupBottomNavigationView(); + setupToolbar(); + } + + private void setupToolbar(){ + Toolbar toolbar = (Toolbar) findViewById(R.id.profileToolBar); + setSupportActionBar(toolbar); + + toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + Log.d(TAG, "onMenuItemClick: clicked menu item: " + item); + + switch (item.getItemId()){ + case R.id.profileMenu: + Log.d(TAG, "onMenuItemClick: Navigating to Profile Preferences."); + } + + return false; + } + }); } /** @@ -44,4 +65,10 @@ private void setupBottomNavigationView(){ MenuItem menuItem = menu.getItem(ACTIVITY_NUM); menuItem.setChecked(true); } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.profile_menu, menu); + return true; + } } diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml new file mode 100644 index 0000000..a87afc0 --- /dev/null +++ b/app/src/main/res/layout/activity_profile.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/snippet_top_prolfilebar.xml b/app/src/main/res/layout/snippet_top_prolfilebar.xml new file mode 100644 index 0000000..75fe57d --- /dev/null +++ b/app/src/main/res/layout/snippet_top_prolfilebar.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/profile_menu.xml b/app/src/main/res/menu/profile_menu.xml new file mode 100644 index 0000000..bfa37c2 --- /dev/null +++ b/app/src/main/res/menu/profile_menu.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 226a646..85e3809 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -6,4 +6,5 @@ #bfbfbf #fff + #000 From 766ec53ac97cef3d4edccec18819bea2a5825be0 Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 28 May 2017 16:03:14 -0700 Subject: [PATCH 013/122] part8 - Building the Profile Part 1 --- .../Profile/ProfileActivity.java | 5 +- .../main/res/drawable-hdpi/black_border.xml | 24 ++++ .../main/res/drawable-hdpi/grey_border.xml | 24 ++++ app/src/main/res/layout/activity_profile.xml | 2 + .../main/res/layout/snippet_top_profile.xml | 109 ++++++++++++++++++ app/src/main/res/values/colors.xml | 2 +- 6 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/black_border.xml create mode 100644 app/src/main/res/drawable-hdpi/grey_border.xml create mode 100644 app/src/main/res/layout/snippet_top_profile.xml diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java index b54d45d..4515c5b 100644 --- a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java @@ -30,10 +30,13 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { setContentView(R.layout.activity_profile); Log.d(TAG, "onCreate: started."); - //setupBottomNavigationView(); + setupBottomNavigationView(); setupToolbar(); } + /** + * Responsible for setting up the profile toolbar + */ private void setupToolbar(){ Toolbar toolbar = (Toolbar) findViewById(R.id.profileToolBar); setSupportActionBar(toolbar); diff --git a/app/src/main/res/drawable-hdpi/black_border.xml b/app/src/main/res/drawable-hdpi/black_border.xml new file mode 100644 index 0000000..8578c9f --- /dev/null +++ b/app/src/main/res/drawable-hdpi/black_border.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/grey_border.xml b/app/src/main/res/drawable-hdpi/grey_border.xml new file mode 100644 index 0000000..6a5f22b --- /dev/null +++ b/app/src/main/res/drawable-hdpi/grey_border.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index a87afc0..d867061 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -10,6 +10,8 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/snippet_top_profile.xml b/app/src/main/res/layout/snippet_top_profile.xml new file mode 100644 index 0000000..e4d875e --- /dev/null +++ b/app/src/main/res/layout/snippet_top_profile.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 85e3809..a054f79 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -6,5 +6,5 @@ #bfbfbf #fff - #000 + #000000 From e8ae7140c3624de4a4d1e88d48aaf474a47787a1 Mon Sep 17 00:00:00 2001 From: Mitch Tabian Date: Mon, 29 May 2017 20:07:10 -0700 Subject: [PATCH 014/122] Update README.md --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index 2b0aee1..d94fa82 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,27 @@ the database would roughly look like if you did that. (SQLite is probably fine)<

    That would require a TON more code. Setting up the server/website alone would probably be another 20 videos or so. So to keep things simple and condensed I will just use Firebase for everything. After all this is an Android Course, not a web development course.

    + +

    Lecture Source Code:

    +
    + + + + + + + + From 75567884e79c207bd7ddaf9695cfe6b5cfa0f85f Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 4 Jun 2017 12:40:00 -0700 Subject: [PATCH 015/122] part9 - Building the Profile Part 2 --- app/build.gradle | 3 + app/src/main/res/layout/activity_profile.xml | 9 +- .../main/res/layout/layout_center_profile.xml | 161 ++++++++++++++++++ .../main/res/layout/snippet_top_profile.xml | 2 +- app/src/main/res/values/colors.xml | 2 + 5 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/layout/layout_center_profile.xml diff --git a/app/build.gradle b/app/build.gradle index 4c045c8..8bafcd1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,4 +34,7 @@ dependencies { //BottomNavigationViewEx library compile 'com.github.ittianyu:BottomNavigationViewEx:1.1.9' + //Circle ImageView + compile 'de.hdodenhof:circleimageview:2.1.0' + } diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index d867061..50e2ef6 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -8,10 +8,17 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_center_profile.xml b/app/src/main/res/layout/layout_center_profile.xml new file mode 100644 index 0000000..237b83c --- /dev/null +++ b/app/src/main/res/layout/layout_center_profile.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/snippet_top_profile.xml b/app/src/main/res/layout/snippet_top_profile.xml index e4d875e..4c13865 100644 --- a/app/src/main/res/layout/snippet_top_profile.xml +++ b/app/src/main/res/layout/snippet_top_profile.xml @@ -5,7 +5,7 @@ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index a054f79..7850def 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -7,4 +7,6 @@ #bfbfbf #fff #000000 + #005ce6 + From 194fbc7e36d15f4ac7656b90d7a3c982ef703a01 Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 4 Jun 2017 13:20:00 -0700 Subject: [PATCH 016/122] part10 - Account Settings Layout --- app/src/main/AndroidManifest.xml | 1 + .../Profile/AccountSettingsActivity.java | 24 +++++++++ .../Profile/ProfileActivity.java | 24 ++++----- .../main/res/drawable-hdpi/ic_backarrow.png | Bin 0 -> 272 bytes .../main/res/drawable-hdpi/ic_ellipses.png | Bin 0 -> 204 bytes .../main/res/drawable-mdpi/ic_backarrow.png | Bin 0 -> 178 bytes .../main/res/drawable-mdpi/ic_ellipses.png | Bin 0 -> 153 bytes .../main/res/drawable-xhdpi/ic_backarrow.png | Bin 0 -> 258 bytes .../main/res/drawable-xhdpi/ic_ellipses.png | Bin 0 -> 264 bytes .../main/res/drawable-xxhdpi/ic_backarrow.png | Bin 0 -> 458 bytes .../main/res/drawable-xxhdpi/ic_ellipses.png | Bin 0 -> 472 bytes .../main/res/drawable/grey_border_bottom.xml | 19 +++++++ .../res/layout/activity_accountsettings.xml | 38 +++++++++++++ .../layout/layout_center_accountsettings.xml | 33 ++++++++++++ .../snippet_top_accountsettingtoolbar.xml | 50 ++++++++++++++++++ .../res/layout/snippet_top_prolfilebar.xml | 9 ++++ 16 files changed, 183 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java create mode 100644 app/src/main/res/drawable-hdpi/ic_backarrow.png create mode 100644 app/src/main/res/drawable-hdpi/ic_ellipses.png create mode 100644 app/src/main/res/drawable-mdpi/ic_backarrow.png create mode 100644 app/src/main/res/drawable-mdpi/ic_ellipses.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_backarrow.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_ellipses.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_backarrow.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_ellipses.png create mode 100644 app/src/main/res/drawable/grey_border_bottom.xml create mode 100644 app/src/main/res/layout/activity_accountsettings.xml create mode 100644 app/src/main/res/layout/layout_center_accountsettings.xml create mode 100644 app/src/main/res/layout/snippet_top_accountsettingtoolbar.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 67b6bc8..b7613a9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,6 +20,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java b/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java new file mode 100644 index 0000000..f5fd21d --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java @@ -0,0 +1,24 @@ +package tabian.com.instagramclone.Profile; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; + +import tabian.com.instagramclone.R; + +/** + * Created by User on 6/4/2017. + */ + +public class AccountSettingsActivity extends AppCompatActivity { + + private static final String TAG = "AccountSettingsActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_accountsettings); + Log.d(TAG, "onCreate: started."); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java index 4515c5b..83b844b 100644 --- a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java @@ -1,6 +1,7 @@ package tabian.com.instagramclone.Profile; import android.content.Context; +import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; @@ -8,6 +9,8 @@ import android.util.Log; import android.view.Menu; import android.view.MenuItem; +import android.view.View; +import android.widget.ImageView; import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; @@ -41,17 +44,13 @@ private void setupToolbar(){ Toolbar toolbar = (Toolbar) findViewById(R.id.profileToolBar); setSupportActionBar(toolbar); - toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { + ImageView profileMenu = (ImageView) findViewById(R.id.profileMenu); + profileMenu.setOnClickListener(new View.OnClickListener() { @Override - public boolean onMenuItemClick(MenuItem item) { - Log.d(TAG, "onMenuItemClick: clicked menu item: " + item); - - switch (item.getItemId()){ - case R.id.profileMenu: - Log.d(TAG, "onMenuItemClick: Navigating to Profile Preferences."); - } - - return false; + public void onClick(View v) { + Log.d(TAG, "onClick: navigating to account settings."); + Intent intent = new Intent(mContext, AccountSettingsActivity.class); + startActivity(intent); } }); } @@ -69,9 +68,4 @@ private void setupBottomNavigationView(){ menuItem.setChecked(true); } - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.profile_menu, menu); - return true; - } } diff --git a/app/src/main/res/drawable-hdpi/ic_backarrow.png b/app/src/main/res/drawable-hdpi/ic_backarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..ef7f278fb7a08aa9c61eae6caba749d032427f88 GIT binary patch literal 272 zcmV+r0q_2aP)VSi2jpktc_q!%!xTMC+0L-PIA3*hKO@A`R8t&Q{@bkIYI~_zsw8Y WKGa7`MWP`90000`!4??6S@noygtrU+#)UU^rO+Ay!z!LshwBtmS?rwy43J*k~L${ pb>Y6~v_$|+F+gcB#mLYguQ#i)+;O98w*}C744$rjF6*2UngBrwNNxZC literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_backarrow.png b/app/src/main/res/drawable-mdpi/ic_backarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..df7b5f2f9e1b8b944adb39a995ace74ac43219fa GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJN>3NZkcwN$2@B%a;sy1)qNLX<6JSQF>%Tk;^>?lamR378U}&Mk($*GoCI^5D8#q ZVAx?Bm;8i<%N*zk22WQ%mvv4FO#m39INbmM literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_ellipses.png b/app/src/main/res/drawable-mdpi/ic_ellipses.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ac25545d3371816e6ba30dec80feeff50dd8d9 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ1Wy;okcwMxr#Nyo81S%smeQ@; zaCG1Kc{Nk2JsgjGc1jd`Hm6lZ*zv@no36s4Iqx32@)W91-+kn#l-`fWN_fOau>y85}Sb4q9e0LL*k AM*si- literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_backarrow.png b/app/src/main/res/drawable-xhdpi/ic_backarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..2367cf889c590bbffb2d95228116f363eaa6d550 GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Cp}#pLn>~)y=BOC$U%hdA#1M7 zo{ox+IY&=Tj#x1v&Y<2rV7-#faUd`(3GEQ@1+c# z^#8vpd%dr9%KPgs9R@1*-wQx&A745pZM?L?V6!wbXJQ2xt-L sU(%-3GU~)z2V5!Y#`zqxII9- zRNbnmx+$PQn{{FL1-(^*N+Rq@3ri-<;pU(7ul*XG z;JeI^JDJ+1V4Udb;uunK>+PNWdd-0{#~)5_ zJGh@i{J_~6F-;d0dQbLxSaqCD*m%=dMJ%@}uui>FT2^Fz!MW;N&nMRib6&R0mseVv zsp2^aj4qk4wQMTlO?tj@^Nn4PPyBzf{ILA-d$+s;jvbairnWJ2cZs05$EoAz{yaQy zmT7NZ;Pe0dxsrp&-d?XzO-V?B`~IglHZ;p7 zvRfbGD{GN`!(n|xunZ{hCV}1h#z8(Xv*wLm*%iCLrg`gMUW`uIwQ2GJ)ceNTURm*g8M5LZ+LwNR8o%zv<@?f2W??^sstOr5haZ}nf9R?H!q?glO~1u_ zl>7ZD`9;3vu5Q`meA;&%FCX6T|N7KLjcqTdbEH~IeLZ<8b)~lZbv;IRi$j8a1ue=l z4>@o#e<`}(?prJ4{xWxxdfyrz_kX#mj(vX~Uu%+C+TT9!kC9B`as&4pnt!}LJn@Ev d;G{35?^WCaH9GFS;Q+=FgQu&X%Q~loCICV4Uyi;uunK>+P+BUQU4mY!8II zI6lcXDSWut;=sWozi966X^*sSv26=p63Ty-<+yLaBir!jI{WzliO<;C^ZitPAtTTz z1_l{}o*3!FKY5hCPs~gat<;ZnlT$9A=$&kJ_wqmEAGuFn_va{0J~6fMtNov&_Rat2 zrhC8m{>Dbu@K3GUxj=h4rQLkoH>TWY(K>6zQ$OGR@oIbf^`hJnQi*eKpV*be_ApS~~lrJ(JZ?EHU?AHP0U`&4w~ zgLqwy|K^sTjm2BE>!T(9ah|`pL+8=jJ&V?zK7MP>pWKIU<`haU{QAiDmBswsSzIIG?`2%>)Y7hQs?9-_N?M!Nqy}B8czl>gTe~DWM4f D=}yoS literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/grey_border_bottom.xml b/app/src/main/res/drawable/grey_border_bottom.xml new file mode 100644 index 0000000..b161448 --- /dev/null +++ b/app/src/main/res/drawable/grey_border_bottom.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_accountsettings.xml b/app/src/main/res/layout/activity_accountsettings.xml new file mode 100644 index 0000000..b1d3d08 --- /dev/null +++ b/app/src/main/res/layout/activity_accountsettings.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_center_accountsettings.xml b/app/src/main/res/layout/layout_center_accountsettings.xml new file mode 100644 index 0000000..d0e856e --- /dev/null +++ b/app/src/main/res/layout/layout_center_accountsettings.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/snippet_top_accountsettingtoolbar.xml b/app/src/main/res/layout/snippet_top_accountsettingtoolbar.xml new file mode 100644 index 0000000..2de8200 --- /dev/null +++ b/app/src/main/res/layout/snippet_top_accountsettingtoolbar.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/snippet_top_prolfilebar.xml b/app/src/main/res/layout/snippet_top_prolfilebar.xml index 75fe57d..7693d71 100644 --- a/app/src/main/res/layout/snippet_top_prolfilebar.xml +++ b/app/src/main/res/layout/snippet_top_prolfilebar.xml @@ -26,6 +26,15 @@ android:layout_marginStart="15dp" android:id="@+id/profileName"/> + + From 07da29439db27d2bb1a725567ce7805d1601564a Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 4 Jun 2017 13:30:42 -0700 Subject: [PATCH 017/122] part11 - Account Settings Navigation --- .../Profile/AccountSettingsActivity.java | 53 +++++++++++++++++++ .../Profile/ProfileActivity.java | 5 ++ app/src/main/res/values/strings.xml | 3 ++ 3 files changed, 61 insertions(+) diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java b/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java index f5fd21d..8f0b154 100644 --- a/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java @@ -1,9 +1,16 @@ package tabian.com.instagramclone.Profile; +import android.content.Context; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.util.Log; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.ListView; + +import java.util.ArrayList; import tabian.com.instagramclone.R; @@ -15,10 +22,56 @@ public class AccountSettingsActivity extends AppCompatActivity { private static final String TAG = "AccountSettingsActivity"; + private Context mContext; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_accountsettings); + mContext = AccountSettingsActivity.this; Log.d(TAG, "onCreate: started."); + + setupSettingsList(); + + //setup the backarrow for navigating back to "ProfileActivity" + ImageView backArrow = (ImageView) findViewById(R.id.backArrow); + backArrow.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "onClick: navigating back to 'ProfileActivity'"); + finish(); + } + }); + } + + private void setupSettingsList(){ + Log.d(TAG, "setupSettingsList: initializing 'Account Settings' list."); + ListView listView = (ListView) findViewById(R.id.lvAccountSettings); + + ArrayList options = new ArrayList<>(); + options.add(getString(R.string.edit_profile)); + options.add(getString(R.string.sign_out)); + + ArrayAdapter adapter = new ArrayAdapter(mContext, android.R.layout.simple_list_item_1, options); + listView.setAdapter(adapter); + + + } } + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java index 83b844b..19a42e8 100644 --- a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java @@ -11,6 +11,7 @@ import android.view.MenuItem; import android.view.View; import android.widget.ImageView; +import android.widget.ProgressBar; import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; @@ -27,11 +28,15 @@ public class ProfileActivity extends AppCompatActivity{ private Context mContext = ProfileActivity.this; + private ProgressBar mProgressBar; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_profile); Log.d(TAG, "onCreate: started."); + mProgressBar = (ProgressBar) findViewById(R.id.profileProgressBar); + mProgressBar.setVisibility(View.GONE); setupBottomNavigationView(); setupToolbar(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 82efcf8..f239204 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,6 @@ InstagramClone + + Edit Profile + Sign Out From b5b71da913bdd831c341dc825ab5cf9844559b1b Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 4 Jun 2017 13:57:32 -0700 Subject: [PATCH 018/122] part12 - Account Settings Fragments --- .../com/instagramclone/Home/HomeActivity.java | 2 +- .../Profile/AccountSettingsActivity.java | 38 ++++++- .../Profile/EditProfileFragment.java | 27 +++++ .../Profile/SignOutFragment.java | 27 +++++ .../Utils/SectionsPagerAdapter.java | 43 ++++++++ .../Utils/SectionsStatePagerAdapter.java | 102 ++++++++++++++++++ .../res/layout/activity_accountsettings.xml | 2 + .../main/res/layout/fragment_editprofile.xml | 7 ++ app/src/main/res/layout/fragment_signout.xml | 7 ++ app/src/main/res/values/strings.xml | 4 +- 10 files changed, 253 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/tabian/com/instagramclone/Profile/EditProfileFragment.java create mode 100644 app/src/main/java/tabian/com/instagramclone/Profile/SignOutFragment.java create mode 100644 app/src/main/java/tabian/com/instagramclone/Utils/SectionsPagerAdapter.java create mode 100644 app/src/main/java/tabian/com/instagramclone/Utils/SectionsStatePagerAdapter.java create mode 100644 app/src/main/res/layout/fragment_editprofile.xml create mode 100644 app/src/main/res/layout/fragment_signout.xml diff --git a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java index 69b4db7..2a9b4ca 100644 --- a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java @@ -8,12 +8,12 @@ import android.util.Log; import android.view.Menu; import android.view.MenuItem; -import android.widget.TableLayout; import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; import tabian.com.instagramclone.R; import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; +import tabian.com.instagramclone.Utils.SectionsPagerAdapter; public class HomeActivity extends AppCompatActivity { diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java b/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java index 8f0b154..e1e2d84 100644 --- a/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java @@ -3,16 +3,21 @@ import android.content.Context; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.ListView; +import android.widget.RelativeLayout; import java.util.ArrayList; import tabian.com.instagramclone.R; +import tabian.com.instagramclone.Utils.SectionsStatePagerAdapter; /** * Created by User on 6/4/2017. @@ -24,15 +29,23 @@ public class AccountSettingsActivity extends AppCompatActivity { private Context mContext; + private SectionsStatePagerAdapter pagerAdapter; + private ViewPager mViewPager; + private RelativeLayout mRelativeLayout; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_accountsettings); mContext = AccountSettingsActivity.this; Log.d(TAG, "onCreate: started."); + mViewPager = (ViewPager) findViewById(R.id.container); + mRelativeLayout = (RelativeLayout) findViewById(R.id.relLayout1); setupSettingsList(); + setupFragments(); + //setup the backarrow for navigating back to "ProfileActivity" ImageView backArrow = (ImageView) findViewById(R.id.backArrow); backArrow.setOnClickListener(new View.OnClickListener() { @@ -44,18 +57,37 @@ public void onClick(View v) { }); } + private void setupFragments(){ + pagerAdapter = new SectionsStatePagerAdapter(getSupportFragmentManager()); + pagerAdapter.addFragment(new EditProfileFragment(), getString(R.string.edit_profile_fragment)); //fragment 0 + pagerAdapter.addFragment(new SignOutFragment(), getString(R.string.sign_out_fragment)); //fragment 1 + } + + private void setViewPager(int fragmentNumber){ + mRelativeLayout.setVisibility(View.GONE); + Log.d(TAG, "setViewPager: navigating to fragment #: " + fragmentNumber); + mViewPager.setAdapter(pagerAdapter); + mViewPager.setCurrentItem(fragmentNumber); + } + private void setupSettingsList(){ Log.d(TAG, "setupSettingsList: initializing 'Account Settings' list."); ListView listView = (ListView) findViewById(R.id.lvAccountSettings); ArrayList options = new ArrayList<>(); - options.add(getString(R.string.edit_profile)); - options.add(getString(R.string.sign_out)); + options.add(getString(R.string.edit_profile_fragment)); //fragment 0 + options.add(getString(R.string.sign_out_fragment)); //fragement 1 ArrayAdapter adapter = new ArrayAdapter(mContext, android.R.layout.simple_list_item_1, options); listView.setAdapter(adapter); - + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Log.d(TAG, "onItemClick: navigating to fragment#: " + position); + setViewPager(position); + } + }); } } diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/EditProfileFragment.java b/app/src/main/java/tabian/com/instagramclone/Profile/EditProfileFragment.java new file mode 100644 index 0000000..1bb5750 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Profile/EditProfileFragment.java @@ -0,0 +1,27 @@ +package tabian.com.instagramclone.Profile; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import tabian.com.instagramclone.R; + +/** + * Created by User on 6/4/2017. + */ + +public class EditProfileFragment extends Fragment { + + private static final String TAG = "EditProfileFragment"; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_editprofile, container, false); + + return view; + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/SignOutFragment.java b/app/src/main/java/tabian/com/instagramclone/Profile/SignOutFragment.java new file mode 100644 index 0000000..7f21ad6 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Profile/SignOutFragment.java @@ -0,0 +1,27 @@ +package tabian.com.instagramclone.Profile; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import tabian.com.instagramclone.R; + +/** + * Created by User on 6/4/2017. + */ + +public class SignOutFragment extends Fragment { + + private static final String TAG = "SignOutFragment"; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_signout, container, false); + + return view; + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/SectionsPagerAdapter.java b/app/src/main/java/tabian/com/instagramclone/Utils/SectionsPagerAdapter.java new file mode 100644 index 0000000..e0ac8ed --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Utils/SectionsPagerAdapter.java @@ -0,0 +1,43 @@ +package tabian.com.instagramclone.Utils; + +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by User on 5/28/2017. + */ + +/** + * Class that stores fragments for tabs + */ +public class SectionsPagerAdapter extends FragmentPagerAdapter { + + private static final String TAG = "SectionsPagerAdapter"; + + private final List mFragmentList = new ArrayList<>(); + + + public SectionsPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + return mFragmentList.get(position); + } + + + @Override + public int getCount() { + return mFragmentList.size(); + } + + public void addFragment(Fragment fragment){ + mFragmentList.add(fragment); + } + +} diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/SectionsStatePagerAdapter.java b/app/src/main/java/tabian/com/instagramclone/Utils/SectionsStatePagerAdapter.java new file mode 100644 index 0000000..17afe28 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Utils/SectionsStatePagerAdapter.java @@ -0,0 +1,102 @@ +package tabian.com.instagramclone.Utils; + +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Created by User on 6/4/2017. + */ + +public class SectionsStatePagerAdapter extends FragmentStatePagerAdapter { + + private final List mFragmentList = new ArrayList<>(); + private final HashMap mFragments = new HashMap<>(); + private final HashMap mFragmentNumbers = new HashMap<>(); + private final HashMap mFragmentNames = new HashMap<>(); + + public SectionsStatePagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + return mFragmentList.get(position); + } + + @Override + public int getCount() { + return mFragmentList.size(); + } + + public void addFragment(Fragment fragment, String fragmentName){ + mFragmentList.add(fragment); + mFragments.put(fragment, mFragmentList.size()-1); + mFragmentNumbers.put(fragmentName, mFragmentList.size()-1); + mFragmentNames.put(mFragmentList.size()-1, fragmentName); + } + + /** + * returns the fragment with the name @param + * @param fragmentName + * @return + */ + public Integer getFragmentNumber(String fragmentName){ + if(mFragmentNumbers.containsKey(fragmentName)){ + return mFragmentNumbers.get(fragmentName); + }else{ + return null; + } + } + + + /** + * returns the fragment with the name @param + * @param fragment + * @return + */ + public Integer getFragmentNumber(Fragment fragment){ + if(mFragmentNumbers.containsKey(fragment)){ + return mFragmentNumbers.get(fragment); + }else{ + return null; + } + } + + /** + * returns the fragment with the name @param + * @param fragmentNumber + * @return + */ + public String getFragmentName(Integer fragmentNumber){ + if(mFragmentNames.containsKey(fragmentNumber)){ + return mFragmentNames.get(fragmentNumber); + }else{ + return null; + } + } +} + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_accountsettings.xml b/app/src/main/res/layout/activity_accountsettings.xml index b1d3d08..208709c 100644 --- a/app/src/main/res/layout/activity_accountsettings.xml +++ b/app/src/main/res/layout/activity_accountsettings.xml @@ -5,6 +5,8 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_signout.xml b/app/src/main/res/layout/fragment_signout.xml new file mode 100644 index 0000000..fb3d8a2 --- /dev/null +++ b/app/src/main/res/layout/fragment_signout.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f239204..4ed3fc2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ InstagramClone - Edit Profile - Sign Out + Edit Profile + Sign Out From b29cf20ac12e0d9cda259e3bf0e360ad82544f44 Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 4 Jun 2017 15:15:23 -0700 Subject: [PATCH 019/122] part13 - EditProfile Fragment Layout --- .../main/res/drawable-hdpi/ic_checkmark.png | Bin 0 -> 328 bytes .../main/res/drawable-hdpi/ic_description.png | Bin 0 -> 465 bytes .../res/drawable-hdpi/ic_display_name.png | Bin 0 -> 661 bytes app/src/main/res/drawable-hdpi/ic_email.png | Bin 0 -> 631 bytes app/src/main/res/drawable-hdpi/ic_phone.png | Bin 0 -> 406 bytes .../main/res/drawable-hdpi/ic_username.png | Bin 0 -> 450 bytes app/src/main/res/drawable-hdpi/ic_web.png | Bin 0 -> 356 bytes .../main/res/drawable-mdpi/ic_checkmark.png | Bin 0 -> 218 bytes .../main/res/drawable-mdpi/ic_description.png | Bin 0 -> 324 bytes .../res/drawable-mdpi/ic_display_name.png | Bin 0 -> 451 bytes app/src/main/res/drawable-mdpi/ic_email.png | Bin 0 -> 424 bytes app/src/main/res/drawable-mdpi/ic_phone.png | Bin 0 -> 278 bytes .../main/res/drawable-mdpi/ic_username.png | Bin 0 -> 312 bytes app/src/main/res/drawable-mdpi/ic_web.png | Bin 0 -> 241 bytes .../main/res/drawable-xhdpi/ic_checkmark.png | Bin 0 -> 321 bytes .../res/drawable-xhdpi/ic_description.png | Bin 0 -> 529 bytes .../res/drawable-xhdpi/ic_display_name.png | Bin 0 -> 831 bytes app/src/main/res/drawable-xhdpi/ic_email.png | Bin 0 -> 642 bytes app/src/main/res/drawable-xhdpi/ic_phone.png | Bin 0 -> 468 bytes .../main/res/drawable-xhdpi/ic_username.png | Bin 0 -> 523 bytes app/src/main/res/drawable-xhdpi/ic_web.png | Bin 0 -> 381 bytes .../main/res/drawable-xxhdpi/ic_checkmark.png | Bin 0 -> 525 bytes .../res/drawable-xxhdpi/ic_description.png | Bin 0 -> 878 bytes .../res/drawable-xxhdpi/ic_display_name.png | Bin 0 -> 1333 bytes app/src/main/res/drawable-xxhdpi/ic_email.png | Bin 0 -> 1203 bytes app/src/main/res/drawable-xxhdpi/ic_phone.png | Bin 0 -> 740 bytes .../main/res/drawable-xxhdpi/ic_username.png | Bin 0 -> 843 bytes app/src/main/res/drawable-xxhdpi/ic_web.png | Bin 0 -> 613 bytes .../main/res/layout/fragment_editprofile.xml | 32 ++- .../res/layout/snippet_center_editprofile.xml | 220 ++++++++++++++++++ .../layout/snippet_top_editprofiletoolbar.xml | 59 +++++ 31 files changed, 308 insertions(+), 3 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/ic_checkmark.png create mode 100644 app/src/main/res/drawable-hdpi/ic_description.png create mode 100644 app/src/main/res/drawable-hdpi/ic_display_name.png create mode 100644 app/src/main/res/drawable-hdpi/ic_email.png create mode 100644 app/src/main/res/drawable-hdpi/ic_phone.png create mode 100644 app/src/main/res/drawable-hdpi/ic_username.png create mode 100644 app/src/main/res/drawable-hdpi/ic_web.png create mode 100644 app/src/main/res/drawable-mdpi/ic_checkmark.png create mode 100644 app/src/main/res/drawable-mdpi/ic_description.png create mode 100644 app/src/main/res/drawable-mdpi/ic_display_name.png create mode 100644 app/src/main/res/drawable-mdpi/ic_email.png create mode 100644 app/src/main/res/drawable-mdpi/ic_phone.png create mode 100644 app/src/main/res/drawable-mdpi/ic_username.png create mode 100644 app/src/main/res/drawable-mdpi/ic_web.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_checkmark.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_description.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_display_name.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_email.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_phone.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_username.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_web.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_checkmark.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_description.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_display_name.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_email.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_phone.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_username.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_web.png create mode 100644 app/src/main/res/layout/snippet_center_editprofile.xml create mode 100644 app/src/main/res/layout/snippet_top_editprofiletoolbar.xml diff --git a/app/src/main/res/drawable-hdpi/ic_checkmark.png b/app/src/main/res/drawable-hdpi/ic_checkmark.png new file mode 100644 index 0000000000000000000000000000000000000000..8c2cdd9ad91f9a749e89df6c3e3bdc2efb0ea166 GIT binary patch literal 328 zcmV-O0k{5%P)?Nc#}4HyrepLXajAa4Ya8cogz6hWl zrAtT^Xxuh(1GnHSb<`gvemDs`Zktz$v`Gmk4<_=Py&bpBqr|$lM2${P7LI+v4|e^e ze$+`#z9zgSKdCP|*`-Yjo$S-5p-!~kHU^zYy=_c7k$4gtbfWPjHkF_mzEXm2cmMzZ aphND7F`>buACpJ`0000M9WwZ`%zPuv27YTC0G7=v^K&zi^MD$Smyw^>S^#uP02b&=v-$(T2Dfed$g-?` z9m4fu6@+#G$8q*_9hiU+fQFe(5V0O+pssZ(+eNEjU&0KFw0&~sOZXfO_Y1)xp$ z3kaQ(Fe(5;0^mlW|3n)B*cbqu1Au5FTtAEe=yDE76cT`;0CfFxSF>gufT<|}NV2pB zP)c2MGBdh`BnvV{tQQSHU?$eFoa(SUL8eGD?oy;kF}M5yMNwYv!haZf00000NkvXX Hu0mjff!W0c literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_display_name.png b/app/src/main/res/drawable-hdpi/ic_display_name.png new file mode 100644 index 0000000000000000000000000000000000000000..1467892853fc15f70008c2c8d966c36389d5a001 GIT binary patch literal 661 zcmV;G0&4w3*`?sD03G~6XnaQM` zLIw_E$lN(+?wy<4JE2f8+K)z~F+>a$Y0I*P^ZC4)%jK@|_l?MAvsal+W?OqP>2!Jq zWbZ(_`5z$ardTXaX-VER%@Gj1ZAab#y}@_26Tq<`GK>E&Mdx$PLZNV)OePnl$Yb&{NW4lcO!D6(?$|O6V;;|bByGJ&iNM6V%z};p z?!IHITrSVa3LxkS83FII3)+YE95$vYgyH1H7Q;#AP&U1SyY6M@ThSK*DiH{fJO{tT zKnXz1f1&Q#N9Kqj{Y?^h76%TQowODJf)5}bZD$k0*5Q#ST?Kr0BJYe+skFg&wG)7y z-E(Uj?;dFRTpECJgGI%c7d zR4TRVV)vt3rcv7q_xSRzbs~><9LS(7H-@>M8juGro7>2QFw;XH0vlaq)U_tnpgfS&7U_OjFTNF$$ z^<02`Kx=H5cx|4s=i{b@qf7u}nqeZi<6S+1Z^TZgY^6*97TNWyl?f45-vzXG+*A*E zcfof7KKGNugDxP{i$fgo6Uqd%Ywq&7pHSA^RnSpZ241oV3qY=4k-3>s4PLVFrby~Q vQ3O5V^{zmYI76z=o1);xJs80VhQ8wu;R^l5oe?I800000NkvXXu0mjfOR_5J literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_email.png b/app/src/main/res/drawable-hdpi/ic_email.png new file mode 100644 index 0000000000000000000000000000000000000000..4d8e8d3bc5c34370ca57801569b2eb20ba152ef9 GIT binary patch literal 631 zcmV--0*L*IP)x%%UvO`~`a=ARO)fNSziT?qygl*h)##>N(${R2s_#eiDt RcdP&a002ovPDHLkV1l@@AT|I1 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_phone.png b/app/src/main/res/drawable-hdpi/ic_phone.png new file mode 100644 index 0000000000000000000000000000000000000000..c69282fe6567f32f4aebfc6904704dba0698e182 GIT binary patch literal 406 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezr3(FvfbiIEGZ*dOP#9*AWK+*Xo*e zB1hvnQYQND`h1Ip_f^>e-@4QkBfe+MM~-WB)Mty9G|w(%dYN_bPE*n$oxH0n->o|v zn)S%=^rkljKAYSw^vzyodE)aP!(%!c^H+ABosq(ODO$v}@aU~YXRnvm`nk%lcre{X z$Y=Vpmoq&+*W3w7QN6myd)4MG;ivO2l&o7iyL{!=eN!wNQ#Basgzw3(tIc^g!~W&> z!|74J%l}{5_I96ngGN_hu44FuzW<+RuKDR)KUwAEL=+6=j{f$ z$j7n=ZaKVWIJ@2@C#-Lij{XZpJFdL>rn6sq8C6()vnu`acU$)BH(r-2Qn|ykYn9D@ m<{q4#w8r}8_rLRI71b~=sL|bMcz*&n$W@-MelF{r5}E){=dViu literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_username.png b/app/src/main/res/drawable-hdpi/ic_username.png new file mode 100644 index 0000000000000000000000000000000000000000..92838b0bb79b919776fae0ee09ae446a835b770a GIT binary patch literal 450 zcmV;z0X_bSP)(qPs9%pq$0R;Cqg!^d{n9n{af#W83;pdI+OF8a z?c6(aX6~zX90r5IU@#aA#-GI~ilR*&!e*XBU4JwDH^cY+!#Iw|VHm!V(Nu@9Ns{C` z2!aFEuj{(owB}XUXN}K|B53nt9D)RVn~*ko!9}P7=(|q?pHt8Cww#71zA-(#BwoU* zfTAciy10Ew__8X%bc0#6T5?#xe-MBeZp+3J+P8q-`+yArOI3x);XBp(1ddlhz=Klb zzi3>DMf1xw1Wd#p+C=!Z5Xl=DrWt49DgTmyzz9vo6{XEb2ei;PM)O;9B0Ad`mt?PsAE(R0O^)QEo9b%lm z?NGqjx&Vs#Q&H-SN9iofj;sq1uW%w>VuD20A#6}?)x%2x5T@%>62I~m5+G5Q<+^U2 suBvKn-k$`$_5lWi!C){L4905V2aws+5hgpmlK=n!07*qoM6N<$f;9-r(f|Me literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_web.png b/app/src/main/res/drawable-hdpi/ic_web.png new file mode 100644 index 0000000000000000000000000000000000000000..5be198303699395853d7b96e5c3318b3fc6957b2 GIT binary patch literal 356 zcmV-q0h|7bP)2R?2)31PeA!05_e2K#u%j z3jxUdMmO`1@O^*%(R>s|eJ0fvfV>^p<68jBvPQh`GzLi7BLDyZfPVofO!z`&<~Iyu zOye#900000&|(0p!6yL&&O0001hW&y%59O&3qd~Pp(Y;3V;&|X&nZa5b%tx{@50~6iM^UmPLbE*AFtFX*h zB9W?vD%4B~dD)dV|Jv-8sDr9R9LGJ}GeHmpiRlh(JP?;+kYkJh0000n%D7xsdm3WnuebH2fN8a3nS+U7qQ&< zq<$znbJl|b%O<^PkIPx+>KuRC!Fcj{gp8y8>5Udm|E4KhCmqm{2fFA669ZSoDPxA# S>A^t9GI+ZBxvX0r6B^7D0X7ZEkKZ4vYy2AiD>jS|FYRRFkQ#t<6Kw0YG156EF;hbC5zM zj~G25M-UUl(}*-|8ql%sK(;54J)KBLPa)_4A`K!N4^0OE6Iz%li2xWq;Z$<~FpiB# z%}vmPYM3}+G!X)$pd3i2lY)VIDn=6_HPb*D&=D!5U|=~=Hku3Qng(#i`S5T65Ql&q zfe(W!tl^sm=;{Dsn`Go*P(zm(2jtSw0a*kc0BmaWfgC~2kbpK|vq4RMhEXsI&;S5U WHe%zLefEF=0000b2ROjj?NKA5Ck_Q*L4HB)=FjH_ZL0Sdq&~!N#S}wNs@&&04}S= zO9AXcx`1IAt0?jajp_;&D}IZjXcJFj3-bZ%UTBDW9!%3*;R0Y4Jx;PxPZPV+7l|PV zku4qzCL06x6!SC8KLw$OTmZpDQ|oU4(3V5DcmyYf?x3%>0O&;TSL5P1KA``U1JJ=^ z#GWe$a2#j7E;bCq4dno7n$EM@v~mE;vbO7D@lo1Q4nU`$5qsatYlwq*g}%O2#^}1f zjMZPa-H1N08yN~`H2*)H5UYN{ZTV6uMR-=SgpA+ z0GSO++SJ$})* tHWvU^dyODO&1nMz+at@b&Bkn0#t#6dIkCM9-QNHJ002ovPDHLkV1n}=z!3ld literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_email.png b/app/src/main/res/drawable-mdpi/ic_email.png new file mode 100644 index 0000000000000000000000000000000000000000..2bc5b2a60a6131dc592146003dd467dec4de94e3 GIT binary patch literal 424 zcmV;Z0ayNsP)F|0c!|6#{Ii(Vv2<;;_t$Y1ps@(>oKhEG=OhB3B1Adz4`9>MS zO{$oK=8(Mq#|r&VfCzrUJKfd9??KS3A&0$y-%YA(GAjWfh%EN`MAu|i0^~tawL1Y$ zKs^Ou8y>An0R8+-37}(?PPr9SKi2+|@wXqKORUBnuJ_CIlJi1-;+;9Gh5Z2K!Tbswo$jBXt6OE0HQ;5M(wQhQPdfXIQZfa^O3pA+5#KdGKIT)z78|VlbvMg_C zXkY>w&`hr7NRDU(nMJY#fEtx4wH$^mEG!gAc7UOwp$W_YQ!)XPBMixjf4BkUrXi$g zFdB8hr~^hFFzSF&2aGyk)B&Ro7}^e?Lc??jIsmy*ip9WkAf1kkfnpVS96@@c6koF( zn~(5?n3u!15kY_l~0ep}M*{FVHYAP^S|;-f>~5T2GMP cLErlZ0IHa4#gEn^Y5)KL07*qoM6N<$f^8~q$^ZZW literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_username.png b/app/src/main/res/drawable-mdpi/ic_username.png new file mode 100644 index 0000000000000000000000000000000000000000..9baa5b573a74a220f6458beb2c97d0f90aff5a3b GIT binary patch literal 312 zcmV-80muG{P)l12lLh z3D^s!-xLUl)d#f42*Uvu78aT$S`IR(hiVQW#Q^{P|X1#pr@zD z4OHL{G&l`Nr{lrNKs6RXEsV&O5dl4L40Nl~Xw^RoM!_f;Gynh)A4k_MV#=fd0000< KMNUMnLSTYJ9&D`u literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_web.png b/app/src/main/res/drawable-mdpi/ic_web.png new file mode 100644 index 0000000000000000000000000000000000000000..22516484d797f3cfbbf34741ff59acebb7473152 GIT binary patch literal 241 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ9iA?ZAr-fh6C_v{Cm1j$CnxJE zD=W(@%yr`CF}i)}(j?*4PkDKHeH>g()zs9CGdmmmRxsUceaNt2iPc)&_C#Z2W7C|2 z`7ZkG4R54M4?HMi2xE0&iuvW+m~e%0G2ek~yA2&CZeA->pG^CnV$I;|XgR@8T{!qC z$eptU`hmgI)z4*}Q$iB}DM?a+ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_checkmark.png b/app/src/main/res/drawable-xhdpi/ic_checkmark.png new file mode 100644 index 0000000000000000000000000000000000000000..15d5d7a1275b710ee1a7d02027674507ae396292 GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEVC3+0aSW-r^>&6KUz34|L+5NM zhg|n_4<4Ate6iS7$rvu2pM2*^G{fGuCeAjAkSToI{_kBP?R?)m^D-MF&=eqO_#M+c zFXFq#<tqg)m|mp_VBKAGq) z2Pf{G%J!bIveYtg;-|oM=HET13U8G-sQWW3qU*sCdwJ=tSv3VOBo5Bx%}@BUCW6s@ zw&0xGZ*$!^dZR2VuiWe~Fv^OosW1CB=e^Lu%Ab0IdnW!@Z7TnC-{nKtzEYO?PorHY z6s^vdKKNSu?Q)KL_n+T)6;S-I)ui$BIfv5I*Mdh*F@yc^$Jkt8+svEuExt*C_@1tQ JF6*2UngGT^i2eWo literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_description.png b/app/src/main/res/drawable-xhdpi/ic_description.png new file mode 100644 index 0000000000000000000000000000000000000000..5517829c4a921c588c9e28f7e12e67751c609561 GIT binary patch literal 529 zcmV+s0`C2ZP)}%b=@IeXKCTHKCYk0 zcbaN`8+w^Ho}p*cG&h=NejR#S!2FNoghWxa)|mSprh1E-PwBo9bpgMonZtZ?5)QO6 z;yBI@Hq?>h2~G2wij7U7wqY16=m4vDe_mw0xQI@m0dx^}6?K7@6=30U(M_fRTxR6B zR<%C#2{}s4qfhUuG%pgM^LcFBK317SASgKrFn^_ZW1`cHTG3XWM{Wld07fNjY$P=$ z$$`GVhwC3D@124uCu_ zRQT_*O8^8w00h7`NB{&t00f}Xqi`>%D3I@oZIA#6fBd6JX??-ql>U@#aA#xL;=Oy^Qf T`)2Us00000NkvXXu0mjfRj$|C literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_display_name.png b/app/src/main/res/drawable-xhdpi/ic_display_name.png new file mode 100644 index 0000000000000000000000000000000000000000..83a5e61a56203ec966ffbddac17d3d22467cbf74 GIT binary patch literal 831 zcmV-F1Hk-=P)U$tI2DA#b8ksY1jjYsJ<=(YCZG_|T?`TG6Pe>E+-0 zeX@ZNLbKhO&Fqfnz{f6oJ9EB0bLPyMNhCx>Ovn+}buVSJ*)&lum&bX{daDbC!cehT zyr0kKzu>sv3EcaP>v#E#t;SCPAG!_ifkq~i8MDp!i@;YO#{UC7q*|?>x2C_ts5gF% z@4%`RaRGlb6TtYkC)|#VA&%o*MuX<)p1@vEqddd*faz2!bs8hU8Js^<`JNX_Z z!-#u5V#Ty>J?suT2xx}TuqI4j`{`pX z0MBh%MF0ySFl@xHPEL~W&L=AfV1Gx}cRfG`deasUc&SiJSh9ftM?rTf_5@&>drqa6 z7<&R5jmFWSx|7M|aO?@dUp%Sc0cT@Rfa|(9g6c+cbjt=0m{IV6x(#{2_aNOMolc*^ zdq1tn1X)f$>|zSunYV2&@W{_f4@V8ejmNgm23Z4~=(G5;Vs$;hTftfLmdU3Gp5w2t z^PW_Mga9F6-}V@=!vcvH2bK`{Ug7*L&OfTII!84V{D$Lm9IIStt=H?v4%$P6V0aDB z*FeSslc-n{z``c}>{I6QD!V+G6X1K39)YdM6F|e6`!kKzy+MO@1(5pWutW@u05ojf zPt{k`ZnKR@5x_kJ2led`NEiYZBS8S%{@oyrZ%eIKJMPC52H^pdrZ#S|;A)%z1iTZb z2;gFiaRN+l-xC6a0K)_zbNklp+yj7#>6r!Gkyzz3K4aum9E;NF``f znh>zs7qwOVc2_xzCvgf5f(GC5Apc{pc}a0GNg! zVQ6l|^-v0vj5Rs(ThQJnxyKiQsRaNNXR;&zFgdFLuqLU>D_fnPS;%~`vo9u>BvP8WI;Rlw8=2{S3ibtVPC=?2X cLj5a!0+S8cUWXk7*gvdY zB>gz0q0I!v;2=YU|JMJoft0y%j%QMO^J`)Akb_J+aa=S1eS|Cdeq)U@^I zB8@hazxv?}84~i(3R9RD#76GE^hfLL>?YxaH&P6DS+CDwn7p6$g7U{RGkF=d=P>xP z7UUn|Wv&2vlQht9k0D1LtYrhE#!@xif2XZ4|L6JjchAwU?=2XQ)%vYCE9+)@w_sm$ z@^uCc)#q{>ynnvEAot;A(e>cf)5=l+*vv?^=9I%W$J7$M#@E@I3F)_x+AWdxPHtxG$yjd!@P04t!n=I(ZNFrF$S<)-qNAA;cUS zyk|K1$Xp`@z&tH_8|j_w%w~Y z?Us9%tKBqBFW1Ze^P}@0lsF#oUzpAFEcWB0FZbVZhe)iraK*{DM(#(R+1cMFoEv=w zfQB(J+)?qIwC+kkw(RZz*Ldr4_Vb(GIBR~LyX@u3qe6nOE&A?jx9a=++a>jHeoM2> zkrQPnwm*3^_w~c`s!ZF|CZD}5|5NB+%%qpAw=fu*eGE8oB#rA#jc|gIA_F6b0|S#l zLqitR8mSc%wZ2ckuP4yJz@h+^2$;^W^vb5r@;|*C6E+l2|Ng18r-7A8Z}|Z)^8<%D zDz>=_Kn(zDd0@$UVq5vE+wFqIFBWfMxY^WiYolnSrK`YmI9$@Gx}W9EB8{x*v$mi8 zecH}mY|d|bw&H&JRn`mz-W(ae|C66r{=e7y!&T~)r{-G@*ZBKB_nAQ+Z&>|@QN!g* T`FYhz(ICF3tDnm{r-UW|$19!N literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_checkmark.png b/app/src/main/res/drawable-xxhdpi/ic_checkmark.png new file mode 100644 index 0000000000000000000000000000000000000000..19ba9c865805a1f7ff923bf331012afd6b5cd18b GIT binary patch literal 525 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>V7%h#;uunK>+KC+uOkK$4G({9 zo@17L>E_Ole2)$>S8$qlDRfBZKdcjDJ-FFI@9N7ifjg0xKZ+#>t?r1>yzxx>#cwCR z3;HL6Z)qr@gH^L^{M=5xYR-^cYs}mDQ2mYYn|1E4F0YWHve&E?VhNmJLRKm z&!ilhTVwy{=XJI#vjgt3Sa2QkySL$ihJ>~6>EbO0?mjv!*1XaSylPKfIkfR}?b)k` z=Is1_fNe7ONk7{^H(m+H9SV9=GpDAF-+F`d24-s(6pBZ_EP)+_e);cRvU}s)m|v^; ztrer)vON>OJ-T$}mG=Cf!5r3&tJ>>7KUQ3>Xr8#?%?|B7>%EF^e^?O7(Z_c7oc!VQ z&IKkBWmjh3`q?^n*;Q`$!~aec@f&S=w&&^L@^gankzdt%ylW@!nbmIQ{Gw~|7tP+E zCw}FK<%Z3^@K5bew{rcb$3gKQ^W7U3FS&8;)UxY;ZVNs*kstB;A^*4ge*Q8C`xM+a zD4!5~!%@Uy-2~(s0J-M{->hK((r17)RJx;(#d;A`^)bOW9YEESfZPvi1~n)lzvx^Q ZdrZpv)aQ&Q^MTRK;OXk;vd$@?2>?6n>p1`b literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_description.png b/app/src/main/res/drawable-xxhdpi/ic_description.png new file mode 100644 index 0000000000000000000000000000000000000000..873ea771053e5d34cb613d5643da2df0326bb8f0 GIT binary patch literal 878 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>U^ex1aSW-r^>%J{wy>i}+hcb9 zE5CU^wkb4ntlpWQq>}K5eW`-tf;yoib)PneO<`m8^j#g6^MCF06E4$DIy1|v%Wl}{ z%LsA2J+tThyPKAqXZz^23piyk%AS7yS-n}oV&VIZhYx&kTU@v^Y_;vg3f+y7Ys2})u)hh4~C+|*uZ_ow=I4__!=$=a&-@~A1} zXZQ3&&(k(n@})obw>>|}$e!t;=DBmztJa+{z8%SMU|I~nUP|6HCHL34p5oa?2YBZ) zdA(81z1OnxS-aQLpzAMJE)&b#y>e@VIbS-<^mMNhT6<8iift;15|*twZ9Uk@CA zv{=gip1kd@rX<%FV2j18 zNdBUbr{_*Ro+PwxS%F*MuWf0M_VIl3oAXFxHG_%l%ot&l_sb0(%umEeEjY^%;IGW; z`fGcZq3<1^?1sgX0UIN1Y%>q~{krDAIp50Ks)!-#)^Zz<)(>HeUMySiJXI@Z+V$^p zU$Qe86YjSctW1k8UhiKUCB?806xC30;L6c0vfJ;yk9}d}cE{^hHbYgg%cEUl0d{R6 zH?}`or}~pGL4f6;Wc+(Q&6XYIk73$Cw1cXTDi4xCLw$ew>*?=mdQ{}rKd*D>(U|IG zzEj=-NsW;uZ)v=8)JH>>16z0W@2-yT*cp}ZATuX*mq4;66OvI3-T|EIfj5zb6okJs zmz<4NjA*fAO8#4Hc8A}iqISO53@-_Uz5|~Pe%?IQ@~!lwR>MNp2D>!>wO`D2f&%zA z2mj&xZNT&1%h}%G&x3iXyXJNuRa%_)-~-cTewn{_=UkPWHrMa@6q6rpkN?a4eVrE` zZmr2;D?H6ocIRA|s%OvKFHejUzVmMBU)7n5-tBr@ynEMN@4mIgf=(QYEdn6o!kk~c XTc_}bUQSqO3v!RAtDnm{r-UW|cz||g literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_display_name.png b/app/src/main/res/drawable-xxhdpi/ic_display_name.png new file mode 100644 index 0000000000000000000000000000000000000000..973c2d0e6af12b6043ac9a9dda7b64a2f6e94cc5 GIT binary patch literal 1333 zcmV-51B1j>YXkJZviAIem2qIWoV+~b7u|6t@{^AclV`HmgZELOC{ zp^L&#gr~FF>=&^5{3xH#UnrGI`w5806pzPu=W@9_!VAKy8?gW}FW0Jo(o4;G@YIVk zGos9Ic8Xui@;_hYdWtG^K`<$z$fZt|-vq+TZ34{tY+n(v^YscGh0KlBg2m2!DrO4BIOw7fo z4DbzHK;adymDj@6e4oi=a&S*!TIAjqVgUp9T~TiCYq{Tu$k6Yb<`IF4FyrtvbPs$D z*P!^d^5E%~?`BNOB4b}v58qbf%9oo?8CLw?Cs6L2{hwU&eZj;V*aC3INQJkvRc&-;V*RLHh#f3w9z~-A~!z9cc#up}o(81PHH$lgb6%E3R-_u5SY%*SrY;R)fIG z)GWaE21%x_0U)SM00;m9AOHk_01yBIV1$>05SMfX0Lt&5k?RD4Fs!>^T?lzVsZ{C+ zf-(92F18>2T#kq&04f3N95UhTyhT0O(WlEHc~B3PAooD;&2h z>oBsSk#Ge!6q`5_tQ{>B3WM@}S=`cFa(yBH_t~SaTV0hE0k`s@D6WJ}bho*oXssZ8 z35mKU+8Bfq0CYvfk^{ONB9hf5JHX5fA@5X2Q>ah@pn|Ds(Z^-g&&_1B)gG8Ik>Q$` zz3D;&0E#Ejl2S(sqJy_$ugG-Ot2ZLh0LWl}p^V7O%x8~*cF{7iBUmdXe+5 zbB+)IuDB`u3nTzoEJI32EF^@9+9?Qu13*o-rC7)auB#Js6hr`?8}BOU0jaK#FGCLi zcCun2B^7yx8-P|lKEpz)i*L9Ah=uqx3uI(O0f0~w0U!VbfB+Bx=K`tv+|Y91+E#YD z!-Ug}!pwnd+!}!Pz=35PVqwArRjF(rTiECG`4d>(q{7#qS%%|WjBMv&Q-w-j_wF-rK7OW76iNr-E5B3Ng`F_%5OGDm=o0LrFGLuP(Ehl;rQHf7kZF2bzeH78&?d|P7DmtoLZ->GMA-{3MHOl`29sNRk zCzs1@2~_!AU0qwD_%SNknur%YJw5G#5rB&hgMd{k*G@!Nkb8kBzrVl#5ExyiV%1i# z44-fyh~7U$g?hGxL0`%jX96Y*RHkPu_?XYrh{5}gA z-@pVElgZ>6C)$k~0skB~{<~f4!D86!=OH&rrP8K~DSGq>aI8V{A`(60n3WhSenp~M ziG`}fNRcI=4Cyf-B8y{ZVyOIY7l6uMA1eYJBoc`Zaa=KpsF(1Zc}X=}WC_A2pu4+! zmu)IroHT}|VifaA@=Ovqxt;8Kz_EM7o`%Z!{!AW35nXS?%ifIAlvSpd7;Uae)>jdv z?!$YG*6K`kC%`2Oc#w;l)gcT^2gON;X${hWaR29MI~6)<$MKgTix$^!7y-_V;SHSb z30o63Q`U@GRcd&e0QXHP7EfAXC8t2xd)rRaPy#Afg*4`jbN1lnMjA0?#XbI@eW37N zPEKq{J8XtRfIC-`$z;xJ)<|*AX|vY6S|=x47#J8hsaXTZd1wO{a9t_1h{(NG?aQtX$?nk-fKVBV3r2QM47htHNoRm zLz-XWqd|Zp80X&^Cv80h7$-gDWe5}}t02AA41t9JEiYOGn1@=Fr8=8Pvm)ZON_V@{ z#fssk1D)f(Id^SC6W|&iKBGOSu?CBDcTp3`nyFi^ai*xg;8U0=%TVHR)m!pkE-bmF`xji%Ecwk09KMHLvMn65z8mP#mnEbTJ7C zpawt6bw|DlSg-7YLIOwtg#?fQ3JD+q6cRuJC?tRcP)Gm?ppXC(Kp_DnfCP{L5$6QsnlaC)3Xfwt}K?4?l^Bb6K2T_bayzA@@`nc z2sdukRd>rbXF-+MmrMWT;|VI)y7#}*e3NVixgak5h`Z=o?KM=lE$zz{$cBgsvwiz~ zlZ%vYmSq14%|<1GkRhKDNwC(;Vm_s6n9>P?AP9mW2!bF8f*=TjAPB+({sLtpSBuJ4 Rsk;CG002ovPDHLkV1hLW9clmo literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_phone.png b/app/src/main/res/drawable-xxhdpi/ic_phone.png new file mode 100644 index 0000000000000000000000000000000000000000..22bcfc699b94b8da2639c333c7bb3c71b30d4dff GIT binary patch literal 740 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>U|Q|z;uunK>+RiGZ)r!7V;@7a z9JMbkTI*r&gKT3XKzI;URAUC=APvz*J^%Wef8D)3Bk#K7Pfv|6Sw}nOJL2~inFVC ziB~<;Z~U=r^};7rrvpFE&rou|*L8ntd*wX+op&aM{5YfbV8@T;E8o6wnBN~G8vpzG z9=3h2_x^~z9r*msvo~p9_jfJ*@qFdmFFU&*-S!eZ;F-fvreFLqWy$Pomv404FSW0D z^KipgyD$dpHLS6Jofa0{_S>#=YS1}d7iF%Nz3Q6(t^2qB zOGq+gKUmOMC;6adzn1u~x6A=rQ{|$v4>88ECYl#WlyFbpA6xkUK^M>N*3KlK=06hJ z4W*5||7^S1b_!`b%zJ+NAoG&UD*J10c~6UeuA9ESGe3#>!mIj+PjlDhI&&M&Wq&jA z+PXJKf-^3ZKHuA-U&W<;`AGDZ+iwfk&I(nOslNApt!C+?oyYg&#dOP6os19q^ZwTN z&nj&fIDa;tV_!cv$8+1$JtbEU{M^-UvfFb0Tw%ML8}H5g{JZwN@qsrPg*mT2H|LsP vU>5RpaSW-r^>+5jZed4}cHzQ1 z$DTfLbq#ED;G4*Eb8_>I3K5sNj(6B>Rw#7HiP&Vg9a31-ce>~Culv8MgC+_Xy*yH~ zOMCA7X7}e8u7M76<1xUW1wkuyPVo8O6jRGc+IBTdwr624^VwJ1%v>Zt z=WL9yiCr5O9_qL|MsNT1(&AI!{J!qJ^mW#oCl-89KmSzL+AQcSUB0>WXtv>|?RS~h zFL?jrmo;aw^tRCdUdu1vH1?V;-Fqx>>hDPj)#lu-haPq|%d;G0w0)Bq)W=isW}?h( zb91ICUQ45^KG*$JYS`*pX1m7PtCfN4pQi1L<@yKT7v`P*tG*}ef#aE?lfpkd=dTJ`AwShgB|S)>vxMxcm0@SKCxu4RYp_N zOEsA)!Gw;}hOs(u-IL!LuhV5duFZG*@4n1Qp)^1?>eD&9> z%7brf@OL_LNq3xlcl-+k%hG_p&Pm6xn-oM!G z!*E#U8uR-T`_z9tdw-*Fr2@ydbBCs7En)hy=Aw?J;;xr+^Oxm>9dB!@4?bu=Tk`Xa zRclWiyKt;AO`CP1Y_P0K+uFbW)xLLM%}DUA-S(XsBaH$Djy>j23%T;6?pN($khG_( KpUXO@geCx(LW1@H literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_web.png b/app/src/main/res/drawable-xxhdpi/ic_web.png new file mode 100644 index 0000000000000000000000000000000000000000..8fd9da5775638f735979950d69d24394ce64e39f GIT binary patch literal 613 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>VAAn)aSW-r^>)r#ufq-^ZqZx1 z>~{#)2e7>3ny6ebF?3UXzwZHl_G{cGF_zl$YCnZ8AQF`G1v zpIXmUyD&3a186D?{K;Q+HOn*0?s=$G`ZL$#g=Se>qoURJeX@BUx9;zp>vNwJYF>}M zUV7bh@sW3BoO@KiY6;f`-S;-Cn)upp^UXQir0RCY%$xeapVM+v$7HXiM#;VnJhucH zxb{6YTS`w#>6K@{7dtWW!@ze`lqWkQ8j-*UC=nX&UD!>wa zj7h5Z*c_fK%07=@Wwsq-dg8fn#rs_>nR}Ri%~E6%XkcJbU|{5MU_dY(#8{5ZOJKV3 z=ik2f`X?>UqevpD12G$xu-d#5dt);9<*6wQwjB$EE|o0P4rTf`OX26Ojah&jykMZ;F z-mrDCJ#Vc9^vIEaXV+YRJv-^sTm$#~Xw92zqbdtdYFR8Re4Wu7t@@`nJD=~Dg5cuk zEz&>V*>t!)B{db;|#taD0e0stR*^sN8@ literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/fragment_editprofile.xml b/app/src/main/res/layout/fragment_editprofile.xml index fb3d8a2..3fc9aeb 100644 --- a/app/src/main/res/layout/fragment_editprofile.xml +++ b/app/src/main/res/layout/fragment_editprofile.xml @@ -1,7 +1,33 @@ - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/snippet_center_editprofile.xml b/app/src/main/res/layout/snippet_center_editprofile.xml new file mode 100644 index 0000000..0bdbfe4 --- /dev/null +++ b/app/src/main/res/layout/snippet_center_editprofile.xml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/snippet_top_editprofiletoolbar.xml b/app/src/main/res/layout/snippet_top_editprofiletoolbar.xml new file mode 100644 index 0000000..0d9fbfc --- /dev/null +++ b/app/src/main/res/layout/snippet_top_editprofiletoolbar.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From d4545f9e3fad183a0b0d6890103d261280666065 Mon Sep 17 00:00:00 2001 From: Mitch Tabian Date: Sun, 4 Jun 2017 15:27:21 -0700 Subject: [PATCH 020/122] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index d94fa82..01559dd 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,19 @@ things simple and condensed I will just use Firebase for everything. After all t
  • SectionsPagerAdapter (Home Screen Tabs)
  • +
  • Profile Toolbar and Menu
  • + +
  • Building the Profile Part 1
  • + +
  • Building the Profile Part 2
  • + +
  • Account Settings Layout
  • + +
  • Account Settings Navigation
  • + +
  • Account Settings Fragments
  • + +
  • EditProfile Fragment Layout
  • From 06fbce53308bebfdc215a0d997499cf405443b1b Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 4 Jun 2017 16:51:58 -0700 Subject: [PATCH 021/122] part14 - Universal Image Loader Config --- app/build.gradle | 3 + app/src/main/AndroidManifest.xml | 2 + .../Profile/EditProfileFragment.java | 24 +++++ .../Utils/UniversalImageLoader.java | 93 +++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 app/src/main/java/tabian/com/instagramclone/Utils/UniversalImageLoader.java diff --git a/app/build.gradle b/app/build.gradle index 8bafcd1..4095602 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -37,4 +37,7 @@ dependencies { //Circle ImageView compile 'de.hdodenhof:circleimageview:2.1.0' + //Universal image loader + compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' + } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b7613a9..b088e10 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + Date: Sun, 4 Jun 2017 17:18:01 -0700 Subject: [PATCH 022/122] part15 - Testing Images in The User Profile --- .../com/instagramclone/Home/HomeActivity.java | 9 ++ .../Profile/AccountSettingsActivity.java | 22 +++- .../Profile/EditProfileFragment.java | 18 ++- .../Profile/ProfileActivity.java | 50 ++++++- .../Utils/GridImageAdapter.java | 123 ++++++++++++++++++ .../main/res/layout/layout_center_profile.xml | 2 +- .../main/res/layout/layout_grid_imageview.xml | 18 +++ 7 files changed, 231 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/tabian/com/instagramclone/Utils/GridImageAdapter.java create mode 100644 app/src/main/res/layout/layout_grid_imageview.xml diff --git a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java index 2a9b4ca..96b2d1d 100644 --- a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java @@ -10,10 +10,12 @@ import android.view.MenuItem; import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; +import com.nostra13.universalimageloader.core.ImageLoader; import tabian.com.instagramclone.R; import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; import tabian.com.instagramclone.Utils.SectionsPagerAdapter; +import tabian.com.instagramclone.Utils.UniversalImageLoader; public class HomeActivity extends AppCompatActivity { @@ -28,8 +30,15 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_home); Log.d(TAG, "onCreate: starting."); + initImageLoader(); setupBottomNavigationView(); setupViewPager(); + + } + + private void initImageLoader(){ + UniversalImageLoader universalImageLoader = new UniversalImageLoader(mContext); + ImageLoader.getInstance().init(universalImageLoader.getConfig()); } /** diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java b/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java index e1e2d84..69a919b 100644 --- a/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Profile/AccountSettingsActivity.java @@ -7,6 +7,8 @@ import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; @@ -14,9 +16,12 @@ import android.widget.ListView; import android.widget.RelativeLayout; +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + import java.util.ArrayList; import tabian.com.instagramclone.R; +import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; import tabian.com.instagramclone.Utils.SectionsStatePagerAdapter; /** @@ -26,6 +31,7 @@ public class AccountSettingsActivity extends AppCompatActivity { private static final String TAG = "AccountSettingsActivity"; + private static final int ACTIVITY_NUM = 4; private Context mContext; @@ -43,7 +49,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { mRelativeLayout = (RelativeLayout) findViewById(R.id.relLayout1); setupSettingsList(); - + setupBottomNavigationView(); setupFragments(); //setup the backarrow for navigating back to "ProfileActivity" @@ -90,6 +96,20 @@ public void onItemClick(AdapterView parent, View view, int position, long id) }); } + + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } } diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/EditProfileFragment.java b/app/src/main/java/tabian/com/instagramclone/Profile/EditProfileFragment.java index 91ccb06..b1859ef 100644 --- a/app/src/main/java/tabian/com/instagramclone/Profile/EditProfileFragment.java +++ b/app/src/main/java/tabian/com/instagramclone/Profile/EditProfileFragment.java @@ -31,21 +31,25 @@ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, View view = inflater.inflate(R.layout.fragment_editprofile, container, false); mProfilePhoto = (ImageView) view.findViewById(R.id.profile_photo); - initImageLoader(); - setProfileImage(); + //back arrow for navigating back to "ProfileActivity" + ImageView backArrow = (ImageView) view.findViewById(R.id.backArrow); + backArrow.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "onClick: navigating back to ProfileActivity"); + getActivity().finish(); + } + }); + return view; } - private void initImageLoader(){ - UniversalImageLoader universalImageLoader = new UniversalImageLoader(getActivity()); - ImageLoader.getInstance().init(universalImageLoader.getConfig()); - } private void setProfileImage(){ Log.d(TAG, "setProfileImage: setting profile image."); - String imgURL = "www.androidcentral.com/sites/androidcentral.com/files/styles/xlarge/public/article_images/2016/08/ac-lloyd.jpg?itok=bb72IeLf"; + String imgURL = "www.androidcentral.com/sites/androidcentral.com/files/styles/xlarge/public/article_images/2016/08/ac-lloyd.jpg?itok=bb72IeLf"; UniversalImageLoader.setImage(imgURL, mProfilePhoto, null, "https://"); } } diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java index 19a42e8..23daf8f 100644 --- a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java @@ -10,13 +10,18 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.widget.GridView; import android.widget.ImageView; import android.widget.ProgressBar; import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; +import java.util.ArrayList; + import tabian.com.instagramclone.R; import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; +import tabian.com.instagramclone.Utils.GridImageAdapter; +import tabian.com.instagramclone.Utils.UniversalImageLoader; /** * Created by User on 5/28/2017. @@ -29,17 +34,58 @@ public class ProfileActivity extends AppCompatActivity{ private Context mContext = ProfileActivity.this; private ProgressBar mProgressBar; + private ImageView profilePhoto; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_profile); Log.d(TAG, "onCreate: started."); - mProgressBar = (ProgressBar) findViewById(R.id.profileProgressBar); - mProgressBar.setVisibility(View.GONE); + setupBottomNavigationView(); setupToolbar(); + setupActivityWidgets(); + setProfileImage(); + + tempGridSetup(); + } + + private void tempGridSetup(){ + ArrayList imgURLs = new ArrayList<>(); + imgURLs.add("https://pbs.twimg.com/profile_images/616076655547682816/6gMRtQyY.jpg"); + imgURLs.add("https://i.redd.it/9bf67ygj710z.jpg"); + imgURLs.add("https://c1.staticflickr.com/5/4276/34102458063_7be616b993_o.jpg"); + imgURLs.add("http://i.imgur.com/EwZRpvQ.jpg"); + imgURLs.add("http://i.imgur.com/JTb2pXP.jpg"); + imgURLs.add("https://i.redd.it/59kjlxxf720z.jpg"); + imgURLs.add("https://i.redd.it/pwduhknig00z.jpg"); + imgURLs.add("https://i.redd.it/clusqsm4oxzy.jpg"); + imgURLs.add("https://i.redd.it/svqvn7xs420z.jpg"); + imgURLs.add("http://i.imgur.com/j4AfH6P.jpg"); + imgURLs.add("https://i.redd.it/89cjkojkl10z.jpg"); + imgURLs.add("https://i.redd.it/aw7pv8jq4zzy.jpg"); + + setupImageGrid(imgURLs); + } + + private void setupImageGrid(ArrayList imgURLs){ + GridView gridView = (GridView) findViewById(R.id.gridView); + + GridImageAdapter adapter = new GridImageAdapter(mContext, R.layout.layout_grid_imageview, "", imgURLs); + gridView.setAdapter(adapter); + } + + private void setProfileImage(){ + Log.d(TAG, "setProfileImage: setting profile photo."); + String imgURL = "www.androidcentral.com/sites/androidcentral.com/files/styles/xlarge/public/article_images/2016/08/ac-lloyd.jpg?itok=bb72IeLf"; + UniversalImageLoader.setImage(imgURL, profilePhoto, mProgressBar, "https://"); + } + + private void setupActivityWidgets(){ + mProgressBar = (ProgressBar) findViewById(R.id.profileProgressBar); + mProgressBar.setVisibility(View.GONE); + profilePhoto = (ImageView) findViewById(R.id.profile_photo); } /** diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/GridImageAdapter.java b/app/src/main/java/tabian/com/instagramclone/Utils/GridImageAdapter.java new file mode 100644 index 0000000..304e3a8 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Utils/GridImageAdapter.java @@ -0,0 +1,123 @@ +package tabian.com.instagramclone.Utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.ProgressBar; + +import com.nostra13.universalimageloader.core.ImageLoader; +import com.nostra13.universalimageloader.core.assist.FailReason; +import com.nostra13.universalimageloader.core.listener.ImageLoadingListener; + +import java.util.ArrayList; + +import tabian.com.instagramclone.R; + +/** + * Created by User on 6/4/2017. + */ + +public class GridImageAdapter extends ArrayAdapter{ + + private Context mContext; + private LayoutInflater mInflater; + private int layoutResource; + private String mAppend; + private ArrayList imgURLs; + + public GridImageAdapter(Context context, int layoutResource, String append, ArrayList imgURLs) { + super(context, layoutResource, imgURLs); + mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + mContext = context; + this.layoutResource = layoutResource; + mAppend = append; + this.imgURLs = imgURLs; + } + + private static class ViewHolder{ + ImageView image; + ProgressBar mProgressBar; + } + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + + /* + Viewholder build pattern (Similar to recyclerview) + */ + final ViewHolder holder; + if(convertView == null){ + convertView = mInflater.inflate(layoutResource, parent, false); + holder = new ViewHolder(); + holder.mProgressBar = (ProgressBar) convertView.findViewById(R.id.gridImageProgressbar); + holder.image = (ImageView) convertView.findViewById(R.id.gridImageView); + + convertView.setTag(holder); + } + else{ + holder = (ViewHolder) convertView.getTag(); + } + + String imgURL = getItem(position); + + ImageLoader imageLoader = ImageLoader.getInstance(); + + imageLoader.displayImage(mAppend + imgURL, holder.image, new ImageLoadingListener() { + @Override + public void onLoadingStarted(String imageUri, View view) { + if(holder.mProgressBar != null){ + holder.mProgressBar.setVisibility(View.VISIBLE); + } + } + + @Override + public void onLoadingFailed(String imageUri, View view, FailReason failReason) { + if(holder.mProgressBar != null){ + holder.mProgressBar.setVisibility(View.GONE); + } + } + + @Override + public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { + if(holder.mProgressBar != null){ + holder.mProgressBar.setVisibility(View.GONE); + } + } + + @Override + public void onLoadingCancelled(String imageUri, View view) { + if(holder.mProgressBar != null){ + holder.mProgressBar.setVisibility(View.GONE); + } + } + }); + + return convertView; + } +} + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/layout_center_profile.xml b/app/src/main/res/layout/layout_center_profile.xml index 237b83c..1a0042a 100644 --- a/app/src/main/res/layout/layout_center_profile.xml +++ b/app/src/main/res/layout/layout_center_profile.xml @@ -43,7 +43,7 @@ android:layout_weight="25"> + + + + + + + \ No newline at end of file From df348142edcd5e8f76171ad00e5f317f98d19bd5 Mon Sep 17 00:00:00 2001 From: Mitch Date: Sun, 4 Jun 2017 17:30:45 -0700 Subject: [PATCH 023/122] part16 - Sqare ImageViews --- .../Profile/ProfileActivity.java | 9 ++++++ .../Utils/GridImageAdapter.java | 4 +-- .../instagramclone/Utils/SqaureImageView.java | 29 +++++++++++++++++++ .../main/res/layout/layout_grid_imageview.xml | 6 ++-- 4 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/tabian/com/instagramclone/Utils/SqaureImageView.java diff --git a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java index 23daf8f..9af1ab8 100644 --- a/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Profile/ProfileActivity.java @@ -13,6 +13,7 @@ import android.widget.GridView; import android.widget.ImageView; import android.widget.ProgressBar; +import android.widget.TextView; import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; @@ -30,12 +31,14 @@ public class ProfileActivity extends AppCompatActivity{ private static final String TAG = "ProfileActivity"; private static final int ACTIVITY_NUM = 4; + private static final int NUM_GRID_COLUMNS = 3; private Context mContext = ProfileActivity.this; private ProgressBar mProgressBar; private ImageView profilePhoto; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -49,6 +52,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { setProfileImage(); tempGridSetup(); + } private void tempGridSetup(){ @@ -72,6 +76,10 @@ private void tempGridSetup(){ private void setupImageGrid(ArrayList imgURLs){ GridView gridView = (GridView) findViewById(R.id.gridView); + int gridWidth = getResources().getDisplayMetrics().widthPixels; + int imageWidth = gridWidth/NUM_GRID_COLUMNS; + gridView.setColumnWidth(imageWidth); + GridImageAdapter adapter = new GridImageAdapter(mContext, R.layout.layout_grid_imageview, "", imgURLs); gridView.setAdapter(adapter); } @@ -86,6 +94,7 @@ private void setupActivityWidgets(){ mProgressBar = (ProgressBar) findViewById(R.id.profileProgressBar); mProgressBar.setVisibility(View.GONE); profilePhoto = (ImageView) findViewById(R.id.profile_photo); + } /** diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/GridImageAdapter.java b/app/src/main/java/tabian/com/instagramclone/Utils/GridImageAdapter.java index 304e3a8..a895009 100644 --- a/app/src/main/java/tabian/com/instagramclone/Utils/GridImageAdapter.java +++ b/app/src/main/java/tabian/com/instagramclone/Utils/GridImageAdapter.java @@ -41,7 +41,7 @@ public GridImageAdapter(Context context, int layoutResource, String append, Arra } private static class ViewHolder{ - ImageView image; + SqaureImageView image; ProgressBar mProgressBar; } @@ -57,7 +57,7 @@ Viewholder build pattern (Similar to recyclerview) convertView = mInflater.inflate(layoutResource, parent, false); holder = new ViewHolder(); holder.mProgressBar = (ProgressBar) convertView.findViewById(R.id.gridImageProgressbar); - holder.image = (ImageView) convertView.findViewById(R.id.gridImageView); + holder.image = (SqaureImageView) convertView.findViewById(R.id.gridImageView); convertView.setTag(holder); } diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/SqaureImageView.java b/app/src/main/java/tabian/com/instagramclone/Utils/SqaureImageView.java new file mode 100644 index 0000000..71e4bda --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Utils/SqaureImageView.java @@ -0,0 +1,29 @@ +package tabian.com.instagramclone.Utils; + +import android.content.Context; +import android.support.v7.widget.AppCompatImageView; +import android.util.AttributeSet; + +/** + * Created by User on 6/4/2017. + */ + +public class SqaureImageView extends AppCompatImageView { + + public SqaureImageView(Context context) { + super(context); + } + + public SqaureImageView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SqaureImageView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, widthMeasureSpec); + } +} diff --git a/app/src/main/res/layout/layout_grid_imageview.xml b/app/src/main/res/layout/layout_grid_imageview.xml index fec21d2..4967c33 100644 --- a/app/src/main/res/layout/layout_grid_imageview.xml +++ b/app/src/main/res/layout/layout_grid_imageview.xml @@ -1,9 +1,9 @@ + android:layout_width="wrap_content" + android:layout_height="wrap_content"> - Date: Sat, 10 Jun 2017 17:11:29 -0700 Subject: [PATCH 024/122] Create README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 01559dd..5c640aa 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,14 @@ things simple and condensed I will just use Firebase for everything. After all t
  • Account Settings Fragments
  • EditProfile Fragment Layout
  • + +
  • Universal Image Loader Config
  • + +
  • Testing Images in the User Profile
  • + +
  • Square ImageView Widgets
  • + +
  • More coming every week!
  • From 8ae1584eb7f06d2eae5a51447e38fbc96ab96579 Mon Sep 17 00:00:00 2001 From: Mitch Date: Mon, 19 Jun 2017 11:44:29 -0700 Subject: [PATCH 025/122] part17 - Login Layout --- .../instagramclone/Likes/LikesActivity.java | 4 +- app/src/main/res/drawable/instagram_logo.png | Bin 0 -> 122414 bytes .../res/drawable/white_rounded_button.xml | 29 +++++ app/src/main/res/layout/activity_login.xml | 107 ++++++++++++++++++ 4 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/drawable/instagram_logo.png create mode 100644 app/src/main/res/drawable/white_rounded_button.xml create mode 100644 app/src/main/res/layout/activity_login.xml diff --git a/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java b/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java index 87b1927..5d15c9e 100644 --- a/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java @@ -26,10 +26,10 @@ public class LikesActivity extends AppCompatActivity{ @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_home); + setContentView(R.layout.activity_login); Log.d(TAG, "onCreate: started."); - setupBottomNavigationView(); + //setupBottomNavigationView(); } /** diff --git a/app/src/main/res/drawable/instagram_logo.png b/app/src/main/res/drawable/instagram_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b8f392e4ef56f05cdcc249386f3a1fee01d49ced GIT binary patch literal 122414 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 KD^|)|hW{U4h2by& literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/white_rounded_button.xml b/app/src/main/res/drawable/white_rounded_button.xml new file mode 100644 index 0000000..817b8ea --- /dev/null +++ b/app/src/main/res/drawable/white_rounded_button.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..c708f6d --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From e32302aa11be0a7e360a11d21830488dfbabc9ee Mon Sep 17 00:00:00 2001 From: Mitch Date: Mon, 19 Jun 2017 11:55:58 -0700 Subject: [PATCH 026/122] part18 - Register Layout --- .../instagramclone/Likes/LikesActivity.java | 2 +- app/src/main/res/layout/activity_login.xml | 11 +- app/src/main/res/layout/activity_register.xml | 117 ++++++++++++++++++ 3 files changed, 124 insertions(+), 6 deletions(-) create mode 100644 app/src/main/res/layout/activity_register.xml diff --git a/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java b/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java index 5d15c9e..1f2e4a8 100644 --- a/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java @@ -26,7 +26,7 @@ public class LikesActivity extends AppCompatActivity{ @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_login); + setContentView(R.layout.activity_register); Log.d(TAG, "onCreate: started."); //setupBottomNavigationView(); diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index c708f6d..9599d73 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -17,7 +17,7 @@ android:layout_height="75dp" android:src="@drawable/instagram_logo" android:layout_gravity="center_horizontal" - android:layout_marginBottom="25dp"/> + android:layout_marginBottom="40dp"/> + android:layout_alignBottom="@+id/progressBar" + android:layout_alignRight="@+id/progressBar" + android:layout_alignLeft="@+id/progressBar"/>
    diff --git a/app/src/main/res/layout/activity_register.xml b/app/src/main/res/layout/activity_register.xml new file mode 100644 index 0000000..25d4d49 --- /dev/null +++ b/app/src/main/res/layout/activity_register.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From af2ce97f4c8fac1e0976c29feffb9cca8476c7bf Mon Sep 17 00:00:00 2001 From: Mitch Date: Mon, 19 Jun 2017 14:35:35 -0700 Subject: [PATCH 027/122] part20 - Setup Firebase Authentication --- app/build.gradle | 8 ++ app/google-services.json | 55 ++++++++++++++ app/src/main/AndroidManifest.xml | 2 + .../com/instagramclone/Home/HomeActivity.java | 75 +++++++++++++++++++ .../instagramclone/Likes/LikesActivity.java | 4 +- .../instagramclone/Login/LoginActivity.java | 30 ++++++++ .../Login/RegisterActivity.java | 24 ++++++ build.gradle | 2 + 8 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 app/google-services.json create mode 100644 app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java diff --git a/app/build.gradle b/app/build.gradle index 4095602..26e0e47 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -40,4 +40,12 @@ dependencies { //Universal image loader compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' + //firebase authentication + compile 'com.google.firebase:firebase-auth:11.0.1' + } + +//Firebase +apply plugin: 'com.google.gms.google-services' + + diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..0028473 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,55 @@ +{ + "project_info": { + "project_number": "318191497561", + "firebase_url": "https://instagramclone2-cd474.firebaseio.com", + "project_id": "instagramclone2-cd474", + "storage_bucket": "instagramclone2-cd474.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:318191497561:android:dac77f310048e88b", + "android_client_info": { + "package_name": "tabian.com.instagramclone" + } + }, + "oauth_client": [ + { + "client_id": "318191497561-6i65180hj99pv0l4o2a8bhtlbusp06t1.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "tabian.com.instagramclone", + "certificate_hash": "a1282f8c2b490a54cc1d7bdcefea5c630f537950" + } + }, + { + "client_id": "318191497561-a3ln1o39js8ot3j2mdv8fn9objqoihsj.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCpGGSLRslL60EFbhgp40sJ5H39C7ZczSs" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 2, + "other_platform_oauth_client": [ + { + "client_id": "318191497561-a3ln1o39js8ot3j2mdv8fn9objqoihsj.apps.googleusercontent.com", + "client_type": 3 + } + ] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b088e10..04c9722 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,6 +23,8 @@ + +
    \ No newline at end of file diff --git a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java index 96b2d1d..a74deb9 100644 --- a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java @@ -1,6 +1,8 @@ package tabian.com.instagramclone.Home; import android.content.Context; +import android.content.Intent; +import android.support.annotation.NonNull; import android.support.design.widget.TabLayout; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; @@ -9,9 +11,13 @@ import android.view.Menu; import android.view.MenuItem; + +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; import com.nostra13.universalimageloader.core.ImageLoader; +import tabian.com.instagramclone.Login.LoginActivity; import tabian.com.instagramclone.R; import tabian.com.instagramclone.Utils.BottomNavigationViewHelper; import tabian.com.instagramclone.Utils.SectionsPagerAdapter; @@ -24,18 +30,27 @@ public class HomeActivity extends AppCompatActivity { private Context mContext = HomeActivity.this; + //firebase + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); Log.d(TAG, "onCreate: starting."); + setupFirebaseAuth(); + initImageLoader(); setupBottomNavigationView(); setupViewPager(); } + + private void initImageLoader(){ UniversalImageLoader universalImageLoader = new UniversalImageLoader(mContext); ImageLoader.getInstance().init(universalImageLoader.getConfig()); @@ -72,4 +87,64 @@ private void setupBottomNavigationView(){ MenuItem menuItem = menu.getItem(ACTIVITY_NUM); menuItem.setChecked(true); } + + + /* + ------------------------------------ Firebase --------------------------------------------- + */ + + /** + * checks to see if the @param 'user' is logged in + * @param user + */ + private void checkCurrentUser(FirebaseUser user){ + Log.d(TAG, "checkCurrentUser: checking if user is logged in."); + + if(user == null){ + Intent intent = new Intent(mContext, LoginActivity.class); + startActivity(intent); + } + } + /** + * Setup the firebase auth object + */ + private void setupFirebaseAuth(){ + Log.d(TAG, "setupFirebaseAuth: setting up firebase auth."); + + mAuth = FirebaseAuth.getInstance(); + + mAuthListener = new FirebaseAuth.AuthStateListener() { + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + + //check if the user is logged in + checkCurrentUser(user); + + if (user != null) { + // User is signed in + Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); + } else { + // User is signed out + Log.d(TAG, "onAuthStateChanged:signed_out"); + } + // ... + } + }; + } + + @Override + public void onStart() { + super.onStart(); + mAuth.addAuthStateListener(mAuthListener); + } + + @Override + public void onStop() { + super.onStop(); + if (mAuthListener != null) { + mAuth.removeAuthStateListener(mAuthListener); + } + } + } diff --git a/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java b/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java index 1f2e4a8..87b1927 100644 --- a/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Likes/LikesActivity.java @@ -26,10 +26,10 @@ public class LikesActivity extends AppCompatActivity{ @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_register); + setContentView(R.layout.activity_home); Log.d(TAG, "onCreate: started."); - //setupBottomNavigationView(); + setupBottomNavigationView(); } /** diff --git a/app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java b/app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java new file mode 100644 index 0000000..b2f1651 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java @@ -0,0 +1,30 @@ +package tabian.com.instagramclone.Login; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; + + +import tabian.com.instagramclone.R; + +/** + * Created by User on 6/19/2017. + */ + +public class LoginActivity extends AppCompatActivity { + + private static final String TAG = "LoginActivity"; + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + Log.d(TAG, "onCreate: started."); + + + } + +} diff --git a/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java b/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java new file mode 100644 index 0000000..a6150d1 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java @@ -0,0 +1,24 @@ +package tabian.com.instagramclone.Login; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; + +import tabian.com.instagramclone.R; + +/** + * Created by User on 6/19/2017. + */ + +public class RegisterActivity extends AppCompatActivity { + + private static final String TAG = "RegisterActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_register); + Log.d(TAG, "onCreate: started."); + } +} diff --git a/build.gradle b/build.gradle index f1bed3e..db26d6d 100644 --- a/build.gradle +++ b/build.gradle @@ -6,9 +6,11 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:2.3.1' + classpath 'com.google.gms:google-services:3.1.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files + } } From bedefc93cdd7bdaf0c90294f2d0b2df708508e53 Mon Sep 17 00:00:00 2001 From: Mitch Date: Mon, 19 Jun 2017 15:09:16 -0700 Subject: [PATCH 028/122] part21 - Testing Firebase Authentication --- .../com/instagramclone/Home/HomeActivity.java | 1 + .../instagramclone/Login/LoginActivity.java | 162 ++++++++++++++++++ app/src/main/res/layout/activity_login.xml | 3 +- app/src/main/res/values/strings.xml | 5 + 4 files changed, 170 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java index a74deb9..9d55008 100644 --- a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java @@ -137,6 +137,7 @@ public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { public void onStart() { super.onStart(); mAuth.addAuthStateListener(mAuthListener); + checkCurrentUser(mAuth.getCurrentUser()); } @Override diff --git a/app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java b/app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java index b2f1651..6ab0f58 100644 --- a/app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java @@ -1,12 +1,26 @@ package tabian.com.instagramclone.Login; +import android.content.Context; +import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.auth.AuthResult; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; + import tabian.com.instagramclone.R; /** @@ -17,14 +31,162 @@ public class LoginActivity extends AppCompatActivity { private static final String TAG = "LoginActivity"; + //firebase + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + + private Context mContext; + private ProgressBar mProgressBar; + private EditText mEmail, mPassword; + private TextView mPleaseWait; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); + mProgressBar = (ProgressBar) findViewById(R.id.progressBar); + mPleaseWait = (TextView) findViewById(R.id.pleaseWait); + mEmail = (EditText) findViewById(R.id.input_email); + mPassword = (EditText) findViewById(R.id.input_password); + mContext = LoginActivity.this; Log.d(TAG, "onCreate: started."); + mPleaseWait.setVisibility(View.GONE); + mProgressBar.setVisibility(View.GONE); + + setupFirebaseAuth(); + init(); + + } + + private boolean isStringNull(String string){ + Log.d(TAG, "isStringNull: checking string if null."); + + if(string.equals("")){ + return true; + } + else{ + return false; + } + } + + /* + ------------------------------------ Firebase --------------------------------------------- + */ + + private void init(){ + + //initialize the button for logging in + Button btnLogin = (Button) findViewById(R.id.btn_login); + btnLogin.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "onClick: attempting to log in."); + + String email = mEmail.getText().toString(); + String password = mPassword.getText().toString(); + if(isStringNull(email) && isStringNull(password)){ + Toast.makeText(mContext, "You must fill out all the fields", Toast.LENGTH_SHORT).show(); + }else{ + mProgressBar.setVisibility(View.VISIBLE); + mPleaseWait.setVisibility(View.VISIBLE); + + mAuth.signInWithEmailAndPassword(email, password) + .addOnCompleteListener(LoginActivity.this, new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + Log.d(TAG, "signInWithEmail:onComplete:" + task.isSuccessful()); + + // If sign in fails, display a message to the user. If sign in succeeds + // the auth state listener will be notified and logic to handle the + // signed in user can be handled in the listener. + if (!task.isSuccessful()) { + Log.w(TAG, "signInWithEmail:failed", task.getException()); + + Toast.makeText(LoginActivity.this, getString(R.string.auth_failed), + Toast.LENGTH_SHORT).show(); + mProgressBar.setVisibility(View.GONE); + mPleaseWait.setVisibility(View.GONE); + } + else{ + Log.d(TAG, "signInWithEmail: successful login"); + Toast.makeText(LoginActivity.this, getString(R.string.auth_success), + Toast.LENGTH_SHORT).show(); + mProgressBar.setVisibility(View.GONE); + mPleaseWait.setVisibility(View.GONE); + } + + // ... + } + }); + } + + } + }); + } + + /** + * Setup the firebase auth object + */ + private void setupFirebaseAuth(){ + Log.d(TAG, "setupFirebaseAuth: setting up firebase auth."); + + mAuth = FirebaseAuth.getInstance(); + + mAuthListener = new FirebaseAuth.AuthStateListener() { + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + + if (user != null) { + // User is signed in + Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); + } else { + // User is signed out + Log.d(TAG, "onAuthStateChanged:signed_out"); + } + // ... + } + }; + } + + @Override + public void onStart() { + super.onStart(); + mAuth.addAuthStateListener(mAuthListener); } + @Override + public void onStop() { + super.onStop(); + if (mAuthListener != null) { + mAuth.removeAuthStateListener(mAuthListener); + } + } } + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 9599d73..89834ca 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -85,7 +85,8 @@ android:textSize="20sp" android:layout_alignBottom="@+id/progressBar" android:layout_alignRight="@+id/progressBar" - android:layout_alignLeft="@+id/progressBar"/> + android:layout_alignLeft="@+id/progressBar" + android:id="@+id/pleaseWait"/>
    diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4ed3fc2..dc9745e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,4 +3,9 @@ Edit Profile Sign Out + + + + Failed to Authenticate + Authentication Success From 5db4202be6f96ea0f1a8affe1e853ed41e7fd399 Mon Sep 17 00:00:00 2001 From: Mitch Date: Mon, 19 Jun 2017 15:23:12 -0700 Subject: [PATCH 029/122] part22 - Register Activity Widgets --- .../instagramclone/Login/LoginActivity.java | 20 ++++ .../Login/RegisterActivity.java | 93 +++++++++++++++++++ app/src/main/res/layout/activity_register.xml | 3 +- 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java b/app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java index 6ab0f58..631de98 100644 --- a/app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Login/LoginActivity.java @@ -21,6 +21,7 @@ import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; +import tabian.com.instagramclone.Home.HomeActivity; import tabian.com.instagramclone.R; /** @@ -125,6 +126,25 @@ public void onComplete(@NonNull Task task) { } }); + + TextView linkSignUp = (TextView) findViewById(R.id.link_signup); + linkSignUp.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "onClick: navigating to register screen"); + Intent intent = new Intent(LoginActivity.this, RegisterActivity.class); + startActivity(intent); + } + }); + + /* + If the user is logged in then navigate to HomeActivity and call 'finish()' + */ + if(mAuth.getCurrentUser() != null){ + Intent intent = new Intent(LoginActivity.this, HomeActivity.class); + startActivity(intent); + finish(); + } } /** diff --git a/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java b/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java index a6150d1..4422f91 100644 --- a/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java @@ -1,9 +1,19 @@ package tabian.com.instagramclone.Login; +import android.content.Context; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; import tabian.com.instagramclone.R; @@ -15,10 +25,93 @@ public class RegisterActivity extends AppCompatActivity { private static final String TAG = "RegisterActivity"; + private Context mContext; + private String email, username, password; + private EditText mEmail, mPassword, mUsername; + private TextView loadingPleaseWait; + private Button btnRegister; + private ProgressBar mProgressBar; + + //firebase + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); Log.d(TAG, "onCreate: started."); + + initWidgets(); + setupFirebaseAuth(); + } + + /** + * Initialize the activity widgets + */ + private void initWidgets(){ + Log.d(TAG, "initWidgets: Initializing Widgets."); + mEmail = (EditText) findViewById(R.id.input_email); + mProgressBar = (ProgressBar) findViewById(R.id.progressBar); + loadingPleaseWait = (TextView) findViewById(R.id.loadingPleaseWait); + mPassword = (EditText) findViewById(R.id.input_password); + mContext = RegisterActivity.this; + mProgressBar.setVisibility(View.GONE); + loadingPleaseWait.setVisibility(View.GONE); + + } + + private boolean isStringNull(String string){ + Log.d(TAG, "isStringNull: checking string if null."); + + if(string.equals("")){ + return true; + } + else{ + return false; + } + } + + /* + ------------------------------------ Firebase --------------------------------------------- + */ + + /** + * Setup the firebase auth object + */ + private void setupFirebaseAuth(){ + Log.d(TAG, "setupFirebaseAuth: setting up firebase auth."); + + mAuth = FirebaseAuth.getInstance(); + + mAuthListener = new FirebaseAuth.AuthStateListener() { + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + + if (user != null) { + // User is signed in + Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); + } else { + // User is signed out + Log.d(TAG, "onAuthStateChanged:signed_out"); + } + // ... + } + }; + } + + @Override + public void onStart() { + super.onStart(); + mAuth.addAuthStateListener(mAuthListener); + } + + @Override + public void onStop() { + super.onStop(); + if (mAuthListener != null) { + mAuth.removeAuthStateListener(mAuthListener); + } } } diff --git a/app/src/main/res/layout/activity_register.xml b/app/src/main/res/layout/activity_register.xml index 25d4d49..95d18a2 100644 --- a/app/src/main/res/layout/activity_register.xml +++ b/app/src/main/res/layout/activity_register.xml @@ -94,7 +94,8 @@ android:textSize="20sp" android:layout_alignBottom="@+id/progressBar" android:layout_alignRight="@+id/progressBar" - android:layout_alignLeft="@+id/progressBar"/> + android:layout_alignLeft="@+id/progressBar" + android:id="@+id/loadingPleaseWait"/> From cb5008eed6fd56db1ad0a768b4a289b5aeae99f6 Mon Sep 17 00:00:00 2001 From: Mitch Date: Mon, 26 Jun 2017 14:45:30 -0700 Subject: [PATCH 030/122] part23 - Register New User with Firebase --- app/build.gradle | 2 +- .../Login/RegisterActivity.java | 34 ++++++++++ .../instagramclone/Utils/FirebaseMethods.java | 68 +++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java diff --git a/app/build.gradle b/app/build.gradle index 26e0e47..b12ed65 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -41,7 +41,7 @@ dependencies { compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' //firebase authentication - compile 'com.google.firebase:firebase-auth:11.0.1' + compile 'com.google.firebase:firebase-auth:10.2.6' } diff --git a/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java b/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java index 4422f91..1b0ca65 100644 --- a/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java @@ -11,11 +11,13 @@ import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; import tabian.com.instagramclone.R; +import tabian.com.instagramclone.Utils.FirebaseMethods; /** * Created by User on 6/19/2017. @@ -35,23 +37,55 @@ public class RegisterActivity extends AppCompatActivity { //firebase private FirebaseAuth mAuth; private FirebaseAuth.AuthStateListener mAuthListener; + private FirebaseMethods firebaseMethods; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); + mContext = RegisterActivity.this; + firebaseMethods = new FirebaseMethods(mContext); Log.d(TAG, "onCreate: started."); initWidgets(); setupFirebaseAuth(); + init(); } + private void init(){ + btnRegister.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + email = mEmail.getText().toString(); + username = mUsername.getText().toString(); + password = mPassword.getText().toString(); + + if(checkInputs(email, username, password)){ + mProgressBar.setVisibility(View.VISIBLE); + loadingPleaseWait.setVisibility(View.VISIBLE); + + firebaseMethods.registerNewEmail(email, password, username); + } + } + }); + } + + private boolean checkInputs(String email, String username, String password){ + Log.d(TAG, "checkInputs: checking inputs for null values."); + if(email.equals("") || username.equals("") || password.equals("")){ + Toast.makeText(mContext, "All fields must be filled out.", Toast.LENGTH_SHORT).show(); + return false; + } + return true; + } /** * Initialize the activity widgets */ private void initWidgets(){ Log.d(TAG, "initWidgets: Initializing Widgets."); mEmail = (EditText) findViewById(R.id.input_email); + mUsername = (EditText) findViewById(R.id.input_username); + btnRegister = (Button) findViewById(R.id.btn_register); mProgressBar = (ProgressBar) findViewById(R.id.progressBar); loadingPleaseWait = (TextView) findViewById(R.id.loadingPleaseWait); mPassword = (EditText) findViewById(R.id.input_password); diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java b/app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java new file mode 100644 index 0000000..efee717 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java @@ -0,0 +1,68 @@ +package tabian.com.instagramclone.Utils; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.util.Log; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.auth.AuthResult; +import com.google.firebase.auth.FirebaseAuth; + +import tabian.com.instagramclone.R; + +/** + * Created by User on 6/26/2017. + */ + +public class FirebaseMethods { + + private static final String TAG = "FirebaseMethods"; + + //firebase + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + private String userID; + + private Context mContext; + + public FirebaseMethods(Context context) { + mAuth = FirebaseAuth.getInstance(); + mContext = context; + + if(mAuth.getCurrentUser() != null){ + userID = mAuth.getCurrentUser().getUid(); + } + } + + /** + * Register a new email and password to Firebase Authentication + * @param email + * @param password + * @param username + */ + public void registerNewEmail(final String email, String password, final String username){ + mAuth.createUserWithEmailAndPassword(email, password) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + Log.d(TAG, "createUserWithEmail:onComplete:" + task.isSuccessful()); + + // If sign in fails, display a message to the user. If sign in succeeds + // the auth state listener will be notified and logic to handle the + // signed in user can be handled in the listener. + if (!task.isSuccessful()) { + Toast.makeText(mContext, R.string.auth_failed, + Toast.LENGTH_SHORT).show(); + + } + else if(task.isSuccessful()){ + userID = mAuth.getCurrentUser().getUid(); + Log.d(TAG, "onComplete: Authstate changed: " + userID); + } + + } + }); + } +} From 6e2ffe29621c592e57057b8561d3cac4df9c14a1 Mon Sep 17 00:00:00 2001 From: Mitch Date: Mon, 26 Jun 2017 16:13:13 -0700 Subject: [PATCH 031/122] part25 - Check if Username Already Exists --- app/build.gradle | 3 + .../Login/RegisterActivity.java | 34 ++++++++++ .../instagramclone/Utils/FirebaseMethods.java | 22 ++++++ .../Utils/StringManipulation.java | 16 +++++ .../com/instagramclone/models/User.java | 68 +++++++++++++++++++ 5 files changed, 143 insertions(+) create mode 100644 app/src/main/java/tabian/com/instagramclone/Utils/StringManipulation.java create mode 100644 app/src/main/java/tabian/com/instagramclone/models/User.java diff --git a/app/build.gradle b/app/build.gradle index b12ed65..f1ce730 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,6 +43,9 @@ dependencies { //firebase authentication compile 'com.google.firebase:firebase-auth:10.2.6' + //firebase database + compile 'com.google.firebase:firebase-database:10.2.6' + } //Firebase diff --git a/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java b/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java index 1b0ca65..f6f3ced 100644 --- a/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java @@ -15,6 +15,11 @@ import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ValueEventListener; import tabian.com.instagramclone.R; import tabian.com.instagramclone.Utils.FirebaseMethods; @@ -38,6 +43,11 @@ public class RegisterActivity extends AppCompatActivity { private FirebaseAuth mAuth; private FirebaseAuth.AuthStateListener mAuthListener; private FirebaseMethods firebaseMethods; + private FirebaseDatabase mFirebaseDatabase; + private DatabaseReference myRef; + + private String append = ""; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -117,6 +127,8 @@ private void setupFirebaseAuth(){ Log.d(TAG, "setupFirebaseAuth: setting up firebase auth."); mAuth = FirebaseAuth.getInstance(); + mFirebaseDatabase = FirebaseDatabase.getInstance(); + myRef = mFirebaseDatabase.getReference(); mAuthListener = new FirebaseAuth.AuthStateListener() { @Override @@ -126,6 +138,28 @@ public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { if (user != null) { // User is signed in Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); + + myRef.addListenerForSingleValueEvent(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + //1st check: Make sure the username is not already in use + if(firebaseMethods.checkIfUsernameExists(username, dataSnapshot)){ + append = myRef.push().getKey().substring(3,10); + Log.d(TAG, "onDataChange: username already exists. Appending random string to name: " + append); + } + username = username = append; + + //add new user to the database + + //add new user_account_settings to the database + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + } else { // User is signed out Log.d(TAG, "onAuthStateChanged:signed_out"); diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java b/app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java index efee717..0c13777 100644 --- a/app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java +++ b/app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java @@ -9,8 +9,11 @@ import com.google.android.gms.tasks.Task; import com.google.firebase.auth.AuthResult; import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.UserInfo; +import com.google.firebase.database.DataSnapshot; import tabian.com.instagramclone.R; +import tabian.com.instagramclone.models.User; /** * Created by User on 6/26/2017. @@ -36,6 +39,25 @@ public FirebaseMethods(Context context) { } } + public boolean checkIfUsernameExists(String username, DataSnapshot datasnapshot){ + Log.d(TAG, "checkIfUsernameExists: checking if " + username + " already exists."); + + User user = new User(); + + for (DataSnapshot ds: datasnapshot.getChildren()){ + Log.d(TAG, "checkIfUsernameExists: datasnapshot: " + ds); + + user.setUsername(ds.getValue(User.class).getUsername()); + Log.d(TAG, "checkIfUsernameExists: username: " + user.getUsername()); + + if(StringManipulation.expandUsername(user.getUsername()).equals(username)){ + Log.d(TAG, "checkIfUsernameExists: FOUND A MATCH: " + user.getUsername()); + return true; + } + } + return false; + } + /** * Register a new email and password to Firebase Authentication * @param email diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/StringManipulation.java b/app/src/main/java/tabian/com/instagramclone/Utils/StringManipulation.java new file mode 100644 index 0000000..fc41c43 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/Utils/StringManipulation.java @@ -0,0 +1,16 @@ +package tabian.com.instagramclone.Utils; + +/** + * Created by User on 6/26/2017. + */ + +public class StringManipulation { + + public static String expandUsername(String username){ + return username.replace(".", " "); + } + + public static String condenseUsername(String username){ + return username.replace(" " , "."); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone/models/User.java b/app/src/main/java/tabian/com/instagramclone/models/User.java new file mode 100644 index 0000000..6c1b1ae --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/models/User.java @@ -0,0 +1,68 @@ +package tabian.com.instagramclone.models; + +/** + * Created by User on 6/26/2017. + */ + +public class User { + + private String user_id; + private String phone_number; + private String email; + private String username; + + public User(String user_id, String phone_number, String email, String username) { + this.user_id = user_id; + this.phone_number = phone_number; + this.email = email; + this.username = username; + } + + public User() { + + } + + + public String getUser_id() { + return user_id; + } + + public void setUser_id(String user_id) { + this.user_id = user_id; + } + + public String getPhone_number() { + return phone_number; + } + + public void setPhone_number(String phone_number) { + this.phone_number = phone_number; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + + @Override + public String toString() { + return "User{" + + "user_id='" + user_id + '\'' + + ", phone_number='" + phone_number + '\'' + + ", email='" + email + '\'' + + ", username='" + username + '\'' + + '}'; + } +} From bf91701df9f8cb7cf07d201444e10d8f426ff4ec Mon Sep 17 00:00:00 2001 From: Mitch Tabian Date: Mon, 26 Jun 2017 16:20:08 -0700 Subject: [PATCH 032/122] Update README.md --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 5c640aa..9073335 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,22 @@ things simple and condensed I will just use Firebase for everything. After all t
  • Square ImageView Widgets
  • +
  • Login Layout
  • + +
  • Register Layout
  • + +
  • Setup Firebase Authentication
  • + +
  • Testing Firebase Authentication
  • + +
  • Setup Register Activity Widgets
  • + +
  • Register New User with Firebase
  • + +
  • Firebase Database Structure (no source code)
  • + +
  • Check if Username Already Exists
  • +
  • More coming every week!
  • From 21baa87221e844d38740f0d02e3615887c64dc18 Mon Sep 17 00:00:00 2001 From: Mitch Date: Thu, 29 Jun 2017 20:53:58 -0700 Subject: [PATCH 033/122] part26 - Insert New User Data --- .../com/instagramclone/Home/HomeActivity.java | 1 + .../Login/RegisterActivity.java | 6 +- .../com/instagramclone/models/User.java | 8 +- .../models/UserAccountSettings.java | 111 ++++++++++++++++++ 4 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/tabian/com/instagramclone/models/UserAccountSettings.java diff --git a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java index 9d55008..8bd9d42 100644 --- a/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Home/HomeActivity.java @@ -47,6 +47,7 @@ protected void onCreate(Bundle savedInstanceState) { setupBottomNavigationView(); setupViewPager(); + } diff --git a/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java b/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java index f6f3ced..b172c0c 100644 --- a/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java +++ b/app/src/main/java/tabian/com/instagramclone/Login/RegisterActivity.java @@ -147,11 +147,13 @@ public void onDataChange(DataSnapshot dataSnapshot) { append = myRef.push().getKey().substring(3,10); Log.d(TAG, "onDataChange: username already exists. Appending random string to name: " + append); } - username = username = append; + username = username + append; //add new user to the database + firebaseMethods.addNewUser(email, username, "", "", ""); + + Toast.makeText(mContext, "Signup successful. Sending verification email.", Toast.LENGTH_SHORT).show(); - //add new user_account_settings to the database } @Override diff --git a/app/src/main/java/tabian/com/instagramclone/models/User.java b/app/src/main/java/tabian/com/instagramclone/models/User.java index 6c1b1ae..89d3635 100644 --- a/app/src/main/java/tabian/com/instagramclone/models/User.java +++ b/app/src/main/java/tabian/com/instagramclone/models/User.java @@ -7,11 +7,11 @@ public class User { private String user_id; - private String phone_number; + private long phone_number; private String email; private String username; - public User(String user_id, String phone_number, String email, String username) { + public User(String user_id, long phone_number, String email, String username) { this.user_id = user_id; this.phone_number = phone_number; this.email = email; @@ -31,11 +31,11 @@ public void setUser_id(String user_id) { this.user_id = user_id; } - public String getPhone_number() { + public long getPhone_number() { return phone_number; } - public void setPhone_number(String phone_number) { + public void setPhone_number(long phone_number) { this.phone_number = phone_number; } diff --git a/app/src/main/java/tabian/com/instagramclone/models/UserAccountSettings.java b/app/src/main/java/tabian/com/instagramclone/models/UserAccountSettings.java new file mode 100644 index 0000000..ed534f9 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone/models/UserAccountSettings.java @@ -0,0 +1,111 @@ +package tabian.com.instagramclone.models; + +/** + * Created by User on 6/29/2017. + */ + +public class UserAccountSettings { + + private String description; + private String display_name; + private long followers; + private long following; + private long posts; + private String profile_photo; + private String username; + private String website; + + public UserAccountSettings(String description, String display_name, long followers, long following, + long posts, String profile_photo, String username, String website) { + this.description = description; + this.display_name = display_name; + this.followers = followers; + this.following = following; + this.posts = posts; + this.profile_photo = profile_photo; + this.username = username; + this.website = website; + } + public UserAccountSettings() { + + } + + public String getDescription() { + return description; + } + + public void setDscription(String description) { + this.description = description; + } + + public String getDisplay_name() { + return display_name; + } + + public void setDisplay_name(String display_name) { + this.display_name = display_name; + } + + public long getFollowers() { + return followers; + } + + public void setFollowers(long followers) { + this.followers = followers; + } + + public long getFollowing() { + return following; + } + + public void setFollowing(long following) { + this.following = following; + } + + public long getPosts() { + return posts; + } + + public void setPosts(long posts) { + this.posts = posts; + } + + public String getProfile_photo() { + return profile_photo; + } + + public void setProfile_photo(String profile_photo) { + this.profile_photo = profile_photo; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getWebsite() { + return website; + } + + public void setWebsite(String website) { + this.website = website; + } + + + @Override + public String toString() { + return "UserAccountSettings{" + + "description='" + description + '\'' + + ", display_name='" + display_name + '\'' + + ", followers=" + followers + + ", following=" + following + + ", posts=" + posts + + ", profile_photo='" + profile_photo + '\'' + + ", username='" + username + '\'' + + ", website='" + website + '\'' + + '}'; + } +} From f01202197a5f00dd66f45204ebdefab921c1657b Mon Sep 17 00:00:00 2001 From: Mitch Date: Thu, 29 Jun 2017 20:55:39 -0700 Subject: [PATCH 034/122] part26 - Insert New User Data --- .../instagramclone/Utils/FirebaseMethods.java | 61 ++++++++++++++++++- app/src/main/res/values/strings.xml | 7 +++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java b/app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java index 0c13777..82eab84 100644 --- a/app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java +++ b/app/src/main/java/tabian/com/instagramclone/Utils/FirebaseMethods.java @@ -11,9 +11,12 @@ import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.UserInfo; import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; import tabian.com.instagramclone.R; import tabian.com.instagramclone.models.User; +import tabian.com.instagramclone.models.UserAccountSettings; /** * Created by User on 6/26/2017. @@ -26,12 +29,16 @@ public class FirebaseMethods { //firebase private FirebaseAuth mAuth; private FirebaseAuth.AuthStateListener mAuthListener; + private FirebaseDatabase mFirebaseDatabase; + private DatabaseReference myRef; private String userID; private Context mContext; public FirebaseMethods(Context context) { mAuth = FirebaseAuth.getInstance(); + mFirebaseDatabase = FirebaseDatabase.getInstance(); + myRef = mFirebaseDatabase.getReference(); mContext = context; if(mAuth.getCurrentUser() != null){ @@ -44,7 +51,7 @@ public boolean checkIfUsernameExists(String username, DataSnapshot datasnapshot) User user = new User(); - for (DataSnapshot ds: datasnapshot.getChildren()){ + for (DataSnapshot ds: datasnapshot.child(userID).getChildren()){ Log.d(TAG, "checkIfUsernameExists: datasnapshot: " + ds); user.setUsername(ds.getValue(User.class).getUsername()); @@ -87,4 +94,56 @@ else if(task.isSuccessful()){ } }); } + + + + public void addNewUser(String email, String username, String description, String website, String profile_photo){ + + User user = new User( userID, 1, email, StringManipulation.condenseUsername(username) ); + + myRef.child(mContext.getString(R.string.dbname_users)) + .child(userID) + .setValue(user); + + + UserAccountSettings settings = new UserAccountSettings( + description, + username, + 0, + 0, + 0, + profile_photo, + username, + website + ); + + myRef.child(mContext.getString(R.string.dbname_user_account_settings)) + .child(userID) + .setValue(settings); + + } + } + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dc9745e..91c1ec0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,7 @@ InstagramClone + Edit Profile Sign Out @@ -8,4 +9,10 @@ Failed to Authenticate Authentication Success + + + users + user_account_settings + + From 5054ca6e84a7c101c0088dceaef0c4df1a34bc7e Mon Sep 17 00:00:00 2001 From: Mitch Date: Thu, 29 Jun 2017 21:29:38 -0700 Subject: [PATCH 035/122] part27 - Email Verification --- app/build.gradle | 2 +- app/google-services.json | 22 +- .../ExampleInstrumentedTest.java | 26 ++ app/src/main/AndroidManifest.xml | 18 +- .../instagramclone2/Home/CameraFragment.java | 26 ++ .../instagramclone2/Home/HomeActivity.java | 152 ++++++++++++ .../instagramclone2/Home/HomeFragment.java | 26 ++ .../Home/MessagesFragment.java | 26 ++ .../instagramclone2/Likes/LikesActivity.java | 47 ++++ .../instagramclone2/Login/LoginActivity.java | 222 ++++++++++++++++++ .../Login/RegisterActivity.java | 190 +++++++++++++++ .../Profile/AccountSettingsActivity.java | 128 ++++++++++ .../Profile/EditProfileFragment.java | 52 ++++ .../Profile/ProfileActivity.java | 130 ++++++++++ .../Profile/SignOutFragment.java | 27 +++ .../Search/SearchActivity.java | 47 ++++ .../instagramclone2/Share/ShareActivity.java | 47 ++++ .../Utils/BottomNavigationViewHelper.java | 72 ++++++ .../Utils/FirebaseMethods.java | 177 ++++++++++++++ .../Utils/GridImageAdapter.java | 122 ++++++++++ .../Utils/SectionsPagerAdapter.java | 43 ++++ .../Utils/SectionsStatePagerAdapter.java | 102 ++++++++ .../Utils/SqaureImageView.java | 29 +++ .../Utils/StringManipulation.java | 16 ++ .../Utils/UniversalImageLoader.java | 93 ++++++++ .../com/instagramclone2/models/User.java | 68 ++++++ .../models/UserAccountSettings.java | 111 +++++++++ app/src/main/res/layout/activity_home.xml | 2 +- .../main/res/layout/layout_grid_imageview.xml | 2 +- .../com/instagramclone2/ExampleUnitTest.java | 17 ++ 30 files changed, 2019 insertions(+), 23 deletions(-) create mode 100644 app/src/androidTest/java/tabian/com/instagramclone2/ExampleInstrumentedTest.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Home/CameraFragment.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Home/HomeActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Home/HomeFragment.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Home/MessagesFragment.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Likes/LikesActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Login/LoginActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Login/RegisterActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Profile/AccountSettingsActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Profile/EditProfileFragment.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Profile/ProfileActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Profile/SignOutFragment.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Search/SearchActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Share/ShareActivity.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Utils/BottomNavigationViewHelper.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Utils/FirebaseMethods.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Utils/GridImageAdapter.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Utils/SectionsPagerAdapter.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Utils/SectionsStatePagerAdapter.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Utils/SqaureImageView.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Utils/StringManipulation.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/Utils/UniversalImageLoader.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/models/User.java create mode 100644 app/src/main/java/tabian/com/instagramclone2/models/UserAccountSettings.java create mode 100644 app/src/test/java/tabian/com/instagramclone2/ExampleUnitTest.java diff --git a/app/build.gradle b/app/build.gradle index f1ce730..a4c410d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,7 +4,7 @@ android { compileSdkVersion 25 buildToolsVersion "25.0.0" defaultConfig { - applicationId "tabian.com.instagramclone" + applicationId "tabian.com.instagramclone2" minSdkVersion 18 targetSdkVersion 25 versionCode 1 diff --git a/app/google-services.json b/app/google-services.json index 0028473..a68a365 100644 --- a/app/google-services.json +++ b/app/google-services.json @@ -1,35 +1,35 @@ { "project_info": { - "project_number": "318191497561", - "firebase_url": "https://instagramclone2-cd474.firebaseio.com", - "project_id": "instagramclone2-cd474", - "storage_bucket": "instagramclone2-cd474.appspot.com" + "project_number": "352531809002", + "firebase_url": "https://instagramclone3-b6678.firebaseio.com", + "project_id": "instagramclone3-b6678", + "storage_bucket": "instagramclone3-b6678.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:318191497561:android:dac77f310048e88b", + "mobilesdk_app_id": "1:352531809002:android:d49c650ed5c2c559", "android_client_info": { - "package_name": "tabian.com.instagramclone" + "package_name": "tabian.com.instagramclone2" } }, "oauth_client": [ { - "client_id": "318191497561-6i65180hj99pv0l4o2a8bhtlbusp06t1.apps.googleusercontent.com", + "client_id": "352531809002-gi64mu16aovb40gf82b1fi2sen302e9h.apps.googleusercontent.com", "client_type": 1, "android_info": { - "package_name": "tabian.com.instagramclone", + "package_name": "tabian.com.instagramclone2", "certificate_hash": "a1282f8c2b490a54cc1d7bdcefea5c630f537950" } }, { - "client_id": "318191497561-a3ln1o39js8ot3j2mdv8fn9objqoihsj.apps.googleusercontent.com", + "client_id": "352531809002-sm8t77fn6vf3177s6kig01tm0bd46clo.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyCpGGSLRslL60EFbhgp40sJ5H39C7ZczSs" + "current_key": "AIzaSyCJXKgHH5JH7ytTLDSSJ4IeE3iFl5AV7pw" } ], "services": { @@ -40,7 +40,7 @@ "status": 2, "other_platform_oauth_client": [ { - "client_id": "318191497561-a3ln1o39js8ot3j2mdv8fn9objqoihsj.apps.googleusercontent.com", + "client_id": "352531809002-sm8t77fn6vf3177s6kig01tm0bd46clo.apps.googleusercontent.com", "client_type": 3 } ] diff --git a/app/src/androidTest/java/tabian/com/instagramclone2/ExampleInstrumentedTest.java b/app/src/androidTest/java/tabian/com/instagramclone2/ExampleInstrumentedTest.java new file mode 100644 index 0000000..36e378b --- /dev/null +++ b/app/src/androidTest/java/tabian/com/instagramclone2/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package tabian.com.instagramclone2; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("tabian.com.instagramclone", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 04c9722..4bd64e2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="tabian.com.instagramclone2"> @@ -11,20 +11,20 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> - + - - - - - - - + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/tabian/com/instagramclone2/Home/CameraFragment.java b/app/src/main/java/tabian/com/instagramclone2/Home/CameraFragment.java new file mode 100644 index 0000000..cd704ba --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Home/CameraFragment.java @@ -0,0 +1,26 @@ +package tabian.com.instagramclone2.Home; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import tabian.com.instagramclone2.R; + +/** + * Created by User on 5/28/2017. + */ + +public class CameraFragment extends Fragment { + private static final String TAG = "CameraFragment"; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_camera, container, false); + + return view; + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Home/HomeActivity.java b/app/src/main/java/tabian/com/instagramclone2/Home/HomeActivity.java new file mode 100644 index 0000000..90c2280 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Home/HomeActivity.java @@ -0,0 +1,152 @@ +package tabian.com.instagramclone2.Home; + +import android.content.Context; +import android.content.Intent; +import android.support.annotation.NonNull; +import android.support.design.widget.TabLayout; +import android.support.v4.view.ViewPager; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + + +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; +import com.nostra13.universalimageloader.core.ImageLoader; + +import tabian.com.instagramclone2.Login.LoginActivity; +import tabian.com.instagramclone2.R; +import tabian.com.instagramclone2.Utils.BottomNavigationViewHelper; +import tabian.com.instagramclone2.Utils.SectionsPagerAdapter; +import tabian.com.instagramclone2.Utils.UniversalImageLoader; + +public class HomeActivity extends AppCompatActivity { + + private static final String TAG = "HomeActivity"; + private static final int ACTIVITY_NUM = 0; + + private Context mContext = HomeActivity.this; + + //firebase + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: starting."); + + setupFirebaseAuth(); + + initImageLoader(); + setupBottomNavigationView(); + setupViewPager(); + + + } + + + + private void initImageLoader(){ + UniversalImageLoader universalImageLoader = new UniversalImageLoader(mContext); + ImageLoader.getInstance().init(universalImageLoader.getConfig()); + } + + /** + * Responsible for adding the 3 tabs: Camera, Home, Messages + */ + private void setupViewPager(){ + SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager()); + adapter.addFragment(new CameraFragment()); //index 0 + adapter.addFragment(new HomeFragment()); //index 1 + adapter.addFragment(new MessagesFragment()); //index 2 + ViewPager viewPager = (ViewPager) findViewById(R.id.container); + viewPager.setAdapter(adapter); + + TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); + tabLayout.setupWithViewPager(viewPager); + + tabLayout.getTabAt(0).setIcon(R.drawable.ic_camera); + tabLayout.getTabAt(1).setIcon(R.drawable.ic_action_name); + tabLayout.getTabAt(2).setIcon(R.drawable.ic_arrow); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } + + + /* + ------------------------------------ Firebase --------------------------------------------- + */ + + /** + * checks to see if the @param 'user' is logged in + * @param user + */ + private void checkCurrentUser(FirebaseUser user){ + Log.d(TAG, "checkCurrentUser: checking if user is logged in."); + + if(user == null){ + Intent intent = new Intent(mContext, LoginActivity.class); + startActivity(intent); + } + } + /** + * Setup the firebase auth object + */ + private void setupFirebaseAuth(){ + Log.d(TAG, "setupFirebaseAuth: setting up firebase auth."); + + mAuth = FirebaseAuth.getInstance(); + + mAuthListener = new FirebaseAuth.AuthStateListener() { + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + + //check if the user is logged in + checkCurrentUser(user); + + if (user != null) { + // User is signed in + Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); + } else { + // User is signed out + Log.d(TAG, "onAuthStateChanged:signed_out"); + } + // ... + } + }; + } + + @Override + public void onStart() { + super.onStart(); + mAuth.addAuthStateListener(mAuthListener); + checkCurrentUser(mAuth.getCurrentUser()); + } + + @Override + public void onStop() { + super.onStop(); + if (mAuthListener != null) { + mAuth.removeAuthStateListener(mAuthListener); + } + } + +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Home/HomeFragment.java b/app/src/main/java/tabian/com/instagramclone2/Home/HomeFragment.java new file mode 100644 index 0000000..0c2f6ff --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Home/HomeFragment.java @@ -0,0 +1,26 @@ +package tabian.com.instagramclone2.Home; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import tabian.com.instagramclone2.R; + +/** + * Created by User on 5/28/2017. + */ + +public class HomeFragment extends Fragment { + private static final String TAG = "HomeFragment"; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_home, container, false); + + return view; + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Home/MessagesFragment.java b/app/src/main/java/tabian/com/instagramclone2/Home/MessagesFragment.java new file mode 100644 index 0000000..5680cde --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Home/MessagesFragment.java @@ -0,0 +1,26 @@ +package tabian.com.instagramclone2.Home; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import tabian.com.instagramclone2.R; + +/** + * Created by User on 5/28/2017. + */ + +public class MessagesFragment extends Fragment { + private static final String TAG = "MessagesFragment"; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_messages, container, false); + + return view; + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Likes/LikesActivity.java b/app/src/main/java/tabian/com/instagramclone2/Likes/LikesActivity.java new file mode 100644 index 0000000..a6c723e --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Likes/LikesActivity.java @@ -0,0 +1,47 @@ +package tabian.com.instagramclone2.Likes; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone2.R; +import tabian.com.instagramclone2.Utils.BottomNavigationViewHelper; + +/** + * Created by User on 5/28/2017. + */ + +public class LikesActivity extends AppCompatActivity{ + private static final String TAG = "LikesActivity"; + private static final int ACTIVITY_NUM = 3; + + private Context mContext = LikesActivity.this; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: started."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Login/LoginActivity.java b/app/src/main/java/tabian/com/instagramclone2/Login/LoginActivity.java new file mode 100644 index 0000000..253a949 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Login/LoginActivity.java @@ -0,0 +1,222 @@ +package tabian.com.instagramclone2.Login; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.auth.AuthResult; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; + +import tabian.com.instagramclone2.Home.HomeActivity; +import tabian.com.instagramclone2.R; + +/** + * Created by User on 6/19/2017. + */ + +public class LoginActivity extends AppCompatActivity { + + private static final String TAG = "LoginActivity"; + + //firebase + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + + private Context mContext; + private ProgressBar mProgressBar; + private EditText mEmail, mPassword; + private TextView mPleaseWait; + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + mProgressBar = (ProgressBar) findViewById(R.id.progressBar); + mPleaseWait = (TextView) findViewById(R.id.pleaseWait); + mEmail = (EditText) findViewById(R.id.input_email); + mPassword = (EditText) findViewById(R.id.input_password); + mContext = LoginActivity.this; + Log.d(TAG, "onCreate: started."); + + mPleaseWait.setVisibility(View.GONE); + mProgressBar.setVisibility(View.GONE); + + setupFirebaseAuth(); + init(); + + } + + private boolean isStringNull(String string){ + Log.d(TAG, "isStringNull: checking string if null."); + + if(string.equals("")){ + return true; + } + else{ + return false; + } + } + + /* + ------------------------------------ Firebase --------------------------------------------- + */ + + private void init(){ + + //initialize the button for logging in + Button btnLogin = (Button) findViewById(R.id.btn_login); + btnLogin.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "onClick: attempting to log in."); + + String email = mEmail.getText().toString(); + String password = mPassword.getText().toString(); + + if(isStringNull(email) && isStringNull(password)){ + Toast.makeText(mContext, "You must fill out all the fields", Toast.LENGTH_SHORT).show(); + }else{ + mProgressBar.setVisibility(View.VISIBLE); + mPleaseWait.setVisibility(View.VISIBLE); + + mAuth.signInWithEmailAndPassword(email, password) + .addOnCompleteListener(LoginActivity.this, new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + Log.d(TAG, "signInWithEmail:onComplete:" + task.isSuccessful()); + FirebaseUser user = mAuth.getCurrentUser(); + + // If sign in fails, display a message to the user. If sign in succeeds + // the auth state listener will be notified and logic to handle the + // signed in user can be handled in the listener. + if (!task.isSuccessful()) { + Log.w(TAG, "signInWithEmail:failed", task.getException()); + + Toast.makeText(LoginActivity.this, getString(R.string.auth_failed), + Toast.LENGTH_SHORT).show(); + mProgressBar.setVisibility(View.GONE); + mPleaseWait.setVisibility(View.GONE); + } + else{ + try{ + if(user.isEmailVerified()){ + Log.d(TAG, "onComplete: success. email is verified."); + Intent intent = new Intent(LoginActivity.this, HomeActivity.class); + startActivity(intent); + }else{ + Toast.makeText(mContext, "Email is not verified \n check your email inbox.", Toast.LENGTH_SHORT).show(); + mProgressBar.setVisibility(View.GONE); + mPleaseWait.setVisibility(View.GONE); + mAuth.signOut(); + } + }catch (NullPointerException e){ + Log.e(TAG, "onComplete: NullPointerException: " + e.getMessage() ); + } + } + + // ... + } + }); + } + + } + }); + + TextView linkSignUp = (TextView) findViewById(R.id.link_signup); + linkSignUp.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "onClick: navigating to register screen"); + Intent intent = new Intent(LoginActivity.this, RegisterActivity.class); + startActivity(intent); + } + }); + + /* + If the user is logged in then navigate to HomeActivity and call 'finish()' + */ + if(mAuth.getCurrentUser() != null){ + Intent intent = new Intent(LoginActivity.this, HomeActivity.class); + startActivity(intent); + finish(); + } + } + + /** + * Setup the firebase auth object + */ + private void setupFirebaseAuth(){ + Log.d(TAG, "setupFirebaseAuth: setting up firebase auth."); + + mAuth = FirebaseAuth.getInstance(); + + mAuthListener = new FirebaseAuth.AuthStateListener() { + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + + if (user != null) { + // User is signed in + Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); + } else { + // User is signed out + Log.d(TAG, "onAuthStateChanged:signed_out"); + } + // ... + } + }; + } + + @Override + public void onStart() { + super.onStart(); + mAuth.addAuthStateListener(mAuthListener); + } + + @Override + public void onStop() { + super.onStop(); + if (mAuthListener != null) { + mAuth.removeAuthStateListener(mAuthListener); + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/tabian/com/instagramclone2/Login/RegisterActivity.java b/app/src/main/java/tabian/com/instagramclone2/Login/RegisterActivity.java new file mode 100644 index 0000000..778eb1a --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Login/RegisterActivity.java @@ -0,0 +1,190 @@ +package tabian.com.instagramclone2.Login; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ValueEventListener; + +import tabian.com.instagramclone2.R; +import tabian.com.instagramclone2.Utils.FirebaseMethods; + +/** + * Created by User on 6/19/2017. + */ + +public class RegisterActivity extends AppCompatActivity { + + private static final String TAG = "RegisterActivity"; + + private Context mContext; + private String email, username, password; + private EditText mEmail, mPassword, mUsername; + private TextView loadingPleaseWait; + private Button btnRegister; + private ProgressBar mProgressBar; + + //firebase + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + private FirebaseMethods firebaseMethods; + private FirebaseDatabase mFirebaseDatabase; + private DatabaseReference myRef; + + private String append = ""; + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_register); + mContext = RegisterActivity.this; + firebaseMethods = new FirebaseMethods(mContext); + Log.d(TAG, "onCreate: started."); + + initWidgets(); + setupFirebaseAuth(); + init(); + } + + private void init(){ + btnRegister.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + email = mEmail.getText().toString(); + username = mUsername.getText().toString(); + password = mPassword.getText().toString(); + + if(checkInputs(email, username, password)){ + mProgressBar.setVisibility(View.VISIBLE); + loadingPleaseWait.setVisibility(View.VISIBLE); + + firebaseMethods.registerNewEmail(email, password, username); + } + } + }); + } + + private boolean checkInputs(String email, String username, String password){ + Log.d(TAG, "checkInputs: checking inputs for null values."); + if(email.equals("") || username.equals("") || password.equals("")){ + Toast.makeText(mContext, "All fields must be filled out.", Toast.LENGTH_SHORT).show(); + return false; + } + return true; + } + /** + * Initialize the activity widgets + */ + private void initWidgets(){ + Log.d(TAG, "initWidgets: Initializing Widgets."); + mEmail = (EditText) findViewById(R.id.input_email); + mUsername = (EditText) findViewById(R.id.input_username); + btnRegister = (Button) findViewById(R.id.btn_register); + mProgressBar = (ProgressBar) findViewById(R.id.progressBar); + loadingPleaseWait = (TextView) findViewById(R.id.loadingPleaseWait); + mPassword = (EditText) findViewById(R.id.input_password); + mContext = RegisterActivity.this; + mProgressBar.setVisibility(View.GONE); + loadingPleaseWait.setVisibility(View.GONE); + + } + + private boolean isStringNull(String string){ + Log.d(TAG, "isStringNull: checking string if null."); + + if(string.equals("")){ + return true; + } + else{ + return false; + } + } + + /* + ------------------------------------ Firebase --------------------------------------------- + */ + + /** + * Setup the firebase auth object + */ + private void setupFirebaseAuth(){ + Log.d(TAG, "setupFirebaseAuth: setting up firebase auth."); + + mAuth = FirebaseAuth.getInstance(); + mFirebaseDatabase = FirebaseDatabase.getInstance(); + myRef = mFirebaseDatabase.getReference(); + + mAuthListener = new FirebaseAuth.AuthStateListener() { + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + + if (user != null) { + // User is signed in + Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); + + myRef.addListenerForSingleValueEvent(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + //1st check: Make sure the username is not already in use + if(firebaseMethods.checkIfUsernameExists(username, dataSnapshot)){ + append = myRef.push().getKey().substring(3,10); + Log.d(TAG, "onDataChange: username already exists. Appending random string to name: " + append); + } + username = username + append; + + //add new user to the database + firebaseMethods.addNewUser(email, username, "", "", ""); + + Toast.makeText(mContext, "Signup successful. Sending verification email.", Toast.LENGTH_SHORT).show(); + + mAuth.signOut(); + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + + finish(); + + } else { + // User is signed out + Log.d(TAG, "onAuthStateChanged:signed_out"); + } + // ... + } + }; + } + + @Override + public void onStart() { + super.onStart(); + mAuth.addAuthStateListener(mAuthListener); + } + + @Override + public void onStop() { + super.onStop(); + if (mAuthListener != null) { + mAuth.removeAuthStateListener(mAuthListener); + } + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Profile/AccountSettingsActivity.java b/app/src/main/java/tabian/com/instagramclone2/Profile/AccountSettingsActivity.java new file mode 100644 index 0000000..005337c --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Profile/AccountSettingsActivity.java @@ -0,0 +1,128 @@ +package tabian.com.instagramclone2.Profile; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.view.ViewPager; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.RelativeLayout; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import java.util.ArrayList; + +import tabian.com.instagramclone2.R; +import tabian.com.instagramclone2.Utils.BottomNavigationViewHelper; +import tabian.com.instagramclone2.Utils.SectionsStatePagerAdapter; + +/** + * Created by User on 6/4/2017. + */ + +public class AccountSettingsActivity extends AppCompatActivity { + + private static final String TAG = "AccountSettingsActivity"; + private static final int ACTIVITY_NUM = 4; + + private Context mContext; + + private SectionsStatePagerAdapter pagerAdapter; + private ViewPager mViewPager; + private RelativeLayout mRelativeLayout; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_accountsettings); + mContext = AccountSettingsActivity.this; + Log.d(TAG, "onCreate: started."); + mViewPager = (ViewPager) findViewById(R.id.container); + mRelativeLayout = (RelativeLayout) findViewById(R.id.relLayout1); + + setupSettingsList(); + setupBottomNavigationView(); + setupFragments(); + + //setup the backarrow for navigating back to "ProfileActivity" + ImageView backArrow = (ImageView) findViewById(R.id.backArrow); + backArrow.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "onClick: navigating back to 'ProfileActivity'"); + finish(); + } + }); + } + + private void setupFragments(){ + pagerAdapter = new SectionsStatePagerAdapter(getSupportFragmentManager()); + pagerAdapter.addFragment(new EditProfileFragment(), getString(R.string.edit_profile_fragment)); //fragment 0 + pagerAdapter.addFragment(new SignOutFragment(), getString(R.string.sign_out_fragment)); //fragment 1 + } + + private void setViewPager(int fragmentNumber){ + mRelativeLayout.setVisibility(View.GONE); + Log.d(TAG, "setViewPager: navigating to fragment #: " + fragmentNumber); + mViewPager.setAdapter(pagerAdapter); + mViewPager.setCurrentItem(fragmentNumber); + } + + private void setupSettingsList(){ + Log.d(TAG, "setupSettingsList: initializing 'Account Settings' list."); + ListView listView = (ListView) findViewById(R.id.lvAccountSettings); + + ArrayList options = new ArrayList<>(); + options.add(getString(R.string.edit_profile_fragment)); //fragment 0 + options.add(getString(R.string.sign_out_fragment)); //fragement 1 + + ArrayAdapter adapter = new ArrayAdapter(mContext, android.R.layout.simple_list_item_1, options); + listView.setAdapter(adapter); + + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Log.d(TAG, "onItemClick: navigating to fragment#: " + position); + setViewPager(position); + } + }); + + } + + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/tabian/com/instagramclone2/Profile/EditProfileFragment.java b/app/src/main/java/tabian/com/instagramclone2/Profile/EditProfileFragment.java new file mode 100644 index 0000000..06bc050 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Profile/EditProfileFragment.java @@ -0,0 +1,52 @@ +package tabian.com.instagramclone2.Profile; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import tabian.com.instagramclone2.R; +import tabian.com.instagramclone2.Utils.UniversalImageLoader; + +/** + * Created by User on 6/4/2017. + */ + +public class EditProfileFragment extends Fragment { + + private static final String TAG = "EditProfileFragment"; + + private ImageView mProfilePhoto; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_editprofile, container, false); + mProfilePhoto = (ImageView) view.findViewById(R.id.profile_photo); + + setProfileImage(); + + //back arrow for navigating back to "ProfileActivity" + ImageView backArrow = (ImageView) view.findViewById(R.id.backArrow); + backArrow.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "onClick: navigating back to ProfileActivity"); + getActivity().finish(); + } + }); + + return view; + } + + + private void setProfileImage(){ + Log.d(TAG, "setProfileImage: setting profile image."); + String imgURL = "www.androidcentral.com/sites/androidcentral.com/files/styles/xlarge/public/article_images/2016/08/ac-lloyd.jpg?itok=bb72IeLf"; + UniversalImageLoader.setImage(imgURL, mProfilePhoto, null, "https://"); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Profile/ProfileActivity.java b/app/src/main/java/tabian/com/instagramclone2/Profile/ProfileActivity.java new file mode 100644 index 0000000..f9fddfc --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Profile/ProfileActivity.java @@ -0,0 +1,130 @@ +package tabian.com.instagramclone2.Profile; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.ProgressBar; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import java.util.ArrayList; + +import tabian.com.instagramclone2.R; +import tabian.com.instagramclone2.Utils.BottomNavigationViewHelper; +import tabian.com.instagramclone2.Utils.GridImageAdapter; +import tabian.com.instagramclone2.Utils.UniversalImageLoader; + +/** + * Created by User on 5/28/2017. + */ + +public class ProfileActivity extends AppCompatActivity{ + private static final String TAG = "ProfileActivity"; + private static final int ACTIVITY_NUM = 4; + private static final int NUM_GRID_COLUMNS = 3; + + private Context mContext = ProfileActivity.this; + + private ProgressBar mProgressBar; + private ImageView profilePhoto; + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_profile); + Log.d(TAG, "onCreate: started."); + + + setupBottomNavigationView(); + setupToolbar(); + setupActivityWidgets(); + setProfileImage(); + + tempGridSetup(); + + } + + private void tempGridSetup(){ + ArrayList imgURLs = new ArrayList<>(); + imgURLs.add("https://pbs.twimg.com/profile_images/616076655547682816/6gMRtQyY.jpg"); + imgURLs.add("https://i.redd.it/9bf67ygj710z.jpg"); + imgURLs.add("https://c1.staticflickr.com/5/4276/34102458063_7be616b993_o.jpg"); + imgURLs.add("http://i.imgur.com/EwZRpvQ.jpg"); + imgURLs.add("http://i.imgur.com/JTb2pXP.jpg"); + imgURLs.add("https://i.redd.it/59kjlxxf720z.jpg"); + imgURLs.add("https://i.redd.it/pwduhknig00z.jpg"); + imgURLs.add("https://i.redd.it/clusqsm4oxzy.jpg"); + imgURLs.add("https://i.redd.it/svqvn7xs420z.jpg"); + imgURLs.add("http://i.imgur.com/j4AfH6P.jpg"); + imgURLs.add("https://i.redd.it/89cjkojkl10z.jpg"); + imgURLs.add("https://i.redd.it/aw7pv8jq4zzy.jpg"); + + setupImageGrid(imgURLs); + } + + private void setupImageGrid(ArrayList imgURLs){ + GridView gridView = (GridView) findViewById(R.id.gridView); + + int gridWidth = getResources().getDisplayMetrics().widthPixels; + int imageWidth = gridWidth/NUM_GRID_COLUMNS; + gridView.setColumnWidth(imageWidth); + + GridImageAdapter adapter = new GridImageAdapter(mContext, R.layout.layout_grid_imageview, "", imgURLs); + gridView.setAdapter(adapter); + } + + private void setProfileImage(){ + Log.d(TAG, "setProfileImage: setting profile photo."); + String imgURL = "www.androidcentral.com/sites/androidcentral.com/files/styles/xlarge/public/article_images/2016/08/ac-lloyd.jpg?itok=bb72IeLf"; + UniversalImageLoader.setImage(imgURL, profilePhoto, mProgressBar, "https://"); + } + + private void setupActivityWidgets(){ + mProgressBar = (ProgressBar) findViewById(R.id.profileProgressBar); + mProgressBar.setVisibility(View.GONE); + profilePhoto = (ImageView) findViewById(R.id.profile_photo); + + } + + /** + * Responsible for setting up the profile toolbar + */ + private void setupToolbar(){ + Toolbar toolbar = (Toolbar) findViewById(R.id.profileToolBar); + setSupportActionBar(toolbar); + + ImageView profileMenu = (ImageView) findViewById(R.id.profileMenu); + profileMenu.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "onClick: navigating to account settings."); + Intent intent = new Intent(mContext, AccountSettingsActivity.class); + startActivity(intent); + } + }); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } + +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Profile/SignOutFragment.java b/app/src/main/java/tabian/com/instagramclone2/Profile/SignOutFragment.java new file mode 100644 index 0000000..6ceb22d --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Profile/SignOutFragment.java @@ -0,0 +1,27 @@ +package tabian.com.instagramclone2.Profile; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import tabian.com.instagramclone2.R; + +/** + * Created by User on 6/4/2017. + */ + +public class SignOutFragment extends Fragment { + + private static final String TAG = "SignOutFragment"; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_signout, container, false); + + return view; + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Search/SearchActivity.java b/app/src/main/java/tabian/com/instagramclone2/Search/SearchActivity.java new file mode 100644 index 0000000..06d01b1 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Search/SearchActivity.java @@ -0,0 +1,47 @@ +package tabian.com.instagramclone2.Search; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone2.R; +import tabian.com.instagramclone2.Utils.BottomNavigationViewHelper; + +/** + * Created by User on 5/28/2017. + */ + +public class SearchActivity extends AppCompatActivity{ + private static final String TAG = "SearchActivity"; + private static final int ACTIVITY_NUM = 1; + + private Context mContext = SearchActivity.this; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: started."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Share/ShareActivity.java b/app/src/main/java/tabian/com/instagramclone2/Share/ShareActivity.java new file mode 100644 index 0000000..3cc9f67 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Share/ShareActivity.java @@ -0,0 +1,47 @@ +package tabian.com.instagramclone2.Share; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone2.R; +import tabian.com.instagramclone2.Utils.BottomNavigationViewHelper; + +/** + * Created by User on 5/28/2017. + */ + +public class ShareActivity extends AppCompatActivity{ + private static final String TAG = "ShareActivity"; + private static final int ACTIVITY_NUM = 2; + + private Context mContext = ShareActivity.this; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_home); + Log.d(TAG, "onCreate: started."); + + setupBottomNavigationView(); + } + + /** + * BottomNavigationView setup + */ + private void setupBottomNavigationView(){ + Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView"); + BottomNavigationViewEx bottomNavigationViewEx = (BottomNavigationViewEx) findViewById(R.id.bottomNavViewBar); + BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx); + BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx); + Menu menu = bottomNavigationViewEx.getMenu(); + MenuItem menuItem = menu.getItem(ACTIVITY_NUM); + menuItem.setChecked(true); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Utils/BottomNavigationViewHelper.java b/app/src/main/java/tabian/com/instagramclone2/Utils/BottomNavigationViewHelper.java new file mode 100644 index 0000000..92220f2 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Utils/BottomNavigationViewHelper.java @@ -0,0 +1,72 @@ +package tabian.com.instagramclone2.Utils; + +import android.content.Context; +import android.content.Intent; +import android.support.annotation.NonNull; +import android.support.design.widget.BottomNavigationView; +import android.util.Log; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx; + +import tabian.com.instagramclone2.Home.HomeActivity; +import tabian.com.instagramclone2.Likes.LikesActivity; +import tabian.com.instagramclone2.Profile.ProfileActivity; +import tabian.com.instagramclone2.R; +import tabian.com.instagramclone2.Search.SearchActivity; +import tabian.com.instagramclone2.Share.ShareActivity; + +/** + * Created by User on 5/28/2017. + */ + +public class BottomNavigationViewHelper { + + private static final String TAG = "BottomNavigationViewHel"; + + public static void setupBottomNavigationView(BottomNavigationViewEx bottomNavigationViewEx){ + Log.d(TAG, "setupBottomNavigationView: Setting up BottomNavigationView"); + bottomNavigationViewEx.enableAnimation(false); + bottomNavigationViewEx.enableItemShiftingMode(false); + bottomNavigationViewEx.enableShiftingMode(false); + bottomNavigationViewEx.setTextVisibility(false); + } + + public static void enableNavigation(final Context context, BottomNavigationViewEx view){ + view.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()){ + + case R.id.ic_house: + Intent intent1 = new Intent(context, HomeActivity.class);//ACTIVITY_NUM = 0 + context.startActivity(intent1); + break; + + case R.id.ic_search: + Intent intent2 = new Intent(context, SearchActivity.class);//ACTIVITY_NUM = 1 + context.startActivity(intent2); + break; + + case R.id.ic_circle: + Intent intent3 = new Intent(context, ShareActivity.class);//ACTIVITY_NUM = 2 + context.startActivity(intent3); + break; + + case R.id.ic_alert: + Intent intent4 = new Intent(context, LikesActivity.class);//ACTIVITY_NUM = 3 + context.startActivity(intent4); + break; + + case R.id.ic_android: + Intent intent5 = new Intent(context, ProfileActivity.class);//ACTIVITY_NUM = 4 + context.startActivity(intent5); + break; + } + + + return false; + } + }); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Utils/FirebaseMethods.java b/app/src/main/java/tabian/com/instagramclone2/Utils/FirebaseMethods.java new file mode 100644 index 0000000..5fe70f2 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Utils/FirebaseMethods.java @@ -0,0 +1,177 @@ +package tabian.com.instagramclone2.Utils; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.util.Log; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.auth.AuthResult; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; + +import tabian.com.instagramclone2.R; +import tabian.com.instagramclone2.models.User; +import tabian.com.instagramclone2.models.UserAccountSettings; + +/** + * Created by User on 6/26/2017. + */ + +public class FirebaseMethods { + + private static final String TAG = "FirebaseMethods"; + + //firebase + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + private FirebaseDatabase mFirebaseDatabase; + private DatabaseReference myRef; + private String userID; + + private Context mContext; + + public FirebaseMethods(Context context) { + mAuth = FirebaseAuth.getInstance(); + mFirebaseDatabase = FirebaseDatabase.getInstance(); + myRef = mFirebaseDatabase.getReference(); + mContext = context; + + if(mAuth.getCurrentUser() != null){ + userID = mAuth.getCurrentUser().getUid(); + } + } + + public boolean checkIfUsernameExists(String username, DataSnapshot datasnapshot){ + Log.d(TAG, "checkIfUsernameExists: checking if " + username + " already exists."); + + User user = new User(); + + for (DataSnapshot ds: datasnapshot.child(userID).getChildren()){ + Log.d(TAG, "checkIfUsernameExists: datasnapshot: " + ds); + + user.setUsername(ds.getValue(User.class).getUsername()); + Log.d(TAG, "checkIfUsernameExists: username: " + user.getUsername()); + + if(StringManipulation.expandUsername(user.getUsername()).equals(username)){ + Log.d(TAG, "checkIfUsernameExists: FOUND A MATCH: " + user.getUsername()); + return true; + } + } + return false; + } + + /** + * Register a new email and password to Firebase Authentication + * @param email + * @param password + * @param username + */ + public void registerNewEmail(final String email, String password, final String username){ + mAuth.createUserWithEmailAndPassword(email, password) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + Log.d(TAG, "createUserWithEmail:onComplete:" + task.isSuccessful()); + + // If sign in fails, display a message to the user. If sign in succeeds + // the auth state listener will be notified and logic to handle the + // signed in user can be handled in the listener. + if (!task.isSuccessful()) { + Toast.makeText(mContext, R.string.auth_failed, + Toast.LENGTH_SHORT).show(); + + } + else if(task.isSuccessful()){ + //send verificaton email + sendVerificationEmail(); + + userID = mAuth.getCurrentUser().getUid(); + Log.d(TAG, "onComplete: Authstate changed: " + userID); + } + + } + }); + } + + public void sendVerificationEmail(){ + FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); + + if(user != null){ + user.sendEmailVerification() + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if(task.isSuccessful()){ + + }else{ + Toast.makeText(mContext, "couldn't send verification email.", Toast.LENGTH_SHORT).show(); + } + } + }); + } + } + + /** + * Add information to the users nodes + * Add information to the user_account_settings node + * @param email + * @param username + * @param description + * @param website + * @param profile_photo + */ + public void addNewUser(String email, String username, String description, String website, String profile_photo){ + + User user = new User( userID, 1, email, StringManipulation.condenseUsername(username) ); + + myRef.child(mContext.getString(R.string.dbname_users)) + .child(userID) + .setValue(user); + + + UserAccountSettings settings = new UserAccountSettings( + description, + username, + 0, + 0, + 0, + profile_photo, + username, + website + ); + + myRef.child(mContext.getString(R.string.dbname_user_account_settings)) + .child(userID) + .setValue(settings); + + } + +} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/tabian/com/instagramclone2/Utils/GridImageAdapter.java b/app/src/main/java/tabian/com/instagramclone2/Utils/GridImageAdapter.java new file mode 100644 index 0000000..233c2f9 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Utils/GridImageAdapter.java @@ -0,0 +1,122 @@ +package tabian.com.instagramclone2.Utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ProgressBar; + +import com.nostra13.universalimageloader.core.ImageLoader; +import com.nostra13.universalimageloader.core.assist.FailReason; +import com.nostra13.universalimageloader.core.listener.ImageLoadingListener; + +import java.util.ArrayList; + +import tabian.com.instagramclone2.R; + +/** + * Created by User on 6/4/2017. + */ + +public class GridImageAdapter extends ArrayAdapter{ + + private Context mContext; + private LayoutInflater mInflater; + private int layoutResource; + private String mAppend; + private ArrayList imgURLs; + + public GridImageAdapter(Context context, int layoutResource, String append, ArrayList imgURLs) { + super(context, layoutResource, imgURLs); + mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + mContext = context; + this.layoutResource = layoutResource; + mAppend = append; + this.imgURLs = imgURLs; + } + + private static class ViewHolder{ + SqaureImageView image; + ProgressBar mProgressBar; + } + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + + /* + Viewholder build pattern (Similar to recyclerview) + */ + final ViewHolder holder; + if(convertView == null){ + convertView = mInflater.inflate(layoutResource, parent, false); + holder = new ViewHolder(); + holder.mProgressBar = (ProgressBar) convertView.findViewById(R.id.gridImageProgressbar); + holder.image = (SqaureImageView) convertView.findViewById(R.id.gridImageView); + + convertView.setTag(holder); + } + else{ + holder = (ViewHolder) convertView.getTag(); + } + + String imgURL = getItem(position); + + ImageLoader imageLoader = ImageLoader.getInstance(); + + imageLoader.displayImage(mAppend + imgURL, holder.image, new ImageLoadingListener() { + @Override + public void onLoadingStarted(String imageUri, View view) { + if(holder.mProgressBar != null){ + holder.mProgressBar.setVisibility(View.VISIBLE); + } + } + + @Override + public void onLoadingFailed(String imageUri, View view, FailReason failReason) { + if(holder.mProgressBar != null){ + holder.mProgressBar.setVisibility(View.GONE); + } + } + + @Override + public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { + if(holder.mProgressBar != null){ + holder.mProgressBar.setVisibility(View.GONE); + } + } + + @Override + public void onLoadingCancelled(String imageUri, View view) { + if(holder.mProgressBar != null){ + holder.mProgressBar.setVisibility(View.GONE); + } + } + }); + + return convertView; + } +} + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/tabian/com/instagramclone2/Utils/SectionsPagerAdapter.java b/app/src/main/java/tabian/com/instagramclone2/Utils/SectionsPagerAdapter.java new file mode 100644 index 0000000..ae89aeb --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Utils/SectionsPagerAdapter.java @@ -0,0 +1,43 @@ +package tabian.com.instagramclone2.Utils; + +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by User on 5/28/2017. + */ + +/** + * Class that stores fragments for tabs + */ +public class SectionsPagerAdapter extends FragmentPagerAdapter { + + private static final String TAG = "SectionsPagerAdapter"; + + private final List mFragmentList = new ArrayList<>(); + + + public SectionsPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + return mFragmentList.get(position); + } + + + @Override + public int getCount() { + return mFragmentList.size(); + } + + public void addFragment(Fragment fragment){ + mFragmentList.add(fragment); + } + +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Utils/SectionsStatePagerAdapter.java b/app/src/main/java/tabian/com/instagramclone2/Utils/SectionsStatePagerAdapter.java new file mode 100644 index 0000000..6fddfc1 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Utils/SectionsStatePagerAdapter.java @@ -0,0 +1,102 @@ +package tabian.com.instagramclone2.Utils; + +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Created by User on 6/4/2017. + */ + +public class SectionsStatePagerAdapter extends FragmentStatePagerAdapter { + + private final List mFragmentList = new ArrayList<>(); + private final HashMap mFragments = new HashMap<>(); + private final HashMap mFragmentNumbers = new HashMap<>(); + private final HashMap mFragmentNames = new HashMap<>(); + + public SectionsStatePagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + return mFragmentList.get(position); + } + + @Override + public int getCount() { + return mFragmentList.size(); + } + + public void addFragment(Fragment fragment, String fragmentName){ + mFragmentList.add(fragment); + mFragments.put(fragment, mFragmentList.size()-1); + mFragmentNumbers.put(fragmentName, mFragmentList.size()-1); + mFragmentNames.put(mFragmentList.size()-1, fragmentName); + } + + /** + * returns the fragment with the name @param + * @param fragmentName + * @return + */ + public Integer getFragmentNumber(String fragmentName){ + if(mFragmentNumbers.containsKey(fragmentName)){ + return mFragmentNumbers.get(fragmentName); + }else{ + return null; + } + } + + + /** + * returns the fragment with the name @param + * @param fragment + * @return + */ + public Integer getFragmentNumber(Fragment fragment){ + if(mFragmentNumbers.containsKey(fragment)){ + return mFragmentNumbers.get(fragment); + }else{ + return null; + } + } + + /** + * returns the fragment with the name @param + * @param fragmentNumber + * @return + */ + public String getFragmentName(Integer fragmentNumber){ + if(mFragmentNames.containsKey(fragmentNumber)){ + return mFragmentNames.get(fragmentNumber); + }else{ + return null; + } + } +} + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/tabian/com/instagramclone2/Utils/SqaureImageView.java b/app/src/main/java/tabian/com/instagramclone2/Utils/SqaureImageView.java new file mode 100644 index 0000000..3ee0d21 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Utils/SqaureImageView.java @@ -0,0 +1,29 @@ +package tabian.com.instagramclone2.Utils; + +import android.content.Context; +import android.support.v7.widget.AppCompatImageView; +import android.util.AttributeSet; + +/** + * Created by User on 6/4/2017. + */ + +public class SqaureImageView extends AppCompatImageView { + + public SqaureImageView(Context context) { + super(context); + } + + public SqaureImageView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SqaureImageView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, widthMeasureSpec); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Utils/StringManipulation.java b/app/src/main/java/tabian/com/instagramclone2/Utils/StringManipulation.java new file mode 100644 index 0000000..0944b17 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Utils/StringManipulation.java @@ -0,0 +1,16 @@ +package tabian.com.instagramclone2.Utils; + +/** + * Created by User on 6/26/2017. + */ + +public class StringManipulation { + + public static String expandUsername(String username){ + return username.replace(".", " "); + } + + public static String condenseUsername(String username){ + return username.replace(" " , "."); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/Utils/UniversalImageLoader.java b/app/src/main/java/tabian/com/instagramclone2/Utils/UniversalImageLoader.java new file mode 100644 index 0000000..5f6f0e9 --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/Utils/UniversalImageLoader.java @@ -0,0 +1,93 @@ +package tabian.com.instagramclone2.Utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.view.View; +import android.widget.ImageView; +import android.widget.ProgressBar; + +import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache; +import com.nostra13.universalimageloader.core.DisplayImageOptions; +import com.nostra13.universalimageloader.core.ImageLoader; +import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; +import com.nostra13.universalimageloader.core.assist.FailReason; +import com.nostra13.universalimageloader.core.assist.ImageScaleType; +import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer; +import com.nostra13.universalimageloader.core.listener.ImageLoadingListener; + +import tabian.com.instagramclone2.R; + +/** + * Created by User on 6/4/2017. + */ + +public class UniversalImageLoader { + + private static final int defaultImage = R.drawable.ic_android; + private Context mContext; + + public UniversalImageLoader(Context context) { + mContext = context; + } + + public ImageLoaderConfiguration getConfig(){ + DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder() + .showImageOnLoading(defaultImage) + .showImageForEmptyUri(defaultImage) + .showImageOnFail(defaultImage) + .cacheOnDisk(true).cacheInMemory(true) + .cacheOnDisk(true).resetViewBeforeLoading(true) + .imageScaleType(ImageScaleType.EXACTLY) + .displayer(new FadeInBitmapDisplayer(300)).build(); + + ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(mContext) + .defaultDisplayImageOptions(defaultOptions) + .memoryCache(new WeakMemoryCache()) + .diskCacheSize(100 * 1024 * 1024).build(); + + return configuration; + } + + /** + * this method can be sued to set images that are static. It can't be used if the images + * are being changed in the Fragment/Activity - OR if they are being set in a list or + * a grid + * @param imgURL + * @param image + * @param mProgressBar + * @param append + */ + public static void setImage(String imgURL, ImageView image, final ProgressBar mProgressBar, String append){ + + ImageLoader imageLoader = ImageLoader.getInstance(); + imageLoader.displayImage(append + imgURL, image, new ImageLoadingListener() { + @Override + public void onLoadingStarted(String imageUri, View view) { + if(mProgressBar != null){ + mProgressBar.setVisibility(View.VISIBLE); + } + } + + @Override + public void onLoadingFailed(String imageUri, View view, FailReason failReason) { + if(mProgressBar != null){ + mProgressBar.setVisibility(View.GONE); + } + } + + @Override + public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { + if(mProgressBar != null){ + mProgressBar.setVisibility(View.GONE); + } + } + + @Override + public void onLoadingCancelled(String imageUri, View view) { + if(mProgressBar != null){ + mProgressBar.setVisibility(View.GONE); + } + } + }); + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/models/User.java b/app/src/main/java/tabian/com/instagramclone2/models/User.java new file mode 100644 index 0000000..c1d7c5f --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/models/User.java @@ -0,0 +1,68 @@ +package tabian.com.instagramclone2.models; + +/** + * Created by User on 6/26/2017. + */ + +public class User { + + private String user_id; + private long phone_number; + private String email; + private String username; + + public User(String user_id, long phone_number, String email, String username) { + this.user_id = user_id; + this.phone_number = phone_number; + this.email = email; + this.username = username; + } + + public User() { + + } + + + public String getUser_id() { + return user_id; + } + + public void setUser_id(String user_id) { + this.user_id = user_id; + } + + public long getPhone_number() { + return phone_number; + } + + public void setPhone_number(long phone_number) { + this.phone_number = phone_number; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + + @Override + public String toString() { + return "User{" + + "user_id='" + user_id + '\'' + + ", phone_number='" + phone_number + '\'' + + ", email='" + email + '\'' + + ", username='" + username + '\'' + + '}'; + } +} diff --git a/app/src/main/java/tabian/com/instagramclone2/models/UserAccountSettings.java b/app/src/main/java/tabian/com/instagramclone2/models/UserAccountSettings.java new file mode 100644 index 0000000..365414a --- /dev/null +++ b/app/src/main/java/tabian/com/instagramclone2/models/UserAccountSettings.java @@ -0,0 +1,111 @@ +package tabian.com.instagramclone2.models; + +/** + * Created by User on 6/29/2017. + */ + +public class UserAccountSettings { + + private String description; + private String display_name; + private long followers; + private long following; + private long posts; + private String profile_photo; + private String username; + private String website; + + public UserAccountSettings(String description, String display_name, long followers, long following, + long posts, String profile_photo, String username, String website) { + this.description = description; + this.display_name = display_name; + this.followers = followers; + this.following = following; + this.posts = posts; + this.profile_photo = profile_photo; + this.username = username; + this.website = website; + } + public UserAccountSettings() { + + } + + public String getDescription() { + return description; + } + + public void setDscription(String description) { + this.description = description; + } + + public String getDisplay_name() { + return display_name; + } + + public void setDisplay_name(String display_name) { + this.display_name = display_name; + } + + public long getFollowers() { + return followers; + } + + public void setFollowers(long followers) { + this.followers = followers; + } + + public long getFollowing() { + return following; + } + + public void setFollowing(long following) { + this.following = following; + } + + public long getPosts() { + return posts; + } + + public void setPosts(long posts) { + this.posts = posts; + } + + public String getProfile_photo() { + return profile_photo; + } + + public void setProfile_photo(String profile_photo) { + this.profile_photo = profile_photo; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getWebsite() { + return website; + } + + public void setWebsite(String website) { + this.website = website; + } + + + @Override + public String toString() { + return "UserAccountSettings{" + + "description='" + description + '\'' + + ", display_name='" + display_name + '\'' + + ", followers=" + followers + + ", following=" + following + + ", posts=" + posts + + ", profile_photo='" + profile_photo + '\'' + + ", username='" + username + '\'' + + ", website='" + website + '\'' + + '}'; + } +} diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index ad7a57d..f73dddc 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -5,7 +5,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="tabian.com.instagramclone.Home.HomeActivity"> + tools:context="tabian.com.instagramclone2.Home.HomeActivity"> - Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file From e6de4d2169756396a20265a305540c534d234f32 Mon Sep 17 00:00:00 2001 From: Mitch Date: Thu, 29 Jun 2017 21:55:54 -0700 Subject: [PATCH 036/122] part28 -Enable User Signout --- .../Profile/SignOutFragment.java | 89 +++++++++++++++++++ app/src/main/res/layout/fragment_signout.xml | 50 ++++++++++- 2 files changed, 136 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/tabian/com/instagramclone2/Profile/SignOutFragment.java b/app/src/main/java/tabian/com/instagramclone2/Profile/SignOutFragment.java index 6ceb22d..d6de008 100644 --- a/app/src/main/java/tabian/com/instagramclone2/Profile/SignOutFragment.java +++ b/app/src/main/java/tabian/com/instagramclone2/Profile/SignOutFragment.java @@ -1,12 +1,24 @@ package tabian.com.instagramclone2.Profile; +import android.content.Intent; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ProgressBar; +import android.widget.TextView; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; + +import java.net.Inet4Address; + +import tabian.com.instagramclone2.Login.LoginActivity; import tabian.com.instagramclone2.R; /** @@ -17,11 +29,88 @@ public class SignOutFragment extends Fragment { private static final String TAG = "SignOutFragment"; + //firebase + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + + private ProgressBar mProgressBar; + private TextView tvSignout, tvSigningOut; + @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_signout, container, false); + tvSignout = (TextView) view.findViewById(R.id.tvConfirmSignout); + mProgressBar = (ProgressBar) view.findViewById(R.id.progressBar); + tvSigningOut = (TextView) view.findViewById(R.id.tvSigningOut); + Button btnConfirmSignout = (Button) view.findViewById(R.id.btnConfirmSignout); + + mProgressBar.setVisibility(View.GONE); + tvSigningOut.setVisibility(View.GONE); + + setupFirebaseAuth(); + + btnConfirmSignout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "onClick: attempting to sign out."); + mProgressBar.setVisibility(View.VISIBLE); + tvSigningOut.setVisibility(View.VISIBLE); + + mAuth.signOut(); + getActivity().finish(); + } + }); return view; } + + /* + ------------------------------------ Firebase --------------------------------------------- + */ + + + /** + * Setup the firebase auth object + */ + private void setupFirebaseAuth(){ + Log.d(TAG, "setupFirebaseAuth: setting up firebase auth."); + + mAuth = FirebaseAuth.getInstance(); + + mAuthListener = new FirebaseAuth.AuthStateListener() { + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + + if (user != null) { + // User is signed in + Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); + } else { + // User is signed out + Log.d(TAG, "onAuthStateChanged:signed_out"); + + Log.d(TAG, "onAuthStateChanged: navigating back to login screen."); + Intent intent = new Intent(getActivity(), LoginActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(intent); + } + // ... + } + }; + } + + @Override + public void onStart() { + super.onStart(); + mAuth.addAuthStateListener(mAuthListener); + } + + @Override + public void onStop() { + super.onStop(); + if (mAuthListener != null) { + mAuth.removeAuthStateListener(mAuthListener); + } + } } diff --git a/app/src/main/res/layout/fragment_signout.xml b/app/src/main/res/layout/fragment_signout.xml index fb3d8a2..0c9ba4b 100644 --- a/app/src/main/res/layout/fragment_signout.xml +++ b/app/src/main/res/layout/fragment_signout.xml @@ -1,7 +1,51 @@ - - \ No newline at end of file + + + + +
      +
    1. Getting Started
    2. + +
    3. Toolbars and NavigationView
    4. + +
    5. Customizing the BottomNavigationView
    6. + +
    7. BottomNavigationView Activities
    8. + +
    9. Organizing Things and Tab-Prep
    10. + +
    11. SectionsPagerAdapter (Home Screen Tabs)
    12. + +