Permalink
Please sign in to comment.
Browse files
Initial commit of FirebaseArray and FirebaseListAdapter
FirebaseRecyclerView.Adapter is also in here, but not really done yet
Showing
with
1,256 additions
and 0 deletions.
- +6 −0 .gitignore
- +19 −0 FirebaseUI-Android.iml
- +1 −0 app/.gitignore
- +96 −0 app/app.iml
- +25 −0 app/build.gradle
- +17 −0 app/proguard-rules.pro
- +13 −0 app/src/androidTest/java/com/firebase/firebaseui_android/ApplicationTest.java
- +9 −0 app/src/main/AndroidManifest.xml
- BIN app/src/main/res/mipmap-hdpi/ic_launcher.png
- BIN app/src/main/res/mipmap-mdpi/ic_launcher.png
- BIN app/src/main/res/mipmap-xhdpi/ic_launcher.png
- BIN app/src/main/res/mipmap-xxhdpi/ic_launcher.png
- +3 −0 app/src/main/res/values/strings.xml
- +8 −0 app/src/main/res/values/styles.xml
- +19 −0 build.gradle
- +18 −0 gradle.properties
- BIN gradle/wrapper/gradle-wrapper.jar
- +6 −0 gradle/wrapper/gradle-wrapper.properties
- +164 −0 gradlew
- +90 −0 gradlew.bat
- +1 −0 library/.gitignore
- +32 −0 library/build.gradle
- +106 −0 library/library.iml
- +17 −0 library/proguard-rules.pro
- +13 −0 library/src/androidTest/java/com/firebase/ui/ApplicationTest.java
- +177 −0 library/src/androidTest/java/com/firebase/ui/FirebaseArrayOfObjectsTest.java
- +149 −0 library/src/androidTest/java/com/firebase/ui/FirebaseArrayTest.java
- +7 −0 library/src/main/AndroidManifest.xml
- +90 −0 library/src/main/java/com/firebase/ui/FirebaseArray.java
- +91 −0 library/src/main/java/com/firebase/ui/FirebaseListAdapter.java
- +75 −0 library/src/main/java/com/firebase/ui/FirebaseRecyclerViewAdapter.java
- +3 −0 library/src/main/res/values/strings.xml
- +1 −0 settings.gradle
6
.gitignore
@@ -0,0 +1,6 @@ | ||
+.gradle | ||
+/local.properties | ||
+.idea | ||
+.DS_Store | ||
+/build | ||
+/captures |
19
FirebaseUI-Android.iml
@@ -0,0 +1,19 @@ | ||
+<?xml version="1.0" encoding="UTF-8"?> | ||
+<module external.linked.project.id="FirebaseUI-Android" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> | ||
+ <component name="FacetManager"> | ||
+ <facet type="java-gradle" name="Java-Gradle"> | ||
+ <configuration> | ||
+ <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" /> | ||
+ <option name="BUILDABLE" value="false" /> | ||
+ </configuration> | ||
+ </facet> | ||
+ </component> | ||
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true"> | ||
+ <exclude-output /> | ||
+ <content url="file://$MODULE_DIR$"> | ||
+ <excludeFolder url="file://$MODULE_DIR$/.gradle" /> | ||
+ </content> | ||
+ <orderEntry type="inheritedJdk" /> | ||
+ <orderEntry type="sourceFolder" forTests="false" /> | ||
+ </component> | ||
+</module> |
1
app/.gitignore
@@ -0,0 +1 @@ | ||
+/build |
96
app/app.iml
@@ -0,0 +1,96 @@ | ||
+<?xml version="1.0" encoding="UTF-8"?> | ||
+<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="FirebaseUI-Android" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> | ||
+ <component name="FacetManager"> | ||
+ <facet type="android-gradle" name="Android-Gradle"> | ||
+ <configuration> | ||
+ <option name="GRADLE_PROJECT_PATH" value=":app" /> | ||
+ </configuration> | ||
+ </facet> | ||
+ <facet type="android" name="Android"> | ||
+ <configuration> | ||
+ <option name="SELECTED_BUILD_VARIANT" value="debug" /> | ||
+ <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" /> | ||
+ <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> | ||
+ <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" /> | ||
+ <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" /> | ||
+ <option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" /> | ||
+ <afterSyncTasks> | ||
+ <task>generateDebugAndroidTestSources</task> | ||
+ <task>generateDebugSources</task> | ||
+ </afterSyncTasks> | ||
+ <option name="ALLOW_USER_CONFIGURATION" value="false" /> | ||
+ <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> | ||
+ <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> | ||
+ <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" /> | ||
+ <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" /> | ||
+ </configuration> | ||
+ </facet> | ||
+ </component> | ||
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false"> | ||
+ <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" /> | ||
+ <output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" /> | ||
+ <exclude-output /> | ||
+ <content url="file://$MODULE_DIR$"> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.2.0/jars" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.2.0/jars" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/outputs" /> | ||
+ </content> | ||
+ <orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" /> | ||
+ <orderEntry type="sourceFolder" forTests="false" /> | ||
+ <orderEntry type="library" exported="" name="support-v4-22.2.0" level="project" /> | ||
+ <orderEntry type="library" exported="" name="support-annotations-22.2.0" level="project" /> | ||
+ <orderEntry type="library" exported="" name="appcompat-v7-22.2.0" level="project" /> | ||
+ </component> | ||
+</module> |
25
app/build.gradle
@@ -0,0 +1,25 @@ | ||
+apply plugin: 'com.android.application' | ||
+ | ||
+android { | ||
+ compileSdkVersion 22 | ||
+ buildToolsVersion "23.0.0 rc2" | ||
+ | ||
+ defaultConfig { | ||
+ applicationId "com.firebase.firebaseui_android" | ||
+ minSdkVersion 10 | ||
+ targetSdkVersion 22 | ||
+ versionCode 1 | ||
+ versionName "1.0" | ||
+ } | ||
+ buildTypes { | ||
+ release { | ||
+ minifyEnabled false | ||
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||
+ } | ||
+ } | ||
+} | ||
+ | ||
+dependencies { | ||
+ compile fileTree(dir: 'libs', include: ['*.jar']) | ||
+ compile 'com.android.support:appcompat-v7:22.2.0' | ||
+} |
17
app/proguard-rules.pro
@@ -0,0 +1,17 @@ | ||
+# Add project specific ProGuard rules here. | ||
+# By default, the flags in this file are appended to flags specified | ||
+# in /Users/puf/Library/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 *; | ||
+#} |
13
app/src/androidTest/java/com/firebase/firebaseui_android/ApplicationTest.java
@@ -0,0 +1,13 @@ | ||
+package com.firebase.firebaseui_android; | ||
+ | ||
+import android.app.Application; | ||
+import android.test.ApplicationTestCase; | ||
+ | ||
+/** | ||
+ * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a> | ||
+ */ | ||
+public class ApplicationTest extends ApplicationTestCase<Application> { | ||
+ public ApplicationTest() { | ||
+ super(Application.class); | ||
+ } | ||
+} |
9
app/src/main/AndroidManifest.xml
@@ -0,0 +1,9 @@ | ||
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
+ package="com.firebase.firebaseui_android"> | ||
+ | ||
+ <application android:allowBackup="true" android:label="@string/app_name" | ||
+ android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme"> | ||
+ | ||
+ </application> | ||
+ | ||
+</manifest> |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3
app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@ | ||
+<resources> | ||
+ <string name="app_name">FirebaseUI-Android</string> | ||
+</resources> |
8
app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@ | ||
+<resources> | ||
+ | ||
+ <!-- Base application theme. --> | ||
+ <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> | ||
+ <!-- Customize your theme here. --> | ||
+ </style> | ||
+ | ||
+</resources> |
19
build.gradle
@@ -0,0 +1,19 @@ | ||
+// 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:1.2.3' | ||
+ | ||
+ // NOTE: Do not place your application dependencies here; they belong | ||
+ // in the individual module build.gradle files | ||
+ } | ||
+} | ||
+ | ||
+allprojects { | ||
+ repositories { | ||
+ jcenter() | ||
+ } | ||
+} |
18
gradle.properties
@@ -0,0 +1,18 @@ | ||
+# 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. | ||
+# Default value: -Xmx10248m -XX:MaxPermSize=256m | ||
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 | ||
+ | ||
+# 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 |
BIN
gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@ | ||
+#Mon Jul 13 17:23:05 PDT 2015 | ||
+distributionBase=GRADLE_USER_HOME | ||
+distributionPath=wrapper/dists | ||
+zipStoreBase=GRADLE_USER_HOME | ||
+zipStorePath=wrapper/dists | ||
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip |
164
gradlew
@@ -0,0 +1,164 @@ | ||
+#!/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 | ||
+ | ||
+# For Cygwin, ensure paths are in UNIX format before anything is touched. | ||
+if $cygwin ; then | ||
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` | ||
+fi | ||
+ | ||
+# 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\"`/" >&- | ||
+APP_HOME="`pwd -P`" | ||
+cd "$SAVED" >&- | ||
+ | ||
+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"` | ||
+ | ||
+ # 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 "$@" |
90
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 |
1
library/.gitignore
@@ -0,0 +1 @@ | ||
+/build |
32
library/build.gradle
@@ -0,0 +1,32 @@ | ||
+apply plugin: 'com.android.library' | ||
+ | ||
+android { | ||
+ compileSdkVersion 22 | ||
+ buildToolsVersion "23.0.0 rc2" | ||
+ | ||
+ defaultConfig { | ||
+ minSdkVersion 10 | ||
+ targetSdkVersion 22 | ||
+ versionCode 1 | ||
+ versionName "1.0" | ||
+ } | ||
+ buildTypes { | ||
+ release { | ||
+ minifyEnabled false | ||
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||
+ } | ||
+ } | ||
+ packagingOptions { | ||
+ exclude 'META-INF/LICENSE' | ||
+ exclude 'META-INF/LICENSE-FIREBASE.txt' | ||
+ exclude 'META-INF/NOTICE' | ||
+ } | ||
+} | ||
+ | ||
+dependencies { | ||
+ compile fileTree(dir: 'libs', include: ['*.jar']) | ||
+ compile 'com.android.support:appcompat-v7:22.2.0' | ||
+ compile 'com.firebase:firebase-client-android:2.3.1' | ||
+ compile 'com.android.support:recyclerview-v7:22.2.0' | ||
+ androidTestCompile 'junit:junit:4.12' | ||
+} |
106
library/library.iml
@@ -0,0 +1,106 @@ | ||
+<?xml version="1.0" encoding="UTF-8"?> | ||
+<module external.linked.project.id=":library" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="FirebaseUI-Android" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> | ||
+ <component name="FacetManager"> | ||
+ <facet type="android-gradle" name="Android-Gradle"> | ||
+ <configuration> | ||
+ <option name="GRADLE_PROJECT_PATH" value=":library" /> | ||
+ </configuration> | ||
+ </facet> | ||
+ <facet type="android" name="Android"> | ||
+ <configuration> | ||
+ <option name="SELECTED_BUILD_VARIANT" value="debug" /> | ||
+ <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" /> | ||
+ <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> | ||
+ <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" /> | ||
+ <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" /> | ||
+ <option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" /> | ||
+ <afterSyncTasks> | ||
+ <task>generateDebugAndroidTestSources</task> | ||
+ <task>generateDebugSources</task> | ||
+ </afterSyncTasks> | ||
+ <option name="ALLOW_USER_CONFIGURATION" value="false" /> | ||
+ <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> | ||
+ <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> | ||
+ <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" /> | ||
+ <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" /> | ||
+ <option name="LIBRARY_PROJECT" value="true" /> | ||
+ </configuration> | ||
+ </facet> | ||
+ </component> | ||
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false"> | ||
+ <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" /> | ||
+ <output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" /> | ||
+ <exclude-output /> | ||
+ <content url="file://$MODULE_DIR$"> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" /> | ||
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/22.2.0/jars" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/outputs" /> | ||
+ <excludeFolder url="file://$MODULE_DIR$/build/tmp" /> | ||
+ </content> | ||
+ <orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" /> | ||
+ <orderEntry type="sourceFolder" forTests="false" /> | ||
+ <orderEntry type="library" exported="" name="jackson-core-2.2.2" level="project" /> | ||
+ <orderEntry type="library" exported="" name="jackson-databind-2.2.2" level="project" /> | ||
+ <orderEntry type="library" exported="" name="firebase-client-jvm-2.3.1" level="project" /> | ||
+ <orderEntry type="library" exported="" name="support-v4-22.2.0" level="project" /> | ||
+ <orderEntry type="library" exported="" name="support-annotations-22.2.0" level="project" /> | ||
+ <orderEntry type="library" exported="" name="tubesock-0.0.11" level="project" /> | ||
+ <orderEntry type="library" exported="" name="recyclerview-v7-22.2.0" level="project" /> | ||
+ <orderEntry type="library" exported="" name="jackson-annotations-2.2.2" level="project" /> | ||
+ <orderEntry type="library" exported="" name="firebase-client-android-2.3.1" level="project" /> | ||
+ <orderEntry type="library" exported="" name="appcompat-v7-22.2.0" level="project" /> | ||
+ <orderEntry type="library" exported="" scope="TEST" name="hamcrest-core-1.3" level="project" /> | ||
+ <orderEntry type="library" exported="" scope="TEST" name="junit-4.12" level="project" /> | ||
+ </component> | ||
+</module> |
17
library/proguard-rules.pro
@@ -0,0 +1,17 @@ | ||
+# Add project specific ProGuard rules here. | ||
+# By default, the flags in this file are appended to flags specified | ||
+# in /Users/puf/Library/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 *; | ||
+#} |
13
library/src/androidTest/java/com/firebase/ui/ApplicationTest.java
@@ -0,0 +1,13 @@ | ||
+package com.firebase.ui; | ||
+ | ||
+import android.app.Application; | ||
+import android.test.ApplicationTestCase; | ||
+ | ||
+/** | ||
+ * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a> | ||
+ */ | ||
+public class ApplicationTest extends ApplicationTestCase<Application> { | ||
+ public ApplicationTest() { | ||
+ super(Application.class); | ||
+ } | ||
+} |
177
library/src/androidTest/java/com/firebase/ui/FirebaseArrayOfObjectsTest.java
@@ -0,0 +1,177 @@ | ||
+package com.firebase.ui; | ||
+ | ||
+import android.test.AndroidTestCase; | ||
+ | ||
+import com.firebase.client.Firebase; | ||
+ | ||
+import junit.framework.AssertionFailedError; | ||
+ | ||
+import org.junit.After; | ||
+import org.junit.Before; | ||
+import org.junit.Test; | ||
+ | ||
+import java.util.concurrent.Callable; | ||
+import java.util.concurrent.TimeUnit; | ||
+ | ||
+public class FirebaseArrayOfObjectsTest extends AndroidTestCase { | ||
+ public static class Bean { | ||
+ int number; | ||
+ String text; | ||
+ boolean bool; | ||
+ | ||
+ public Bean() { | ||
+ // necessary for Jackson | ||
+ } | ||
+ | ||
+ public Bean(int number, String text, boolean bool) { | ||
+ this.number = number; | ||
+ this.text = text; | ||
+ this.bool = bool; | ||
+ } | ||
+ public Bean(int index) { | ||
+ this(index, "Text "+index, index % 2 == 0); | ||
+ } | ||
+ | ||
+ public int getNumber() { | ||
+ return number; | ||
+ } | ||
+ | ||
+ public String getText() { | ||
+ return text; | ||
+ } | ||
+ | ||
+ public boolean isBool() { | ||
+ return bool; | ||
+ } | ||
+ } | ||
+ | ||
+ private Firebase mRef; | ||
+ private FirebaseArray mArray; | ||
+ | ||
+ @Before | ||
+ public void setUp() throws Exception { | ||
+ Firebase.setAndroidContext(this.getContext()); | ||
+ | ||
+ mRef = new Firebase("https://firebaseui-tests.firebaseio-demo.com/firebasearray/objects"); | ||
+ mArray = new FirebaseArray(mRef); | ||
+ mRef.removeValue(); | ||
+ runAndWaitUntil(mArray, mRef, new Runnable() { | ||
+ @Override | ||
+ public void run() { | ||
+ for (int i = 1; i <= 3; i++) { | ||
+ mRef.push().setValue(new Bean(i, "Text " + i, i % 2 == 0 ? true : false), i); | ||
+ } | ||
+ } | ||
+ }, new Callable<Boolean>() { | ||
+ @Override | ||
+ public Boolean call() throws Exception { | ||
+ return mArray.getCount() == 3; | ||
+ } | ||
+ } | ||
+ ); | ||
+ } | ||
+ | ||
+ @After | ||
+ public void tearDown() throws Exception { | ||
+ mRef.removeValue(); | ||
+ mArray.cleanup(); | ||
+ } | ||
+ | ||
+ @Test | ||
+ public void testSize() throws Exception { | ||
+ assertEquals(3, mArray.getCount()); | ||
+ } | ||
+ | ||
+ @Test | ||
+ public void testPushIncreasesSize() throws Exception { | ||
+ assertEquals(3, mArray.getCount()); | ||
+ runAndWaitUntil(mArray, mRef, new Runnable() { | ||
+ public void run() { | ||
+ mRef.push().setValue(new Bean(4)); | ||
+ } | ||
+ }, new Callable<Boolean>() { | ||
+ @Override | ||
+ public Boolean call() throws Exception { | ||
+ return mArray.getCount() == 4; | ||
+ } | ||
+ }); | ||
+ } | ||
+ @Test | ||
+ public void testPushAppends() throws Exception { | ||
+ runAndWaitUntil(mArray, mRef, new Runnable() { | ||
+ public void run() { | ||
+ mRef.push().setValue(new Bean(4), 4); | ||
+ } | ||
+ }, new Callable<Boolean>() { | ||
+ @Override | ||
+ public Boolean call() throws Exception { | ||
+ return mArray.getItem(3).getValue(Bean.class).getNumber() == 4; | ||
+ } | ||
+ }); | ||
+ } | ||
+ | ||
+ @Test | ||
+ public void testAddValueWithPriority() throws Exception { | ||
+ runAndWaitUntil(mArray, mRef, new Runnable() { | ||
+ public void run() { | ||
+ mRef.push().setValue(new Bean(4), 0.5); | ||
+ } | ||
+ }, new Callable<Boolean>() { | ||
+ public Boolean call() throws Exception { | ||
+ return mArray.getItem(3).getValue(Bean.class).getNumber() == 3 && mArray.getItem(0).getValue(Bean.class).getNumber() == 4; | ||
+ } | ||
+ }); | ||
+ } | ||
+ | ||
+ @Test | ||
+ public void testChangePriorities() throws Exception { | ||
+ runAndWaitUntil(mArray, mRef, new Runnable() { | ||
+ public void run() { | ||
+ mArray.getItem(2).getRef().setPriority(0.5); | ||
+ } | ||
+ }, new Callable<Boolean>() { | ||
+ public Boolean call() throws Exception { | ||
+ return getBean(mArray, 0).getNumber() == 3 && getBean(mArray, 1).getNumber() == 1 && getBean(mArray, 2).getNumber() == 2; | ||
+ //return isValuesEqual(mArray, new int[]{3, 1, 2}); | ||
+ } | ||
+ }); | ||
+ } | ||
+ | ||
+ private static boolean isValuesEqual(FirebaseArray array, int[] expected) { | ||
+ if (array.getCount() != expected.length) return false; | ||
+ for (int i=0; i < array.getCount(); i++) { | ||
+ if (!array.getItem(i).getValue(Integer.class).equals(expected[i])) { | ||
+ return false; | ||
+ } | ||
+ } | ||
+ return true; | ||
+ } | ||
+ | ||
+ private Bean getBean(FirebaseArray array, int index) { | ||
+ return array.getItem(index).getValue(Bean.class); | ||
+ } | ||
+ | ||
+ public static void runAndWaitUntil(final FirebaseArray array, Firebase ref, Runnable task, Callable<Boolean> done) throws InterruptedException { | ||
+ final java.util.concurrent.Semaphore semaphore = new java.util.concurrent.Semaphore(0); | ||
+ array.setOnChangedListener(new FirebaseArray.OnChangedListener() { | ||
+ public void onChanged() { | ||
+ semaphore.release(); | ||
+ } | ||
+ }); | ||
+ task.run(); | ||
+ boolean isDone = false; | ||
+ long startedAt = System.currentTimeMillis(); | ||
+ while (!isDone && System.currentTimeMillis() - startedAt < 5000) { | ||
+ semaphore.tryAcquire(1, TimeUnit.SECONDS); | ||
+ try { | ||
+ isDone = done.call(); | ||
+ } catch (Exception e) { | ||
+ e.printStackTrace(); | ||
+ // and we're not done | ||
+ } | ||
+ } | ||
+ if (!isDone) { | ||
+ throw new AssertionFailedError(); | ||
+ } | ||
+ array.setOnChangedListener(null); | ||
+ }} |
149
library/src/androidTest/java/com/firebase/ui/FirebaseArrayTest.java
@@ -0,0 +1,149 @@ | ||
+package com.firebase.ui; | ||
+ | ||
+import android.test.AndroidTestCase; | ||
+ | ||
+import com.firebase.client.Firebase; | ||
+ | ||
+import junit.framework.AssertionFailedError; | ||
+ | ||
+import org.junit.After; | ||
+import org.junit.Before; | ||
+import org.junit.Test; | ||
+ | ||
+import java.util.concurrent.Callable; | ||
+import java.util.concurrent.TimeUnit; | ||
+ | ||
+public class FirebaseArrayTest extends AndroidTestCase { | ||
+ private Firebase mRef; | ||
+ private FirebaseArray mArray; | ||
+ | ||
+ @Before | ||
+ public void setUp() throws Exception { | ||
+ Firebase.setAndroidContext(this.getContext()); | ||
+ mRef = new Firebase("https://firebaseui-tests.firebaseio-demo.com/firebasearray"); | ||
+ mArray = new FirebaseArray(mRef); | ||
+ mRef.removeValue(); | ||
+ runAndWaitUntil(mArray, mRef, new Runnable() { | ||
+ public void run() { | ||
+ for (int i = 1; i <= 3; i++) { | ||
+ mRef.push().setValue(i, i); | ||
+ } | ||
+ } | ||
+ }, new Callable<Boolean>() { | ||
+ public Boolean call() throws Exception { | ||
+ return mArray.getCount() == 3; | ||
+ } | ||
+ }); | ||
+ } | ||
+ | ||
+ @After | ||
+ public void tearDown() throws Exception { | ||
+ mArray.cleanup(); | ||
+ mRef.removeValue(); | ||
+ } | ||
+ | ||
+ @Test | ||
+ public void testSize() throws Exception { | ||
+ assertEquals(3, mArray.getCount()); | ||
+ } | ||
+ | ||
+ @Test | ||
+ public void testPushIncreasesSize() throws Exception { | ||
+ assertEquals(3, mArray.getCount()); | ||
+ runAndWaitUntil(mArray, mRef, new Runnable() { | ||
+ public void run() { | ||
+ mRef.push().setValue(4); | ||
+ } | ||
+ }, new Callable<Boolean>() { | ||
+ @Override | ||
+ public Boolean call() throws Exception { | ||
+ return mArray.getCount() == 4; | ||
+ } | ||
+ }); | ||
+ } | ||
+ @Test | ||
+ public void testPushAppends() throws Exception { | ||
+ runAndWaitUntil(mArray, mRef, new Runnable() { | ||
+ public void run() { | ||
+ mRef.push().setValue(4, 4); | ||
+ } | ||
+ }, new Callable<Boolean>() { | ||
+ @Override | ||
+ public Boolean call() throws Exception { | ||
+ return mArray.getItem(3).getValue(Integer.class).equals(4); | ||
+ } | ||
+ }); | ||
+ } | ||
+ | ||
+ @Test | ||
+ public void testAddValueWithPriority() throws Exception { | ||
+ runAndWaitUntil(mArray, mRef, new Runnable() { | ||
+ public void run() { | ||
+ mRef.push().setValue(4, 0.5); | ||
+ } | ||
+ }, new Callable<Boolean>() { | ||
+ public Boolean call() throws Exception { | ||
+ return mArray.getItem(3).getValue(Integer.class).equals(3) && mArray.getItem(0).getValue(Integer.class).equals(4); | ||
+ } | ||
+ }); | ||
+ } | ||
+ | ||
+ @Test | ||
+ public void testChangePriorities() throws Exception { | ||
+ runAndWaitUntil(mArray, mRef, new Runnable() { | ||
+ public void run() { | ||
+ mArray.getItem(2).getRef().setPriority(0.5); | ||
+ } | ||
+ }, new Callable<Boolean>() { | ||
+ public Boolean call() throws Exception { | ||
+ return isValuesEqual(mArray, new int[]{3, 1, 2}); | ||
+ } | ||
+ }); | ||
+ } | ||
+ | ||
+ private static boolean isValuesEqual(FirebaseArray array, int[] expected) { | ||
+ if (array.getCount() != expected.length) return false; | ||
+ for (int i=0; i < array.getCount(); i++) { | ||
+ if (!array.getItem(i).getValue(Integer.class).equals(expected[i])) { | ||
+ return false; | ||
+ } | ||
+ } | ||
+ return true; | ||
+ } | ||
+ | ||
+ private Integer getIntValue(FirebaseArray array, int index) { | ||
+ return array.getItem(index).getValue(Integer.class); | ||
+ } | ||
+ | ||
+ private static void print(FirebaseArray array) { | ||
+ for (int i=0; i < array.getCount(); i++) { | ||
+ System.out.println(i+": key="+array.getItem(i).getKey()+" value="+array.getItem(i).getValue()); | ||
+ | ||
+ } | ||
+ } | ||
+ | ||
+ public static void runAndWaitUntil(final FirebaseArray array, Firebase ref, Runnable task, Callable<Boolean> done) throws InterruptedException { | ||
+ final java.util.concurrent.Semaphore semaphore = new java.util.concurrent.Semaphore(0); | ||
+ array.setOnChangedListener(new FirebaseArray.OnChangedListener() { | ||
+ public void onChanged() { | ||
+ semaphore.release(); | ||
+ } | ||
+ }); | ||
+ task.run(); | ||
+ boolean isDone = false; | ||
+ long startedAt = System.currentTimeMillis(); | ||
+ while (!isDone && System.currentTimeMillis() - startedAt < 5000) { | ||
+ semaphore.tryAcquire(1, TimeUnit.SECONDS); | ||
+ try { | ||
+ isDone = done.call(); | ||
+ } catch (Exception e) { | ||
+ e.printStackTrace(); | ||
+ // and we're not done | ||
+ } | ||
+ } | ||
+ if (!isDone) { | ||
+ throw new AssertionFailedError(); | ||
+ } | ||
+ array.setOnChangedListener(null); | ||
+ } | ||
+} |
7
library/src/main/AndroidManifest.xml
@@ -0,0 +1,7 @@ | ||
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.firebase.ui"> | ||
+ | ||
+ <application android:allowBackup="true" android:label="@string/app_name"> | ||
+ | ||
+ </application> | ||
+ | ||
+</manifest> |
90
library/src/main/java/com/firebase/ui/FirebaseArray.java
@@ -0,0 +1,90 @@ | ||
+package com.firebase.ui; | ||
+ | ||
+import com.firebase.client.*; | ||
+ | ||
+import java.util.ArrayList; | ||
+ | ||
+/** | ||
+ * This class implements an array-like collection on top of a Firebase location. | ||
+ */ | ||
+class FirebaseArray implements ChildEventListener { | ||
+ public interface OnChangedListener { | ||
+ void onChanged(); | ||
+ } | ||
+ | ||
+ private Query mQuery; | ||
+ private OnChangedListener mListener; | ||
+ private ArrayList<DataSnapshot> mSnapshots; | ||
+ | ||
+ public FirebaseArray(Query ref) { | ||
+ mQuery = ref; | ||
+ mSnapshots = new ArrayList<>(); | ||
+ mQuery.addChildEventListener(this); | ||
+ } | ||
+ | ||
+ public void cleanup() { | ||
+ mQuery.removeEventListener(this); | ||
+ } | ||
+ | ||
+ public int getCount() { | ||
+ return mSnapshots.size(); | ||
+ | ||
+ } | ||
+ public DataSnapshot getItem(int index) { | ||
+ return mSnapshots.get(index); | ||
+ } | ||
+ | ||
+ private int getIndexForKey(String key) { | ||
+ int index = 0; | ||
+ for (DataSnapshot snapshot : mSnapshots) { | ||
+ if (snapshot.getKey().equals(key)) { | ||
+ return index; | ||
+ } else { | ||
+ index++; | ||
+ } | ||
+ } | ||
+ throw new IllegalArgumentException("Key not found"); | ||
+ } | ||
+ | ||
+ // Start of ChildEventListener methods | ||
+ public void onChildAdded(DataSnapshot snapshot, String previousChildKey) { | ||
+ int index = 0; | ||
+ if (previousChildKey != null) { | ||
+ index = getIndexForKey(previousChildKey) + 1; | ||
+ } | ||
+ mSnapshots.add(index, snapshot); | ||
+ notifyChangedListeners(); | ||
+ } | ||
+ | ||
+ public void onChildChanged(DataSnapshot snapshot, String previousChildKey) { | ||
+ int index = getIndexForKey(snapshot.getKey()); | ||
+ mSnapshots.set(index, snapshot); | ||
+ notifyChangedListeners(); | ||
+ } | ||
+ | ||
+ public void onChildRemoved(DataSnapshot snapshot) { | ||
+ int index = getIndexForKey(snapshot.getKey()); | ||
+ mSnapshots.remove(index); | ||
+ notifyChangedListeners(); | ||
+ } | ||
+ | ||
+ public void onChildMoved(DataSnapshot snapshot, String previousChildKey) { | ||
+ onChildRemoved(snapshot); | ||
+ onChildAdded(snapshot, previousChildKey); | ||
+ // TODO: this will send two change notifications, which is wrong | ||
+ } | ||
+ | ||
+ public void onCancelled(FirebaseError firebaseError) { | ||
+ // TODO: what do we do with this? | ||
+ } | ||
+ // End of ChildEventListener methods | ||
+ | ||
+ public void setOnChangedListener(OnChangedListener listener) { | ||
+ mListener = listener; | ||
+ } | ||
+ protected void notifyChangedListeners() { | ||
+ if (mListener != null) { | ||
+ mListener.onChanged(); | ||
+ } | ||
+ } | ||
+} |
91
library/src/main/java/com/firebase/ui/FirebaseListAdapter.java
@@ -0,0 +1,91 @@ | ||
+package com.firebase.ui; | ||
+ | ||
+ | ||
+import android.app.Activity; | ||
+import android.view.View; | ||
+import android.view.ViewGroup; | ||
+import android.widget.BaseAdapter; | ||
+ | ||
+import com.firebase.client.Query; | ||
+ | ||
+/** | ||
+ * This class is a generic way of backing an Android ListView with a Firebase location. | ||
+ * It handles all of the child events at the given Firebase location. It marshals received data into the given | ||
+ * class type. Extend this class and provide an implementation of <code>populateView</code>, which will be given an | ||
+ * instance of your list item mLayout and an instance your class that holds your data. Simply populate the view however | ||
+ * you like and this class will handle updating the list as the data changes. | ||
+ * | ||
+ * @param <T> The class type to use as a model for the data contained in the children of the given Firebase location | ||
+ */ | ||
+public abstract class FirebaseListAdapter<T> extends BaseAdapter { | ||
+ | ||
+ private final Class<T> mModelClass; | ||
+ protected int mLayout; | ||
+ protected Activity mActivity; | ||
+ FirebaseArray mSnapshots; | ||
+ | ||
+ | ||
+ /** | ||
+ * @param modelClass Firebase will marshall the data at a location into an instance of a class that you provide | ||
+ * @param layout This is the mLayout used to represent a single list item. You will be responsible for populating an | ||
+ * instance of the corresponding view with the data from an instance of mModelClass. | ||
+ * @param activity The activity containing the ListView | ||
+ * @param ref The Firebase location to watch for data changes. Can also be a slice of a location, using some | ||
+ * combination of <code>limit()</code>, <code>startAt()</code>, and <code>endAt()</code>, | ||
+ */ | ||
+ public FirebaseListAdapter(Class<T> modelClass, int layout, Activity activity, Query ref) { | ||
+ mModelClass = modelClass; | ||
+ mLayout = layout; | ||
+ mActivity = activity; | ||
+ mSnapshots = new FirebaseArray(ref); | ||
+ mSnapshots.setOnChangedListener(new FirebaseArray.OnChangedListener() { | ||
+ @Override | ||
+ public void onChanged() { | ||
+ notifyDataSetChanged(); | ||
+ } | ||
+ }); | ||
+ } | ||
+ | ||
+ public void cleanup() { | ||
+ // We're being destroyed, let go of our mListener and forget about all of the mModels | ||
+ mSnapshots.cleanup(); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public int getCount() { | ||
+ return mSnapshots.getCount(); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public Object getItem(int i) { return mSnapshots.getItem(i); } | ||
+ | ||
+ @Override | ||
+ public long getItemId(int i) { | ||
+ // http://stackoverflow.com/questions/5100071/whats-the-purpose-of-item-ids-in-android-listview-adapter | ||
+ return mSnapshots.getItem(i).getKey().hashCode(); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public View getView(int i, View view, ViewGroup viewGroup) { | ||
+ if (view == null) { | ||
+ view = mActivity.getLayoutInflater().inflate(mLayout, viewGroup, false); | ||
+ } | ||
+ | ||
+ T model = mSnapshots.getItem(i).getValue(mModelClass); | ||
+ | ||
+ // Call out to subclass to marshall this model into the provided view | ||
+ populateView(view, model); | ||
+ return view; | ||
+ } | ||
+ | ||
+ /** | ||
+ * Each time the data at the given Firebase location changes, this method will be called for each item that needs | ||
+ * to be displayed. The arguments correspond to the mLayout and mModelClass given to the constructor of this class. | ||
+ * <p/> | ||
+ * Your implementation should populate the view using the data contained in the model. | ||
+ * | ||
+ * @param v The view to populate | ||
+ * @param model The object containing the data used to populate the view | ||
+ */ | ||
+ protected abstract void populateView(View v, T model); | ||
+} |
75
library/src/main/java/com/firebase/ui/FirebaseRecyclerViewAdapter.java
@@ -0,0 +1,75 @@ | ||
+package com.firebase.ui; | ||
+ | ||
+import android.support.v7.widget.RecyclerView; | ||
+import android.util.Log; | ||
+ | ||
+import com.firebase.client.ChildEventListener; | ||
+import com.firebase.client.DataSnapshot; | ||
+import com.firebase.client.FirebaseError; | ||
+import com.firebase.client.Query; | ||
+ | ||
+import java.util.ArrayList; | ||
+import java.util.HashMap; | ||
+import java.util.List; | ||
+import java.util.Map; | ||
+ | ||
+/** | ||
+ * This class is a generic way of backing an RecyclerView with a Firebase location. | ||
+ * It handles all of the child events at the given Firebase location. It marshals received data into the given | ||
+ * class type. | ||
+ * | ||
+ * @param <T> The collection type | ||
+ */ | ||
+public abstract class FirebaseRecyclerViewAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> { | ||
+ | ||
+ FirebaseArray mSnapshots; | ||
+ Class<T> mModelClass; | ||
+ protected RecyclerViewClickListener clickListener; | ||
+ | ||
+ | ||
+ /** | ||
+ * @param ref The Firebase location to watch for data changes. Can also be a slice of a location, using some | ||
+ * combination of <code>limit()</code>, <code>startAt()</code>, and <code>endAt()</code>, | ||
+ * @param modelClass Firebase will marshall the data at a location into an instance of a class that you provide | ||
+ */ | ||
+ public FirebaseRecyclerViewAdapter(Query ref, Class<T> modelClass) { | ||
+ mModelClass = modelClass; | ||
+ mSnapshots = new FirebaseArray(ref); | ||
+ | ||
+ // TODO: implement separate notifications for added, removed, changed and moved | ||
+ mSnapshots.setOnChangedListener(new FirebaseArray.OnChangedListener() { | ||
+ @Override | ||
+ public void onChanged() { | ||
+ notifyDataSetChanged(); | ||
+ } | ||
+ }); | ||
+ | ||
+ } | ||
+ | ||
+ public void cleanup() { | ||
+ mSnapshots.cleanup(); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public int getItemCount() { | ||
+ return mSnapshots.getCount(); | ||
+ } | ||
+ | ||
+ public T getItem(int position) { | ||
+ return mSnapshots.getItem(position).getValue(mModelClass); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public long getItemId(int position) { | ||
+ // http://stackoverflow.com/questions/5100071/whats-the-purpose-of-item-ids-in-android-listview-adapter | ||
+ return mSnapshots.getItem(position).getKey().hashCode(); | ||
+ } | ||
+ | ||
+ public void setClickListener(RecyclerViewClickListener clickListener) { | ||
+ this.clickListener = clickListener; | ||
+ } | ||
+ | ||
+ public interface RecyclerViewClickListener { | ||
+ public void onItemClicked(int position); | ||
+ } | ||
+} |
3
library/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@ | ||
+<resources> | ||
+ <string name="app_name">Library</string> | ||
+</resources> |
1
settings.gradle
@@ -0,0 +1 @@ | ||
+include ':app', ':library' |
0 comments on commit
daf8a96