diff --git a/.gitignore b/.gitignore index ccf2efe..01afe3d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ +<<<<<<< HEAD +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +======= # Built application files *.apk *.ap_ @@ -25,3 +34,4 @@ proguard/ # Log Files *.log +>>>>>>> ac8e0a393d1ea8a8d5f7401afa3b0f8ca0829d02 diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..d388799 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +robinhood_hackathon \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..9a8b7e5 --- /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..1bbc21d --- /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..5689cf8 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 1.7 + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..4ff6821 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ 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/app.iml b/app/app.iml new file mode 100644 index 0000000..3f67e83 --- /dev/null +++ b/app/app.iml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..95d3768 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,30 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 22 + buildToolsVersion "22.0.1" + + defaultConfig { + applicationId "abassawo.c4q.nyc.fe_nyc" + minSdkVersion 15 + 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.1' + compile 'com.android.support:design:22.2.0' + compile 'com.jakewharton:butterknife:7.0.1' + compile 'com.android.support:support-v4:22.2.1' + compile 'com.google.android.gms:play-services:7.5.0' + compile 'org.achartengine:achartengine:1.2.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..dcb04d2 --- /dev/null +++ b/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/c4q-Abass/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 *; +#} diff --git a/app/src/androidTest/java/abassawo/c4q/nyc/fe_nyc/ApplicationTest.java b/app/src/androidTest/java/abassawo/c4q/nyc/fe_nyc/ApplicationTest.java new file mode 100644 index 0000000..7b0c3e1 --- /dev/null +++ b/app/src/androidTest/java/abassawo/c4q/nyc/fe_nyc/ApplicationTest.java @@ -0,0 +1,13 @@ +package abassawo.c4q.nyc.fe_nyc; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..84d0e52 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,42 @@ + + + android:theme="@style/Theme.DesignDemo" > + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/chart.html b/app/src/main/assets/chart.html new file mode 100644 index 0000000..0fe4a60 --- /dev/null +++ b/app/src/main/assets/chart.html @@ -0,0 +1,45 @@ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/app/src/main/java/abassawo/c4q/nyc/fe_nyc/BudgetCalculator.java b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/BudgetCalculator.java new file mode 100644 index 0000000..0f9699d --- /dev/null +++ b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/BudgetCalculator.java @@ -0,0 +1,15 @@ +package abassawo.c4q.nyc.fe_nyc; + +/** + * Created by c4q-Abass on 8/1/15. + */ +public class BudgetCalculator { + private int savingGoal; + private int spendable; + private int currentSavings; + private int income; + + public BudgetCalculator(double income){ + + } +} diff --git a/app/src/main/java/abassawo/c4q/nyc/fe_nyc/BudgetViewFragment.java b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/BudgetViewFragment.java new file mode 100644 index 0000000..a7c52bb --- /dev/null +++ b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/BudgetViewFragment.java @@ -0,0 +1,76 @@ + +package abassawo.c4q.nyc.fe_nyc; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.graphics.Color; +import android.graphics.drawable.AnimationDrawable; +import android.net.Uri; +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 android.view.animation.AccelerateDecelerateInterpolator; +import android.webkit.JavascriptInterface; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.Toast; + +import org.achartengine.ChartFactory; +import org.achartengine.GraphicalView; +import org.achartengine.model.CategorySeries; +import org.achartengine.model.SeriesSelection; +import org.achartengine.renderer.DefaultRenderer; +import org.achartengine.renderer.SimpleSeriesRenderer; + +public class BudgetViewFragment extends Fragment { + public WebView webView; + public ImageView goalImage; + + + @SuppressLint("SetJavaScriptEnabled") + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final View myInflatedView = inflater.inflate(R.layout.fragment_budget_view, container, false); + + goalImage = (ImageView)myInflatedView.findViewById(R.id.goal); + goalImage.setBackgroundResource(R.drawable.goal_animation); + AnimationDrawable frameAnimation = (AnimationDrawable) goalImage.getBackground(); + frameAnimation.start(); + + webView = (WebView) myInflatedView.findViewById(R.id.web); + webView.addJavascriptInterface(new WebAppInterface(), "Android"); + + webView.getSettings().setJavaScriptEnabled(true); + webView.loadUrl("file:///android_asset/chart.html"); + + return myInflatedView; + } + + + public class WebAppInterface { + + @JavascriptInterface + public int getNum1() { + return 320; + } + + @JavascriptInterface + public int getNum2() { + return 1285; + } + + @JavascriptInterface + public int getNum3() { + return 115; + } + + } +} + diff --git a/app/src/main/java/abassawo/c4q/nyc/fe_nyc/ExpenseFragment.java b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/ExpenseFragment.java new file mode 100644 index 0000000..9841033 --- /dev/null +++ b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/ExpenseFragment.java @@ -0,0 +1,78 @@ + +package abassawo.c4q.nyc.fe_nyc; + +import android.app.Activity; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + + +/** + * A simple {@link Fragment} subclass. + * Activities that contain this fragment must implement the + * {@link ExpenseFragment.OnFragmentInteractionListener} interface + * to handle interaction events. + * Use the {@link ExpenseFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class ExpenseFragment extends Fragment { + // TODO: Rename parameter arguments, choose names that match + // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER + private static final String ARG_PARAM1 = "param1"; + private static final String ARG_PARAM2 = "param2"; + + + // TODO: Rename and change types of parameters + private String mParam1; + private String mParam2; + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param param1 Parameter 1. + * @param param2 Parameter 2. + * @return A new instance of fragment ExpenseFragment. + */ + // TODO: Rename and change types and number of parameters + public static ExpenseFragment newInstance(String param1, String param2) { + ExpenseFragment fragment = new ExpenseFragment(); + Bundle args = new Bundle(); + args.putString(ARG_PARAM1, param1); + args.putString(ARG_PARAM2, param2); + fragment.setArguments(args); + return fragment; + } + + + public ExpenseFragment() { + // Required empty public constructor + } + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + mParam1 = getArguments().getString(ARG_PARAM1); + mParam2 = getArguments().getString(ARG_PARAM2); + } + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_expense, container, false); + } + + + + + + +} diff --git a/app/src/main/java/abassawo/c4q/nyc/fe_nyc/LandingPageActivity.java b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/LandingPageActivity.java new file mode 100644 index 0000000..ea568f5 --- /dev/null +++ b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/LandingPageActivity.java @@ -0,0 +1,22 @@ +package abassawo.c4q.nyc.fe_nyc; + + +import android.app.Activity; +import android.os.Bundle; +import android.support.v4.app.FragmentManager; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +/** + * Created by c4q-Abass on 8/1/15. + */ +public class LandingPageActivity extends Activity { + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_landing_page); + } +} diff --git a/app/src/main/java/abassawo/c4q/nyc/fe_nyc/LoginFragment.java b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/LoginFragment.java new file mode 100644 index 0000000..b7c5c96 --- /dev/null +++ b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/LoginFragment.java @@ -0,0 +1,166 @@ +package abassawo.c4q.nyc.fe_nyc; + +import android.support.v4.app.Fragment; + + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.annotation.TargetApi; + + +import android.app.LoaderManager.LoaderCallbacks; +import android.content.ContentResolver; +import android.content.CursorLoader; +import android.content.Loader; +import android.database.Cursor; +import android.net.Uri; +import android.os.AsyncTask; + +import android.os.Bundle; + +import android.support.v4.app.FragmentManager; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import android.support.annotation.Nullable; + +import android.support.v4.app.Fragment; +import android.text.TextUtils; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.Button; +import android.widget.EditText; + +import com.google.android.gms.common.SignInButton; + +import java.util.List; + +import butterknife.Bind; +import butterknife.ButterKnife; + + +/** + * A login screen that offers login via email/password and via Google+ sign in. + *

+ * ************ IMPORTANT SETUP NOTES: ************ + * In order for Google+ sign in to work with your app, you must first go to: + * https://developers.google.com/+/mobile/android/getting-started#step_1_enable_the_google_api + * and follow the steps in "Step 1" to create an OAuth 2.0 client for your package. + */ + + +public class LoginFragment extends Fragment { + + @Bind(R.id.email_sign_in_button) + Button signInBtn; + /** + * A dummy authentication store containing known user names and passwords. + * TODO: remove after connecting to a real authentication system. + */ + + public LoginFragment(){ + + } + + private static final String[] DUMMY_CREDENTIALS = new String[]{ + "foo@example.com:hello", "bar@example.com:world" + }; + /** + * Keep track of the login task to ensure we can cancel it if requested. + */ + private UserLoginTask mAuthTask = null; + + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_login, container, false); + ButterKnife.bind(this, view); + signInBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); + fragmentManager.beginTransaction() + .replace(R.id.main_container, new ExpenseFragment()) + .addToBackStack(null) //allows user to press back button and return to previous fragment + .commit(); + + } + }); + return view; + } + + + + private boolean isEmailValid(String email) { + //TODO: Replace this with your own logic + return email.contains("@"); + } + + private boolean isPasswordValid(String password) { + //TODO: Replace this with your own logic + return password.length() > 4; + } + + /** + * Shows the progress UI and hides the login form. + */ + + + + private void addEmailsToAutoComplete(List emailAddressCollection) { + //Create adapter to tell the AutoCompleteTextView what to show in its dropdown list. + // ArrayAdapter adapter = +// new ArrayAdapter(LoginActivity.this, +// android.R.layout.simple_dropdown_item_1line, emailAddressCollection); + + // mEmailView.setAdapter(adapter); + } + + /** + * Represents an asynchronous login/registration task used to authenticate + * the user. + */ + public class UserLoginTask extends AsyncTask { + + private final String mEmail; + private final String mPassword; + + UserLoginTask(String email, String password) { + mEmail = email; + mPassword = password; + } + + @Override + protected Boolean doInBackground(Void... params) { + // TODO: attempt authentication against a network service. + + try { + // Simulate network access. + Thread.sleep(2000); + } catch (InterruptedException e) { + return false; + } + + for (String credential : DUMMY_CREDENTIALS) { + String[] pieces = credential.split(":"); + if (pieces[0].equals(mEmail)) { + // Account exists, return true if the password matches. + return pieces[1].equals(mPassword); + } + } + + // TODO: register the new account here. + return true; + } + + } +} diff --git a/app/src/main/java/abassawo/c4q/nyc/fe_nyc/MainActivity.java b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/MainActivity.java new file mode 100644 index 0000000..ae06563 --- /dev/null +++ b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/MainActivity.java @@ -0,0 +1,190 @@ +package abassawo.c4q.nyc.fe_nyc; + +import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.app.AppCompatActivity; +import android.content.Intent; +import android.support.design.widget.NavigationView; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBar; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.app.Activity; +import android.view.View; +import butterknife.Bind; +import butterknife.ButterKnife; + + + +public class MainActivity extends AppCompatActivity { + @Bind(R.id.drawer_layout) DrawerLayout mDrawerLayout; + private CharSequence mTitle; + NavigationView navigationView; + private ActionBarDrawerToggle mDrawerToggle; + + private FragmentManager fragmentManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + ButterKnife.bind(this); + mTitle = getTitle(); + mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.app_name, R.string.app_name) { + @Override + public void onDrawerOpened(View drawerView) { + super.onDrawerOpened(drawerView); + + invalidateOptionsMenu(); + } + }; + + + navigationView = (NavigationView) findViewById(R.id.nav_view); + if (navigationView != null) { + setupDrawerContent(navigationView); + } + + final ActionBar actionBar = getSupportActionBar(); + actionBar.isHideOnContentScrollEnabled(); + actionBar.setHomeAsUpIndicator(R.drawable.ic_menu); + actionBar.setTitle(getString(R.string.app_name)); + actionBar.setLogo(R.drawable.fe_nyc_logo); + actionBar.setIcon(R.drawable.fe_nyc_logo); + actionBar.setDisplayHomeAsUpEnabled(true); + + + FragmentManager fragmentManager = getSupportFragmentManager(); + fragmentManager.beginTransaction() + .add(R.id.main_container, new LoginFragment()) + .addToBackStack(null) //allows user to press back button and return to previous fragment + .commit(); + + } + + + + private void setupDrawerContent(NavigationView navigationView) { + fragmentManager = getSupportFragmentManager(); + navigationView.setNavigationItemSelectedListener( + new NavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(MenuItem menuItem) { + menuItem.setChecked(true); + if (menuItem.getItemId() == R.id.nav_wallet){ + fragmentManager.beginTransaction() + .replace(R.id.main_container, new WalletFragment())//allows user to press back button and return to previous fragment + .commit(); + } else if(menuItem.getItemId() == R.id.nav_expense){ + fragmentManager.beginTransaction() + .replace(R.id.main_container, new ExpenseFragment()) + //allows user to press back button and return to previous fragment + + .commit(); + } else if(menuItem.getItemId() == R.id.nav_resources){ + fragmentManager.beginTransaction() + .replace(R.id.main_container, new ResourcesFragment())//allows user to press back button and return to previous fragment + .commit(); + } else if((menuItem.getItemId() == R.id.nav_settings)){ + Intent intent = new Intent(getApplicationContext(), SettingsActivity.class); + startActivity(intent); + } + mDrawerLayout.closeDrawers(); + return true; + } + }); + } + + + + public void restoreActionBar() { + ActionBar actionBar = getSupportActionBar(); + actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); + actionBar.setDisplayShowTitleEnabled(true); + actionBar.setTitle(mTitle); + } + + + + + + public boolean onCreateOptionsMenu(Menu menu) { + + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main, menu); + return super.onCreateOptionsMenu(menu); + + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + if (mDrawerToggle.onOptionsItemSelected(item)) { + return true; + } + if (id == R.id.action_log_out) { + return true; + } + + return super.onOptionsItemSelected(item); + } + + public void onSectionAttached(int number) { + switch (number) { + case 4: + mTitle = ("Expenses"); + break; + case 2: + mTitle = ("Budget"); + break; + case 3: + mTitle = ("Settings"); + break; + case 1: + mTitle = ("Resources"); + break; + } + } + + /** + * A placeholder fragment containing a simple view. + */ + public static class PlaceholderFragment extends Fragment { + /** + * The fragment argument representing the section number for this + * fragment. + */ + private static final String ARG_SECTION_NUMBER = "section_number"; + + /** + * Returns a new instance of this fragment for the given section + * number. + */ + public static PlaceholderFragment newInstance(int sectionNumber) { + PlaceholderFragment fragment = new PlaceholderFragment(); + Bundle args = new Bundle(); + args.putInt(ARG_SECTION_NUMBER, sectionNumber); + fragment.setArguments(args); + return fragment; + } + + public PlaceholderFragment() { + } + + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + ((MainActivity) activity).onSectionAttached( + getArguments().getInt(ARG_SECTION_NUMBER)); + } + } + +} + diff --git a/app/src/main/java/abassawo/c4q/nyc/fe_nyc/ResourcesFragment.java b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/ResourcesFragment.java new file mode 100644 index 0000000..b9d3861 --- /dev/null +++ b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/ResourcesFragment.java @@ -0,0 +1,79 @@ +package abassawo.c4q.nyc.fe_nyc; + + +import android.app.Activity; +import android.net.Uri; +import android.os.Bundle; + + +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + + + + +/** + * A simple {@link Fragment} subclass. + * Activities that contain this fragment must implement the + * {@link ResourcesFragment.OnFragmentInteractionListener} interface + * to handle interaction events. + * Use the {@link ResourcesFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class ResourcesFragment extends Fragment { + // TODO: Rename parameter arguments, choose names that match + // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER + private static final String ARG_PARAM1 = "param1"; + private static final String ARG_PARAM2 = "param2"; + + + // TODO: Rename and change types of parameters + private String mParam1; + private String mParam2; + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param param1 Parameter 1. + * @param param2 Parameter 2. + * @return A new instance of fragment ResourcesFragment. + */ + // TODO: Rename and change types and number of parameters + public static ResourcesFragment newInstance(String param1, String param2) { + ResourcesFragment fragment = new ResourcesFragment(); + Bundle args = new Bundle(); + args.putString(ARG_PARAM1, param1); + args.putString(ARG_PARAM2, param2); + fragment.setArguments(args); + return fragment; + } + + + public ResourcesFragment() { + // Required empty public constructor + } + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + mParam1 = getArguments().getString(ARG_PARAM1); + mParam2 = getArguments().getString(ARG_PARAM2); + } + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_resources, container, false); + } + + + +} \ No newline at end of file diff --git a/app/src/main/java/abassawo/c4q/nyc/fe_nyc/SettingsActivity.java b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/SettingsActivity.java new file mode 100644 index 0000000..cc5759a --- /dev/null +++ b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/SettingsActivity.java @@ -0,0 +1,259 @@ +package abassawo.c4q.nyc.fe_nyc; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.Configuration; +import android.media.Ringtone; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.PreferenceActivity; +import android.preference.PreferenceCategory; +import android.preference.PreferenceFragment; +import android.preference.PreferenceManager; +import android.preference.RingtonePreference; +import android.text.TextUtils; + + +import java.util.List; + +/** + * A {@link PreferenceActivity} that presents a set of application settings. On + * handset devices, settings are presented as a single list. On tablets, + * settings are split by category, with category headers shown to the left of + * the list of settings. + *

+ * See + * Android Design: Settings for design guidelines and the Settings + * API Guide for more information on developing a Settings UI. + */ +public class SettingsActivity extends PreferenceActivity { + /** + * Determines whether to always show the simplified settings UI, where + * settings are presented in a single list. When false, settings are shown + * as a master/detail two-pane view on tablets. When true, a single pane is + * shown on tablets. + */ + private static final boolean ALWAYS_SIMPLE_PREFS = false; + + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + + setupSimplePreferencesScreen(); + } + + /** + * Shows the simplified settings UI if the device configuration if the + * device configuration dictates that a simplified, single-pane UI should be + * shown. + */ + private void setupSimplePreferencesScreen() { + if (!isSimplePreferences(this)) { + return; + } + + // In the simplified UI, fragments are not used at all and we instead + // use the older PreferenceActivity APIs. + + // Add 'general' preferences. + addPreferencesFromResource(R.xml.pref_general); + + // Add 'notifications' preferences, and a corresponding header. + PreferenceCategory fakeHeader = new PreferenceCategory(this); + fakeHeader.setTitle(R.string.pref_header_notifications); + getPreferenceScreen().addPreference(fakeHeader); + addPreferencesFromResource(R.xml.pref_notification); + + // Add 'data and sync' preferences, and a corresponding header. + fakeHeader = new PreferenceCategory(this); + fakeHeader.setTitle(R.string.pref_header_data_sync); + getPreferenceScreen().addPreference(fakeHeader); + addPreferencesFromResource(R.xml.pref_data_sync); + + // Bind the summaries of EditText/List/Dialog/Ringtone preferences to + // their values. When their values change, their summaries are updated + // to reflect the new value, per the Android Design guidelines. + bindPreferenceSummaryToValue(findPreference("example_text")); + //bindPreferenceSummaryToValue(findPreference("example_list")); +// bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone")); +// bindPreferenceSummaryToValue(findPreference("sync_frequency")); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean onIsMultiPane() { + return isXLargeTablet(this) && !isSimplePreferences(this); + } + + /** + * Helper method to determine if the device has an extra-large screen. For + * example, 10" tablets are extra-large. + */ + private static boolean isXLargeTablet(Context context) { + return (context.getResources().getConfiguration().screenLayout + & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE; + } + + /** + * Determines whether the simplified settings UI should be shown. This is + * true if this is forced via {@link #ALWAYS_SIMPLE_PREFS}, or the device + * doesn't have newer APIs like {@link PreferenceFragment}, or the device + * doesn't have an extra-large screen. In these cases, a single-pane + * "simplified" settings UI should be shown. + */ + private static boolean isSimplePreferences(Context context) { + return ALWAYS_SIMPLE_PREFS + || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB + || !isXLargeTablet(context); + } + + /** + * {@inheritDoc} + */ + @Override + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public void onBuildHeaders(List

target) { + if (!isSimplePreferences(this)) { + loadHeadersFromResource(R.xml.pref_headers, target); + } + } + + /** + * A preference value change listener that updates the preference's summary + * to reflect its new value. + */ + private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object value) { + String stringValue = value.toString(); + + if (preference instanceof ListPreference) { + // For list preferences, look up the correct display value in + // the preference's 'entries' list. + ListPreference listPreference = (ListPreference) preference; + int index = listPreference.findIndexOfValue(stringValue); + + // Set the summary to reflect the new value. + preference.setSummary( + index >= 0 + ? listPreference.getEntries()[index] + : null); + + } else if (preference instanceof RingtonePreference) { + // For ringtone preferences, look up the correct display value + // using RingtoneManager. + if (TextUtils.isEmpty(stringValue)) { + // Empty values correspond to 'silent' (no ringtone). + preference.setSummary(R.string.pref_ringtone_silent); + + } else { + Ringtone ringtone = RingtoneManager.getRingtone( + preference.getContext(), Uri.parse(stringValue)); + + if (ringtone == null) { + // Clear the summary if there was a lookup error. + preference.setSummary(null); + } else { + // Set the summary to reflect the new ringtone display + // name. + String name = ringtone.getTitle(preference.getContext()); + preference.setSummary(name); + } + } + + } else { + // For all other preferences, set the summary to the value's + // simple string representation. + preference.setSummary(stringValue); + } + return true; + } + }; + + /** + * Binds a preference's summary to its value. More specifically, when the + * preference's value is changed, its summary (line of text below the + * preference title) is updated to reflect the value. The summary is also + * immediately updated upon calling this method. The exact display format is + * dependent on the type of preference. + * + * @see #sBindPreferenceSummaryToValueListener + */ + private static void bindPreferenceSummaryToValue(Preference preference) { + // Set the listener to watch for value changes. + preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener); + + // Trigger the listener immediately with the preference's + // current value. + sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, + PreferenceManager + .getDefaultSharedPreferences(preference.getContext()) + .getString(preference.getKey(), "")); + } + + /** + * This fragment shows general preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public static class GeneralPreferenceFragment extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.pref_general); + + // Bind the summaries of EditText/List/Dialog/Ringtone preferences + // to their values. When their values change, their summaries are + // updated to reflect the new value, per the Android Design + // guidelines. + bindPreferenceSummaryToValue(findPreference("example_text")); + //bindPreferenceSummaryToValue(findPreference("example_list")); + } + } + + /** + * This fragment shows notification preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public static class NotificationPreferenceFragment extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.pref_notification); + + // Bind the summaries of EditText/List/Dialog/Ringtone preferences + // to their values. When their values change, their summaries are + // updated to reflect the new value, per the Android Design + // guidelines. + //bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone")); + } + } + + /** + * This fragment shows data and sync preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public static class DataSyncPreferenceFragment extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.pref_data_sync); + + // Bind the summaries of EditText/List/Dialog/Ringtone preferences + // to their values. When their values change, their summaries are + // updated to reflect the new value, per the Android Design + // guidelines. + bindPreferenceSummaryToValue(findPreference("sync_frequency")); + } + } +} diff --git a/app/src/main/java/abassawo/c4q/nyc/fe_nyc/WalletFragment.java b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/WalletFragment.java new file mode 100644 index 0000000..0a6cf84 --- /dev/null +++ b/app/src/main/java/abassawo/c4q/nyc/fe_nyc/WalletFragment.java @@ -0,0 +1,106 @@ +package abassawo.c4q.nyc.fe_nyc; + +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 android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + + +public class WalletFragment extends Fragment { + String strCash; + boolean addCash; + double cashInWallet, transactionCash, savings, monthlyWallet = 300; + Button add, minus, calculate; + ImageView tree; + TextView cashDisplay, warning; + EditText enterAmount; + + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + + final View myInflatedView = inflater.inflate(R.layout.fragment_wallet, container, false); + + add = (Button) myInflatedView.findViewById(R.id.add_button); + minus = (Button) myInflatedView.findViewById(R.id.minus_button); + calculate = (Button) myInflatedView.findViewById(R.id.calculate); + tree = (ImageView) myInflatedView.findViewById(R.id.tree); + cashDisplay = (TextView) myInflatedView.findViewById(R.id.wallet_money); + warning = (TextView) myInflatedView.findViewById(R.id.warning); + enterAmount = (EditText) myInflatedView.findViewById(R.id.enter_amount); + + //TODO get cash amount from shared preferences + + cashDisplay.setText(String.valueOf(cashInWallet)); + + minus.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + enterAmount.setVisibility(View.VISIBLE); + calculate.setVisibility(View.VISIBLE); + addCash = false; + } + }); + + add.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + enterAmount.setVisibility(View.VISIBLE); + calculate.setVisibility(View.VISIBLE); + addCash = true; + } + }); + + calculate.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + transactionCash = Double.parseDouble(enterAmount.getText().toString()); + + if (addCash) { + cashInWallet = cashInWallet + transactionCash; + } else { + cashInWallet = cashInWallet - transactionCash; + if (cashInWallet < 0) { + cashInWallet = 0.0; + } + } + cashDisplay.setText(String.valueOf(cashInWallet)); + enterAmount.setText(""); + enterAmount.setVisibility(View.GONE); + calculate.setVisibility(View.GONE); + + double cashPercentage = (cashInWallet / monthlyWallet) * 100; + + if (cashPercentage > 80) { + tree.setBackgroundResource(R.drawable.tree_full); + warning.setVisibility(View.GONE); + } else if (cashPercentage > 60) { + tree.setBackgroundResource(R.drawable.tree_60); + warning.setVisibility(View.GONE); + } else if (cashPercentage > 40) { + tree.setBackgroundResource(R.drawable.tree_40); + warning.setVisibility(View.GONE); + } else if (cashPercentage > 20) { + tree.setBackgroundResource(R.drawable.tree_20); + warning.setVisibility(View.GONE); + } else { + tree.setBackgroundResource(R.drawable.tree_empty); + warning.setVisibility(View.VISIBLE); + + } + } + }); + + return myInflatedView; + } + + +} + + + diff --git a/app/src/main/res/drawable/a_new_car_1.png b/app/src/main/res/drawable/a_new_car_1.png new file mode 100644 index 0000000..f5005b1 Binary files /dev/null and b/app/src/main/res/drawable/a_new_car_1.png differ diff --git a/app/src/main/res/drawable/a_new_car_2.png b/app/src/main/res/drawable/a_new_car_2.png new file mode 100644 index 0000000..02464d6 Binary files /dev/null and b/app/src/main/res/drawable/a_new_car_2.png differ diff --git a/app/src/main/res/drawable/a_new_car_3.png b/app/src/main/res/drawable/a_new_car_3.png new file mode 100644 index 0000000..f6eb3ab Binary files /dev/null and b/app/src/main/res/drawable/a_new_car_3.png differ diff --git a/app/src/main/res/drawable/a_new_car_4.png b/app/src/main/res/drawable/a_new_car_4.png new file mode 100644 index 0000000..ce21855 Binary files /dev/null and b/app/src/main/res/drawable/a_new_car_4.png differ diff --git a/app/src/main/res/drawable/arrow.jpg b/app/src/main/res/drawable/arrow.jpg new file mode 100644 index 0000000..65a75a6 Binary files /dev/null and b/app/src/main/res/drawable/arrow.jpg differ diff --git a/app/src/main/res/drawable/button_normal.jpg b/app/src/main/res/drawable/button_normal.jpg new file mode 100644 index 0000000..364ca23 Binary files /dev/null and b/app/src/main/res/drawable/button_normal.jpg differ diff --git a/app/src/main/res/drawable/button_pressed.jpg b/app/src/main/res/drawable/button_pressed.jpg new file mode 100644 index 0000000..c5e4cf5 Binary files /dev/null and b/app/src/main/res/drawable/button_pressed.jpg differ diff --git a/app/src/main/res/drawable/custom_button.xml b/app/src/main/res/drawable/custom_button.xml new file mode 100644 index 0000000..b5d20ca --- /dev/null +++ b/app/src/main/res/drawable/custom_button.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/fe_nyc_logo.png b/app/src/main/res/drawable/fe_nyc_logo.png new file mode 100644 index 0000000..13bab65 Binary files /dev/null and b/app/src/main/res/drawable/fe_nyc_logo.png differ diff --git a/app/src/main/res/drawable/goal_animation.xml b/app/src/main/res/drawable/goal_animation.xml new file mode 100644 index 0000000..3bbf4a1 --- /dev/null +++ b/app/src/main/res/drawable/goal_animation.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_menu.png b/app/src/main/res/drawable/ic_menu.png new file mode 100644 index 0000000..c62db8c Binary files /dev/null and b/app/src/main/res/drawable/ic_menu.png differ diff --git a/app/src/main/res/drawable/moneytrees.jpg b/app/src/main/res/drawable/moneytrees.jpg new file mode 100644 index 0000000..b7a7159 Binary files /dev/null and b/app/src/main/res/drawable/moneytrees.jpg differ diff --git a/app/src/main/res/drawable/moneytrees.png b/app/src/main/res/drawable/moneytrees.png new file mode 100644 index 0000000..4392e55 Binary files /dev/null and b/app/src/main/res/drawable/moneytrees.png differ diff --git a/app/src/main/res/drawable/progress_bar.png b/app/src/main/res/drawable/progress_bar.png new file mode 100644 index 0000000..abff577 Binary files /dev/null and b/app/src/main/res/drawable/progress_bar.png differ diff --git a/app/src/main/res/drawable/tree_20.jpg b/app/src/main/res/drawable/tree_20.jpg new file mode 100644 index 0000000..06fa7b9 Binary files /dev/null and b/app/src/main/res/drawable/tree_20.jpg differ diff --git a/app/src/main/res/drawable/tree_40.jpg b/app/src/main/res/drawable/tree_40.jpg new file mode 100644 index 0000000..bf78cf0 Binary files /dev/null and b/app/src/main/res/drawable/tree_40.jpg differ diff --git a/app/src/main/res/drawable/tree_60.jpg b/app/src/main/res/drawable/tree_60.jpg new file mode 100644 index 0000000..86e8a5a Binary files /dev/null and b/app/src/main/res/drawable/tree_60.jpg differ diff --git a/app/src/main/res/drawable/tree_80.jpg b/app/src/main/res/drawable/tree_80.jpg new file mode 100644 index 0000000..c67f576 Binary files /dev/null and b/app/src/main/res/drawable/tree_80.jpg differ diff --git a/app/src/main/res/drawable/tree_empty.jpg b/app/src/main/res/drawable/tree_empty.jpg new file mode 100644 index 0000000..cc3ba76 Binary files /dev/null and b/app/src/main/res/drawable/tree_empty.jpg differ diff --git a/app/src/main/res/drawable/tree_full.jpg b/app/src/main/res/drawable/tree_full.jpg new file mode 100644 index 0000000..f4389c2 Binary files /dev/null and b/app/src/main/res/drawable/tree_full.jpg differ diff --git a/app/src/main/res/layout/activity_landing_page.xml b/app/src/main/res/layout/activity_landing_page.xml new file mode 100644 index 0000000..dccd9fd --- /dev/null +++ b/app/src/main/res/layout/activity_landing_page.xml @@ -0,0 +1,16 @@ + + + +