diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..a47b068 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,30 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 24 + buildToolsVersion "24.0.1" + defaultConfig { + applicationId "com.rendecano.cashmoney" + minSdkVersion 22 + targetSdkVersion 24 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + exclude group: 'com.android.support', module: 'support-annotations' + }) + compile 'com.android.support:appcompat-v7:24.2.0' + compile 'com.android.support:design:24.2.0' + testCompile 'junit:junit:4.12' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..b67ad41 --- /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/frascellaclaudio/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/com/rendecano/cashmoney/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/rendecano/cashmoney/ExampleInstrumentedTest.java new file mode 100644 index 0000000..c6db17b --- /dev/null +++ b/app/src/androidTest/java/com/rendecano/cashmoney/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.rendecano.cashmoney; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.rendecano.cashmoney", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..65b83b9 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/rendecano/cashmoney/data/entity/Base.java b/app/src/main/java/com/rendecano/cashmoney/data/entity/Base.java new file mode 100644 index 0000000..1fb8fb3 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/data/entity/Base.java @@ -0,0 +1,39 @@ +package com.rendecano.cashmoney.data.entity; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Ren Decano. + */ + +public class Base { + + private String base; + private String date; + private List rates = new ArrayList<>(); + + public String getBase() { + return base; + } + + public void setBase(String base) { + this.base = base; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public List getRates() { + return rates; + } + + public void setRates(List rates) { + this.rates = rates; + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/data/entity/Rate.java b/app/src/main/java/com/rendecano/cashmoney/data/entity/Rate.java new file mode 100644 index 0000000..5d65353 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/data/entity/Rate.java @@ -0,0 +1,27 @@ +package com.rendecano.cashmoney.data.entity; + +/** + * Created by Ren Decano. + */ + +public class Rate { + + private String currency; + private double conversion; + + public double getConversion() { + return conversion; + } + + public void setConversion(double conversion) { + this.conversion = conversion; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/data/entity/mapper/BaseEntityJsonMapper.java b/app/src/main/java/com/rendecano/cashmoney/data/entity/mapper/BaseEntityJsonMapper.java new file mode 100755 index 0000000..56b384b --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/data/entity/mapper/BaseEntityJsonMapper.java @@ -0,0 +1,54 @@ +package com.rendecano.cashmoney.data.entity.mapper; + +import com.rendecano.cashmoney.data.entity.Base; +import com.rendecano.cashmoney.data.entity.Rate; + +import org.json.JSONException; +import org.json.JSONObject; + +public class BaseEntityJsonMapper { + + public Base transformBaseEntity(String jsonResponse) throws JSONException { + + Base entity = new Base(); + + JSONObject jsonObject = new JSONObject(jsonResponse); + + String base = jsonObject.optString("base"); + String date = jsonObject.optString("date"); + + entity.setBase(base); + entity.setDate(date); + + // Get rates + JSONObject rates = jsonObject.getJSONObject("rates"); + + Rate rateCad = new Rate(); + rateCad.setCurrency("CAD"); + rateCad.setConversion(rates.optDouble("CAD")); + + Rate rateGbp = new Rate(); + rateGbp.setCurrency("GBP"); + rateGbp.setConversion(rates.optDouble("GBP")); + + Rate rateJpy = new Rate(); + rateJpy.setCurrency("JPY"); + rateJpy.setConversion(rates.optDouble("JPY")); + + Rate rateUsd = new Rate(); + rateUsd.setCurrency("USD"); + rateUsd.setConversion(rates.optDouble("USD")); + + Rate rateEur = new Rate(); + rateEur.setCurrency("EUR"); + rateEur.setConversion(rates.optDouble("EUR")); + + entity.getRates().add(rateCad); + entity.getRates().add(rateGbp); + entity.getRates().add(rateJpy); + entity.getRates().add(rateUsd); + entity.getRates().add(rateEur); + + return entity; + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/data/local/SharedPrefStorage.java b/app/src/main/java/com/rendecano/cashmoney/data/local/SharedPrefStorage.java new file mode 100644 index 0000000..fb184f0 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/data/local/SharedPrefStorage.java @@ -0,0 +1,42 @@ +package com.rendecano.cashmoney.data.local; + +import android.content.Context; +import android.content.SharedPreferences; +import android.text.TextUtils; + +import com.rendecano.cashmoney.data.entity.Base; +import com.rendecano.cashmoney.data.entity.Rate; +import com.rendecano.cashmoney.presentation.AndroidApplication; + +public class SharedPrefStorage { + + public static final String PREFS_NAME = "CASH_MONEY_PREFS"; + SharedPreferences prefs; + + public SharedPrefStorage(Context pContext) { + prefs = pContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + } + + public void saveCurrencyConversions(Base pBase) { + + savePreference("BASE", pBase.getBase()); + savePreference("DATE", pBase.getDate()); + + if (pBase.getRates().size() > 0) { + for (Rate rate : pBase.getRates()) { + savePreference(rate.getCurrency(), String.valueOf(rate.getConversion())); + } + } + } + + public double getConversion(String pCurrency) { + String conversion = prefs.getString(pCurrency, ""); + return Double.valueOf(conversion); + } + + private void savePreference(String key, String value) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(key, value); + editor.commit(); + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/data/network/ApiConnection.java b/app/src/main/java/com/rendecano/cashmoney/data/network/ApiConnection.java new file mode 100755 index 0000000..8cca664 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/data/network/ApiConnection.java @@ -0,0 +1,76 @@ +package com.rendecano.cashmoney.data.network; + +import android.os.AsyncTask; +import android.text.TextUtils; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +public class ApiConnection { + + private static final String CONTENT_TYPE_LABEL = "Content-Type"; + private static final String CONTENT_TYPE_VALUE_JSON = "application/json;charset=utf-8"; + + private URL url; + private JsonResponseListener mListener; + + public static ApiConnection createGET(String url, JsonResponseListener listener) throws MalformedURLException { + return new ApiConnection(url, listener); + } + + private ApiConnection(String url, JsonResponseListener listener) throws MalformedURLException { + this.url = new URL(url); + this.mListener = listener; + } + + public void call() { + new RestConnectionTask().execute(url); + } + + class RestConnectionTask extends AsyncTask { + + @Override + protected String doInBackground(URL... params) { + String currencies = ""; + HttpURLConnection urlConnection; + try { + + urlConnection = (HttpURLConnection) params[0].openConnection(); + + InputStream stream = new BufferedInputStream(urlConnection.getInputStream()); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); + StringBuilder builder = new StringBuilder(); + + String inputString; + while ((inputString = bufferedReader.readLine()) != null) { + builder.append(inputString); + } + + currencies = builder.toString(); + urlConnection.disconnect(); + + } catch (IOException e) { + e.printStackTrace(); + mListener.onError("Error in getting response"); + } + return currencies; + } + + @Override + protected void onPostExecute(String response) { + + // Check if response is not empty + if (!TextUtils.isEmpty(response)) { + mListener.onSuccess(response); + } else { + mListener.onError("Error in getting response"); + } + } + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/data/network/JsonResponseListener.java b/app/src/main/java/com/rendecano/cashmoney/data/network/JsonResponseListener.java new file mode 100644 index 0000000..b97087f --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/data/network/JsonResponseListener.java @@ -0,0 +1,8 @@ +package com.rendecano.cashmoney.data.network; + +public interface JsonResponseListener { + + void onSuccess(String response); + + void onError(String message); +} diff --git a/app/src/main/java/com/rendecano/cashmoney/data/network/RestApi.java b/app/src/main/java/com/rendecano/cashmoney/data/network/RestApi.java new file mode 100755 index 0000000..7df1f9e --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/data/network/RestApi.java @@ -0,0 +1,8 @@ +package com.rendecano.cashmoney.data.network; + +public interface RestApi { + + String API_BASE_URL = "http://api.fixer.io/latest"; + + void getExchangeRate(String baseCurrency, String[] symbols, JsonResponseListener listener); +} diff --git a/app/src/main/java/com/rendecano/cashmoney/data/network/RestApiImpl.java b/app/src/main/java/com/rendecano/cashmoney/data/network/RestApiImpl.java new file mode 100755 index 0000000..962e4e2 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/data/network/RestApiImpl.java @@ -0,0 +1,57 @@ +package com.rendecano.cashmoney.data.network; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +import java.net.MalformedURLException; + +public class RestApiImpl implements RestApi { + + private final Context context; + private JsonResponseListener mJsonResponseListener; + + public RestApiImpl(Context context) { + if (context == null) { + throw new IllegalArgumentException("The constructor parameters cannot be null."); + } + this.context = context.getApplicationContext(); + } + + @Override + public void getExchangeRate(String baseCurrency, String[] symbols, JsonResponseListener listener) { + mJsonResponseListener = listener; + + if (isThereInternetConnection()) { + try { + getExchangeRatesFromApi(baseCurrency, symbols); + } catch (MalformedURLException e) { + mJsonResponseListener.onError("Malformed URL"); + } + + } else { + mJsonResponseListener.onError("No internet connection detected"); + } + } + + private void getExchangeRatesFromApi(String baseCurrency, String[] symbols) throws MalformedURLException { + String apiUrl = RestApi.API_BASE_URL + "?base=" + baseCurrency + "&symbols="; + + for (String symbol : symbols) { + apiUrl += symbol + ","; + } + + ApiConnection.createGET(apiUrl, mJsonResponseListener).call(); + } + + private boolean isThereInternetConnection() { + boolean isConnected; + + ConnectivityManager connectivityManager = + (ConnectivityManager) this.context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); + isConnected = (networkInfo != null && networkInfo.isConnectedOrConnecting()); + + return isConnected; + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/data/repository/ConvertDataRepository.java b/app/src/main/java/com/rendecano/cashmoney/data/repository/ConvertDataRepository.java new file mode 100644 index 0000000..6a011be --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/data/repository/ConvertDataRepository.java @@ -0,0 +1,75 @@ +package com.rendecano.cashmoney.data.repository; + +import com.rendecano.cashmoney.data.entity.Base; +import com.rendecano.cashmoney.data.entity.mapper.BaseEntityJsonMapper; +import com.rendecano.cashmoney.data.local.SharedPrefStorage; +import com.rendecano.cashmoney.data.network.JsonResponseListener; +import com.rendecano.cashmoney.data.network.RestApi; +import com.rendecano.cashmoney.data.network.RestApiImpl; +import com.rendecano.cashmoney.domain.ConvertRepository; +import com.rendecano.cashmoney.domain.subscriber.UseCaseSubscriber; +import com.rendecano.cashmoney.presentation.AndroidApplication; + +import org.json.JSONException; + +/** + * Created by Ren Decano. + */ + +public class ConvertDataRepository implements ConvertRepository { + + private RestApi restApi; + private SharedPrefStorage sharedPrefStorage; + private final String BASE_CURRENCY = "AUD"; + private final String[] CURRENCIES = {"CAD", "EUR", "GBP", "JPY", "USD"}; + + public ConvertDataRepository() { + restApi = new RestApiImpl(AndroidApplication.getApplicationInstance()); + sharedPrefStorage = new SharedPrefStorage(AndroidApplication.getApplicationInstance()); + } + + @Override + public void initialValues(final UseCaseSubscriber subscriber) { + + // Get values from network + restApi.getExchangeRate(BASE_CURRENCY, CURRENCIES, new JsonResponseListener() { + + @Override + public void onSuccess(String response) { + + // Create json to object mapper + BaseEntityJsonMapper baseEntityJsonMapper = new BaseEntityJsonMapper(); + + try { + // Convert to Base object + Base base = baseEntityJsonMapper.transformBaseEntity(response); + + // Save details to Shared preferences for conversion usage + sharedPrefStorage.saveCurrencyConversions(base); + + subscriber.onNext(base); + + } catch (JSONException e) { + subscriber.onError("JSON Exception"); + } + } + + @Override + public void onError(String message) { + subscriber.onError(message); + } + }); + } + + @Override + public void getConvertedCurrency(double pValue, String symbol, UseCaseSubscriber subscriber) { + + // Get value from shared preferences + double value = sharedPrefStorage.getConversion(symbol); + + // Format to correct currency + String formattedValue = String.valueOf(value * pValue); + + subscriber.onNext(formattedValue); + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/domain/ConvertRepository.java b/app/src/main/java/com/rendecano/cashmoney/domain/ConvertRepository.java new file mode 100644 index 0000000..019aee0 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/domain/ConvertRepository.java @@ -0,0 +1,16 @@ +package com.rendecano.cashmoney.domain; + +import com.rendecano.cashmoney.data.entity.Base; +import com.rendecano.cashmoney.domain.subscriber.UseCaseSubscriber; + +/** + * Created by Ren Decano. + */ + +public interface ConvertRepository { + + void initialValues(UseCaseSubscriber subscriber); + + void getConvertedCurrency(double pValue, String symbol, UseCaseSubscriber subscriber); + +} diff --git a/app/src/main/java/com/rendecano/cashmoney/domain/interactor/ConvertUseCase.java b/app/src/main/java/com/rendecano/cashmoney/domain/interactor/ConvertUseCase.java new file mode 100644 index 0000000..1001fde --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/domain/interactor/ConvertUseCase.java @@ -0,0 +1,28 @@ +package com.rendecano.cashmoney.domain.interactor; + +import com.rendecano.cashmoney.data.entity.Base; +import com.rendecano.cashmoney.data.repository.ConvertDataRepository; +import com.rendecano.cashmoney.domain.ConvertRepository; +import com.rendecano.cashmoney.domain.subscriber.UseCaseSubscriber; + +/** + * Created by Ren Decano. + */ + +public class ConvertUseCase { + + private ConvertRepository repository; + + public ConvertUseCase() { + repository = new ConvertDataRepository(); + } + + public void getInitialValues(UseCaseSubscriber subscriber) { + repository.initialValues(subscriber); + } + + public void convertCurrency(double pValue, String symbol, UseCaseSubscriber subscriber) { + repository.getConvertedCurrency(pValue, symbol, subscriber); + } + +} diff --git a/app/src/main/java/com/rendecano/cashmoney/domain/subscriber/UseCaseSubscriber.java b/app/src/main/java/com/rendecano/cashmoney/domain/subscriber/UseCaseSubscriber.java new file mode 100644 index 0000000..f23f6bc --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/domain/subscriber/UseCaseSubscriber.java @@ -0,0 +1,13 @@ +package com.rendecano.cashmoney.domain.subscriber; + +/** + * Created by Ren Decano. + */ +public abstract class UseCaseSubscriber { + + public void onError(String message) { + } + + public void onNext(T t) { + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/presentation/AndroidApplication.java b/app/src/main/java/com/rendecano/cashmoney/presentation/AndroidApplication.java new file mode 100644 index 0000000..a5841d9 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/presentation/AndroidApplication.java @@ -0,0 +1,23 @@ +package com.rendecano.cashmoney.presentation; + +import android.app.Application; +import android.content.Context; + +/** + * Created by Ren Decano. + */ + +public class AndroidApplication extends Application { + + private static AndroidApplication instance; + + @Override + public void onCreate() { + super.onCreate(); + instance = this; + } + + public static Context getApplicationInstance() { + return instance; + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/presentation/activity/CashMoneyActivity.java b/app/src/main/java/com/rendecano/cashmoney/presentation/activity/CashMoneyActivity.java new file mode 100644 index 0000000..090a6da --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/presentation/activity/CashMoneyActivity.java @@ -0,0 +1,16 @@ +package com.rendecano.cashmoney.presentation.activity; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; + +import com.rendecano.cashmoney.R; + +public class CashMoneyActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_cash_money); + + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/presentation/adapter/CurrencyPagerAdapter.java b/app/src/main/java/com/rendecano/cashmoney/presentation/adapter/CurrencyPagerAdapter.java new file mode 100644 index 0000000..cc78649 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/presentation/adapter/CurrencyPagerAdapter.java @@ -0,0 +1,62 @@ +package com.rendecano.cashmoney.presentation.adapter; + +import android.content.Context; +import android.support.v4.view.PagerAdapter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.rendecano.cashmoney.R; +import com.rendecano.cashmoney.data.entity.Rate; + +import java.util.List; + +/** + * Created by Ren Decano. + */ + +public class CurrencyPagerAdapter extends PagerAdapter { + + private Context mContext; + private List mRates; + + public CurrencyPagerAdapter(Context context, List rates) { + mContext = context; + this.mRates = rates; + } + + @Override + public Object instantiateItem(ViewGroup collection, int position) { + + LayoutInflater inflater = LayoutInflater.from(mContext); + ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.view_rate_item, collection, false); + + TextView txtCurrency = (TextView) layout.findViewById(R.id.txtCurrency); + txtCurrency.setText(mRates.get(position).getCurrency()); + + collection.addView(layout); + return layout; + } + + @Override + public void destroyItem(ViewGroup collection, int position, Object view) { + collection.removeView((View) view); + } + + @Override + public int getCount() { + return mRates.size(); + } + + @Override + public boolean isViewFromObject(View view, Object object) { + return view == object; + } + + @Override + public CharSequence getPageTitle(int position) { + + return mRates.get(position).getCurrency(); + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/presentation/fragment/CashMoneyFragment.java b/app/src/main/java/com/rendecano/cashmoney/presentation/fragment/CashMoneyFragment.java new file mode 100644 index 0000000..6421ba5 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/presentation/fragment/CashMoneyFragment.java @@ -0,0 +1,104 @@ +package com.rendecano.cashmoney.presentation.fragment; + +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.os.Bundle; +import android.support.v4.view.ViewPager; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import com.rendecano.cashmoney.R; +import com.rendecano.cashmoney.data.entity.Base; +import com.rendecano.cashmoney.presentation.adapter.CurrencyPagerAdapter; +import com.rendecano.cashmoney.presentation.presenter.CashMoneyPresenter; +import com.rendecano.cashmoney.presentation.presenter.view.CashMoneyView; + +public class CashMoneyFragment extends Fragment implements CashMoneyView, ViewPager.OnPageChangeListener { + + private View mView; + private TextView mTxtBase; + private TextView mTxtRate; + private EditText mEtConvert; + private CashMoneyPresenter mPresenter; + private ViewPager mViewPager; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + mView = inflater.inflate(R.layout.fragment_cash_money, container, false); + + mTxtBase = (TextView) mView.findViewById(R.id.txtBase); + mTxtRate = (TextView) mView.findViewById(R.id.txtRate); + mEtConvert = (EditText) mView.findViewById(R.id.etConvert); + mViewPager = (ViewPager) mView.findViewById(R.id.viewpager); + + mViewPager.setOnPageChangeListener(this); + return mView; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mPresenter = new CashMoneyPresenter(); + mPresenter.attachView(this); + mPresenter.initialize(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + mPresenter.destroy(); + } + + @Override + public void initialValues(Base base) { + mTxtBase.setText(base.getBase()); + + mViewPager.setAdapter(new CurrencyPagerAdapter(getActivity(), base.getRates())); + + } + + @Override + public void showConvertedRate(String pValue) { + mTxtRate.setText(pValue); + } + + @Override + public void showError(String message) { + Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show(); + } + + @Override + public void showLoading() { + + } + + @Override + public void hideLoading() { + + } + + + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + String currency = mViewPager.getAdapter().getPageTitle(position).toString(); + + Toast.makeText(getActivity(), currency, Toast.LENGTH_LONG).show(); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/CashMoneyPresenter.java b/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/CashMoneyPresenter.java new file mode 100644 index 0000000..8f595e0 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/CashMoneyPresenter.java @@ -0,0 +1,67 @@ +package com.rendecano.cashmoney.presentation.presenter; + +import com.rendecano.cashmoney.data.entity.Base; +import com.rendecano.cashmoney.domain.interactor.ConvertUseCase; +import com.rendecano.cashmoney.domain.subscriber.UseCaseSubscriber; +import com.rendecano.cashmoney.presentation.presenter.view.CashMoneyView; + +/** + * Created by Ren Decano. + */ +public class CashMoneyPresenter implements Presenter { + + private CashMoneyView moneyView; + private ConvertUseCase useCase; + + public CashMoneyPresenter() { + useCase = new ConvertUseCase(); + } + + public void initialize() { + moneyView.showLoading(); + useCase.getInitialValues(new GetDefaultValuesSubscriber()); + } + + public void convertCurrency(double pValue, String pSymbol) { + useCase.convertCurrency(pValue, pSymbol, new ConvertSubscriber()); + } + + @Override + public void attachView(CashMoneyView view) { + moneyView = view; + } + + @Override + public void destroy() { + moneyView = null; + useCase = null; + } + + private class GetDefaultValuesSubscriber extends UseCaseSubscriber { + + @Override + public void onError(String message) { + moneyView.hideLoading(); + moneyView.showError(message); + } + + @Override + public void onNext(Base base) { + moneyView.hideLoading(); + moneyView.initialValues(base); + } + } + + private class ConvertSubscriber extends UseCaseSubscriber { + + @Override + public void onError(String message) { + moneyView.showError(message); + } + + @Override + public void onNext(String pRate) { + moneyView.showConvertedRate(pRate); + } + } +} diff --git a/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/Presenter.java b/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/Presenter.java new file mode 100644 index 0000000..89f8601 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/Presenter.java @@ -0,0 +1,15 @@ +package com.rendecano.cashmoney.presentation.presenter; + +import com.rendecano.cashmoney.presentation.presenter.view.DefaultView; + +/** + * Created by Ren Decano. + */ + +public interface Presenter { + + void attachView(T view); + + void destroy(); + +} diff --git a/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/view/CashMoneyView.java b/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/view/CashMoneyView.java new file mode 100644 index 0000000..2026680 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/view/CashMoneyView.java @@ -0,0 +1,15 @@ +package com.rendecano.cashmoney.presentation.presenter.view; + +import com.rendecano.cashmoney.data.entity.Base; + +/** + * Created by Ren Decano. + */ + +public interface CashMoneyView extends DefaultView { + + void initialValues(Base base); + + void showConvertedRate(String pValue); + +} diff --git a/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/view/DefaultView.java b/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/view/DefaultView.java new file mode 100644 index 0000000..81730d8 --- /dev/null +++ b/app/src/main/java/com/rendecano/cashmoney/presentation/presenter/view/DefaultView.java @@ -0,0 +1,12 @@ +package com.rendecano.cashmoney.presentation.presenter.view; + +/** + * Created by Ren Decano. + */ + +public interface DefaultView { + + void showError(String message); + void showLoading(); + void hideLoading(); +} diff --git a/app/src/main/res/drawable-hdpi/ic_indicator_down.png b/app/src/main/res/drawable-hdpi/ic_indicator_down.png new file mode 100644 index 0000000..c04a477 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_indicator_down.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_indicator_up.png b/app/src/main/res/drawable-hdpi/ic_indicator_up.png new file mode 100644 index 0000000..73f830f Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_indicator_up.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_logo.png b/app/src/main/res/drawable-hdpi/ic_logo.png new file mode 100644 index 0000000..301afd2 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_logo.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_indicator_down.png b/app/src/main/res/drawable-xhdpi/ic_indicator_down.png new file mode 100644 index 0000000..eed20e1 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_indicator_down.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_indicator_up.png b/app/src/main/res/drawable-xhdpi/ic_indicator_up.png new file mode 100644 index 0000000..f44dfde Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_indicator_up.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_logo.png b/app/src/main/res/drawable-xhdpi/ic_logo.png new file mode 100644 index 0000000..90b3bfb Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_logo.png differ diff --git a/app/src/main/res/layout/activity_cash_money.xml b/app/src/main/res/layout/activity_cash_money.xml new file mode 100644 index 0000000..6aa26fb --- /dev/null +++ b/app/src/main/res/layout/activity_cash_money.xml @@ -0,0 +1,9 @@ + diff --git a/app/src/main/res/layout/fragment_cash_money.xml b/app/src/main/res/layout/fragment_cash_money.xml new file mode 100644 index 0000000..d79e93a --- /dev/null +++ b/app/src/main/res/layout/fragment_cash_money.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/view_rate_item.xml b/app/src/main/res/layout/view_rate_item.xml new file mode 100644 index 0000000..21b814d --- /dev/null +++ b/app/src/main/res/layout/view_rate_item.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/app/src/main/res/menu/menu_cash_money.xml b/app/src/main/res/menu/menu_cash_money.xml new file mode 100644 index 0000000..20b4acc --- /dev/null +++ b/app/src/main/res/menu/menu_cash_money.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..cde69bc Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_logo.png b/app/src/main/res/mipmap-hdpi/ic_logo.png new file mode 100644 index 0000000..301afd2 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_logo.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..c133a0c Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..bfa42f0 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..324e72c Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..aee44e1 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml new file mode 100644 index 0000000..dbbdd40 --- /dev/null +++ b/app/src/main/res/values-v21/styles.xml @@ -0,0 +1,9 @@ + + + + diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml new file mode 100644 index 0000000..63fc816 --- /dev/null +++ b/app/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..9cc2239 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,8 @@ + + + #3ACF82 + #3ACF82 + #FF4081 + + #FFFFFF + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..812cb7b --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,6 @@ + + + 16dp + 16dp + 16dp + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..9db2da4 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + CashMoney + Settings + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..545b9c6 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,20 @@ + + + + + + + +