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..19b6dda
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,38 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 24
+ buildToolsVersion "25.0.0"
+ defaultConfig {
+ applicationId "com.akilloren.t2modus_android_test"
+ minSdkVersion 16
+ 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.1'
+ compile 'com.android.support.constraint:constraint-layout:1.0.0-beta3'
+ compile 'com.android.support:design:24.2.1'
+ compile 'com.android.support:recyclerview-v7:24.2.1'
+ compile 'com.squareup.picasso:picasso:2.5.2'
+ compile 'com.google.code.gson:gson:2.6.1'
+ compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
+ compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
+ compile 'com.squareup.okhttp:okhttp:2.4.0'
+ compile 'com.android.support:cardview-v7:24.2.1'
+ testCompile 'junit:junit:4.12'
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..8094279
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/alank/Android/Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/androidTest/java/com/akilloren/t2modus_android_test/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/akilloren/t2modus_android_test/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..093d7c1
--- /dev/null
+++ b/app/src/androidTest/java/com/akilloren/t2modus_android_test/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.akilloren.t2modus_android_test;
+
+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.akilloren.t2modus_android_test", appContext.getPackageName());
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..069b508
--- /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/akilloren/t2modus_android_test/activity/DetailActivity.java b/app/src/main/java/com/akilloren/t2modus_android_test/activity/DetailActivity.java
new file mode 100644
index 0000000..a86b65d
--- /dev/null
+++ b/app/src/main/java/com/akilloren/t2modus_android_test/activity/DetailActivity.java
@@ -0,0 +1,206 @@
+package com.akilloren.t2modus_android_test.activity;
+
+import android.app.ProgressDialog;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.MenuItem;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.akilloren.t2modus_android_test.R;
+import com.akilloren.t2modus_android_test.misc.AppConst;
+import com.akilloren.t2modus_android_test.model.Friend;
+import com.akilloren.t2modus_android_test.views.CircleTransform;
+import com.squareup.okhttp.Callback;
+import com.squareup.okhttp.OkHttpClient;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.Response;
+import com.squareup.picasso.Picasso;
+
+import org.json.JSONObject;
+
+import java.io.IOException;
+
+public class DetailActivity extends AppCompatActivity {
+
+ private ImageView personPhoto;
+ private TextView personName;
+ private TextView personStatus;
+ private TextView personContactInfo;
+ private TextView personBioInfo;
+ private ProgressDialog progressDialog;
+ private ImageView statusIndicator;
+
+ @SuppressWarnings("ConstantConditions")
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_detail);
+
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
+ initViews();
+
+ // get id from intent and call server to get details
+ if (getIntent().hasExtra("id")) {
+ int id = getIntent().getIntExtra("id", -1);
+ if (id > -1) {
+ getFriendDetails(id);
+ }
+ }
+
+ //get passed in status text for display since we don't get it from the details
+ if (getIntent().hasExtra("status")) {
+ personStatus.setText(getIntent().getStringExtra("status"));
+ }
+ }
+
+ /**
+ * Initialize the views used in this activity
+ */
+ private void initViews() {
+
+ progressDialog = new ProgressDialog(this);
+ personPhoto = (ImageView) findViewById(R.id.personPhoto);
+ personName = (TextView) findViewById(R.id.personName);
+ personStatus = (TextView) findViewById(R.id.personStatus);
+ personContactInfo = (TextView) findViewById(R.id.personContactInfo);
+ personBioInfo = (TextView) findViewById(R.id.personBioInfo);
+ statusIndicator = (ImageView) findViewById(R.id.status_indicator);
+ }
+
+ /**
+ * Calls server API and returns details for a person - Uses OKHttpClient to save TONS of repetitive HTTP coding
+ *
+ * @param id Integer value representing the id of the person
+ */
+ private void getFriendDetails(final int id) {
+
+ new AsyncTask() {
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ showProgress(getString(R.string.text_loading));
+ }
+
+ @Override
+ protected Response doInBackground(String... strings) {
+ OkHttpClient client = new OkHttpClient();
+ Response response;
+ Request request = new Request.Builder().url(AppConst.BASE_FRIENDS_API_URL + "/" + id).build();
+
+ try {
+ response = client.newCall(request).execute();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ return response;
+ }
+
+ @Override
+ protected void onPostExecute(Response response) {
+ super.onPostExecute(response);
+ hideProgress();
+
+ if (response != null) {
+ String sResponse;
+ try {
+ sResponse = response.body().string();
+
+ //parse JSON
+ parseJSON(sResponse);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }.execute();
+ }
+
+ /**
+ * Helper method to parse thru returned JSON and populate Friend object
+ *
+ * @param json JSON String to parse
+ */
+ private void parseJSON(String json) {
+
+ try {
+ JSONObject jObj = new JSONObject(json);
+ Friend friend = new Friend();
+ friend.setFirst_name(jObj.getString("first_name"));
+ friend.setLast_name(jObj.getString("last_name"));
+ friend.setImg(jObj.getString("img"));
+ friend.setPhone(jObj.getString("phone"));
+ friend.setAddress_1(jObj.getString("address_1"));
+ friend.setCity(jObj.getString("city"));
+ friend.setState(jObj.getString("state"));
+ friend.setZipcode(jObj.getString("zipcode"));
+ friend.setBio(jObj.getString("bio"));
+ friend.setAvailable(jObj.getBoolean("available"));
+
+ //update UI
+ updateUI(friend);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Helper method to update views with data from Friend object
+ *
+ * @param friend Friend object
+ */
+ private void updateUI(Friend friend) {
+
+ Picasso.with(this).load(friend.getImg())
+ .transform(new CircleTransform())
+ .error(R.drawable.placeholder)
+ .placeholder(R.drawable.placeholder)
+ .into(personPhoto);
+ personName.setText(friend.getFirst_name() + " " + friend.getLast_name());
+ personContactInfo.setText(friend.getAddress_1()
+ + "\n" + friend.getCity()
+ + ", " + friend.getState().toUpperCase()
+ + " " + friend.getZipcode()
+ + "\n" + friend.getPhone());
+ personBioInfo.setText(friend.getBio());
+ if (friend.isAvailable()) {
+ statusIndicator.setImageResource(R.drawable.online);
+ } else {
+ statusIndicator.setImageResource(R.drawable.offline);
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+
+ if (item.getItemId() == android.R.id.home) {
+ finish();
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ /**
+ * Show a progress dialog
+ *
+ * @param msg String message to display
+ */
+ private void showProgress(String msg) {
+
+ progressDialog.setMessage(msg);
+ progressDialog.show();
+ }
+
+ /**
+ * Hide progress dialog
+ */
+ private void hideProgress() {
+ progressDialog.dismiss();
+ }
+}
diff --git a/app/src/main/java/com/akilloren/t2modus_android_test/activity/MainActivity.java b/app/src/main/java/com/akilloren/t2modus_android_test/activity/MainActivity.java
new file mode 100644
index 0000000..0c8fefd
--- /dev/null
+++ b/app/src/main/java/com/akilloren/t2modus_android_test/activity/MainActivity.java
@@ -0,0 +1,118 @@
+package com.akilloren.t2modus_android_test.activity;
+
+import android.app.ProgressDialog;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.akilloren.t2modus_android_test.R;
+import com.akilloren.t2modus_android_test.adapter.FriendAdapter;
+import com.akilloren.t2modus_android_test.api.RetrofitAPI;
+import com.akilloren.t2modus_android_test.misc.AppConst;
+import com.akilloren.t2modus_android_test.model.Friend;
+
+import java.util.List;
+
+import retrofit.Call;
+import retrofit.Callback;
+import retrofit.GsonConverterFactory;
+import retrofit.Response;
+import retrofit.Retrofit;
+
+public class MainActivity extends AppCompatActivity {
+
+ private Call> call;
+ private RecyclerView recyclerView;
+ private FriendAdapter adapter;
+ private List friends;
+ private ProgressDialog progressDialog;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ initViews();
+ getData();
+ }
+
+ /**
+ * Initialize all the views that will be used in this activity
+ */
+ private void initViews() {
+
+ progressDialog = new ProgressDialog(this);
+ LinearLayoutManager llm = new LinearLayoutManager(this);
+ recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
+ recyclerView.setLayoutManager(llm);
+ recyclerView.setHasFixedSize(true);
+
+ //The following line can be uncommented if you are not using a CardView in the layout and just want a regular "listview"
+ //recyclerView.addItemDecoration(new SimpleDividerItemDecoration(getApplicationContext()));
+ }
+
+ /**
+ * Calls server API and returns populated list from JSON - Uses Retrofit/GSON in one call
+ */
+ private void getData() {
+
+ Log.i(AppConst.TAG, "Getting data using Retrofit...");
+ showProgress(getString(R.string.text_loading));
+
+ Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl(AppConst.BASE_API_URL)
+ .addConverterFactory(GsonConverterFactory.create())
+ .build();
+ RetrofitAPI service = retrofit.create(RetrofitAPI.class);
+
+ call = service.getFriendList();
+ call.enqueue(new Callback>() {
+
+ @Override
+ public void onResponse(Response> response, Retrofit retrofit) {
+ hideProgress();
+ friends = response.body();
+ if (friends != null && friends.size() > 0) {
+ getAdapter();
+ Log.i(AppConst.TAG, "Data received and list populated.");
+ }
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ hideProgress();
+ Toast.makeText(MainActivity.this, "Problem occurred while retrieving data", Toast.LENGTH_SHORT).show();
+ Log.e(AppConst.TAG, "Failed to receive data using Retrofit");
+ }
+ });
+ }
+
+ /**
+ * Initializes the data adapter
+ */
+ private void getAdapter() {
+
+ adapter = new FriendAdapter(this, friends);
+ recyclerView.setAdapter(adapter);
+ }
+
+ @Override
+ protected void onDestroy() {
+
+ super.onDestroy();
+ call.cancel();//cancel any calls to the server if we exit
+ }
+
+ private void showProgress(String msg) {
+
+ progressDialog.setMessage(msg);
+ progressDialog.show();
+ }
+
+ private void hideProgress() {
+ progressDialog.dismiss();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/akilloren/t2modus_android_test/adapter/FriendAdapter.java b/app/src/main/java/com/akilloren/t2modus_android_test/adapter/FriendAdapter.java
new file mode 100644
index 0000000..ee15c40
--- /dev/null
+++ b/app/src/main/java/com/akilloren/t2modus_android_test/adapter/FriendAdapter.java
@@ -0,0 +1,96 @@
+package com.akilloren.t2modus_android_test.adapter;
+
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.akilloren.t2modus_android_test.R;
+import com.akilloren.t2modus_android_test.activity.DetailActivity;
+import com.akilloren.t2modus_android_test.model.Friend;
+import com.akilloren.t2modus_android_test.views.CircleTransform;
+import com.squareup.picasso.Picasso;
+
+import java.util.List;
+
+/**
+ * RecyclerView adapter - holds the data for the Friends list
+ *
+ * @author alank
+ */
+
+public class FriendAdapter extends RecyclerView.Adapter {
+
+ private List friends;
+ private Context context;
+
+ public FriendAdapter(Context context, List friends) {
+ this.friends = friends;
+ this.context = context;
+ }
+
+ class FriendViewHolder extends RecyclerView.ViewHolder {
+
+ TextView friendName;
+ TextView friendStatus;
+ ImageView friendPhoto;
+ ImageView statusIndicator;
+ View mRootView;
+
+ FriendViewHolder(View itemView) {
+ super(itemView);
+ friendName = (TextView) itemView.findViewById(R.id.full_name);
+ friendStatus = (TextView) itemView.findViewById(R.id.status);
+ friendPhoto = (ImageView) itemView.findViewById(R.id.personimage);
+ statusIndicator = (ImageView) itemView.findViewById(R.id.status_indicator);
+ mRootView = itemView;
+ }
+ }
+
+ @Override
+ public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+ super.onAttachedToRecyclerView(recyclerView);
+ }
+
+ @Override
+ public FriendViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
+ View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item, viewGroup, false);
+ return new FriendViewHolder(v);
+ }
+
+ @Override
+ public void onBindViewHolder(FriendViewHolder friendViewHolder, int i) {
+ final Friend friend = friends.get(i);
+ friendViewHolder.friendName.setText(friend.getFirst_name() + " " + friend.getLast_name());
+ friendViewHolder.friendStatus.setText(friend.getStatus());
+ if (friend.isAvailable()) {
+ friendViewHolder.statusIndicator.setImageResource(R.drawable.online);
+ } else {
+ friendViewHolder.statusIndicator.setImageResource(R.drawable.offline);
+ }
+ Picasso.with(context).load(friend.getImg())
+ .transform(new CircleTransform())
+ .error(R.drawable.placeholder)
+ .placeholder(R.drawable.placeholder)
+ .into(friendViewHolder.friendPhoto);
+
+ friendViewHolder.mRootView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(context, DetailActivity.class);
+ intent.putExtra("id", friend.getId());
+ intent.putExtra("status",friend.getStatus());
+ context.startActivity(intent);
+ }
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return friends.size();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/akilloren/t2modus_android_test/api/RetrofitAPI.java b/app/src/main/java/com/akilloren/t2modus_android_test/api/RetrofitAPI.java
new file mode 100644
index 0000000..337d880
--- /dev/null
+++ b/app/src/main/java/com/akilloren/t2modus_android_test/api/RetrofitAPI.java
@@ -0,0 +1,23 @@
+package com.akilloren.t2modus_android_test.api;
+
+
+import com.akilloren.t2modus_android_test.model.Friend;
+
+import java.util.List;
+
+import retrofit.Call;
+import retrofit.http.GET;
+
+/**
+ * The Retrofit interface and endpoint definintions
+ * @author alank
+ */
+
+public interface RetrofitAPI {
+
+ @GET("friends")
+ Call> getFriendList();
+
+ //add more endpoints/calls here
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/akilloren/t2modus_android_test/misc/AppConst.java b/app/src/main/java/com/akilloren/t2modus_android_test/misc/AppConst.java
new file mode 100644
index 0000000..4896f84
--- /dev/null
+++ b/app/src/main/java/com/akilloren/t2modus_android_test/misc/AppConst.java
@@ -0,0 +1,15 @@
+package com.akilloren.t2modus_android_test.misc;
+
+/**
+ * Miscellaneous constants
+ *
+ * @author alank
+ */
+
+public class AppConst {
+
+ public static String TAG = "T2ModusTest";
+ public static String BASE_API_URL = "https://private-c1b9f-t2mobile.apiary-mock.com";
+ public static String BASE_FRIENDS_API_URL = BASE_API_URL+ "/friends";
+
+}
diff --git a/app/src/main/java/com/akilloren/t2modus_android_test/model/Friend.java b/app/src/main/java/com/akilloren/t2modus_android_test/model/Friend.java
new file mode 100644
index 0000000..38b40a6
--- /dev/null
+++ b/app/src/main/java/com/akilloren/t2modus_android_test/model/Friend.java
@@ -0,0 +1,139 @@
+package com.akilloren.t2modus_android_test.model;
+
+import java.util.List;
+
+/**
+ * Friend data object
+ *
+ * @author alank
+ */
+
+public class Friend {
+
+ private int id;
+ private String img;
+ private String first_name;
+ private String last_name;
+ private String status;
+ private boolean available;
+ private String phone;
+ private String address_1;
+ private String city;
+ private String state;
+ private String zipcode;
+ private String bio;
+ private List photos;
+ private List statuses;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getImg() {
+ return img;
+ }
+
+ public void setImg(String img) {
+ this.img = img;
+ }
+
+ public String getFirst_name() {
+ return first_name;
+ }
+
+ public void setFirst_name(String first_name) {
+ this.first_name = first_name;
+ }
+
+ public String getLast_name() {
+ return last_name;
+ }
+
+ public void setLast_name(String last_name) {
+ this.last_name = last_name;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public boolean isAvailable() {
+ return available;
+ }
+
+ public void setAvailable(boolean available) {
+ this.available = available;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getAddress_1() {
+ return address_1;
+ }
+
+ public void setAddress_1(String address_1) {
+ this.address_1 = address_1;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getZipcode() {
+ return zipcode;
+ }
+
+ public void setZipcode(String zipcode) {
+ this.zipcode = zipcode;
+ }
+
+ public String getBio() {
+ return bio;
+ }
+
+ public void setBio(String bio) {
+ this.bio = bio;
+ }
+
+ public List getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(List photos) {
+ this.photos = photos;
+ }
+
+ public List getStatuses() {
+ return statuses;
+ }
+
+ public void setStatuses(List statuses) {
+ this.statuses = statuses;
+ }
+}
diff --git a/app/src/main/java/com/akilloren/t2modus_android_test/views/CircleTransform.java b/app/src/main/java/com/akilloren/t2modus_android_test/views/CircleTransform.java
new file mode 100644
index 0000000..e1ac28b
--- /dev/null
+++ b/app/src/main/java/com/akilloren/t2modus_android_test/views/CircleTransform.java
@@ -0,0 +1,49 @@
+package com.akilloren.t2modus_android_test.views;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+
+import com.squareup.picasso.Transformation;
+
+/**
+ * Creates a round image from a bitmap (for Picasso)
+ *
+ * @author alank
+ */
+
+public class CircleTransform implements Transformation {
+ @Override
+ public Bitmap transform(Bitmap source) {
+ int size = Math.min(source.getWidth(), source.getHeight());
+
+ int x = (source.getWidth() - size) / 2;
+ int y = (source.getHeight() - size) / 2;
+
+ Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
+ if (squaredBitmap != source) {
+ source.recycle();
+ }
+
+ Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
+
+ Canvas canvas = new Canvas(bitmap);
+ Paint paint = new Paint();
+ BitmapShader shader = new BitmapShader(squaredBitmap,
+ BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
+ paint.setShader(shader);
+ paint.setAntiAlias(true);
+
+ float r = size / 2f;
+ canvas.drawCircle(r, r, r, paint);
+
+ squaredBitmap.recycle();
+ return bitmap;
+ }
+
+ @Override
+ public String key() {
+ return "circle";
+ }
+}
diff --git a/app/src/main/java/com/akilloren/t2modus_android_test/views/SimpleDividerItemDecoration.java b/app/src/main/java/com/akilloren/t2modus_android_test/views/SimpleDividerItemDecoration.java
new file mode 100644
index 0000000..8bab6f8
--- /dev/null
+++ b/app/src/main/java/com/akilloren/t2modus_android_test/views/SimpleDividerItemDecoration.java
@@ -0,0 +1,40 @@
+package com.akilloren.t2modus_android_test.views;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+
+import com.akilloren.t2modus_android_test.R;
+
+/**
+ * Created by alank on 4/14/17.
+ */
+
+public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
+ private Drawable mDivider;
+
+ public SimpleDividerItemDecoration(Context context) {
+ mDivider = context.getResources().getDrawable(R.drawable.line_divider);
+ }
+
+ @Override
+ public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
+ int left = parent.getPaddingLeft();
+ int right = parent.getWidth() - parent.getPaddingRight();
+
+ int childCount = parent.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = parent.getChildAt(i);
+
+ RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
+
+ int top = child.getBottom() + params.bottomMargin;
+ int bottom = top + mDivider.getIntrinsicHeight();
+
+ mDivider.setBounds(left, top, right, bottom);
+ mDivider.draw(c);
+ }
+ }
+}
diff --git a/app/src/main/res/drawable/line_divider.xml b/app/src/main/res/drawable/line_divider.xml
new file mode 100644
index 0000000..fc4aca7
--- /dev/null
+++ b/app/src/main/res/drawable/line_divider.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/offline.xml b/app/src/main/res/drawable/offline.xml
new file mode 100644
index 0000000..32635da
--- /dev/null
+++ b/app/src/main/res/drawable/offline.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/online.xml b/app/src/main/res/drawable/online.xml
new file mode 100644
index 0000000..acbf92b
--- /dev/null
+++ b/app/src/main/res/drawable/online.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/placeholder.png b/app/src/main/res/drawable/placeholder.png
new file mode 100644
index 0000000..b51fd2a
Binary files /dev/null and b/app/src/main/res/drawable/placeholder.png differ
diff --git a/app/src/main/res/layout/activity_detail.xml b/app/src/main/res/layout/activity_detail.xml
new file mode 100644
index 0000000..cfbfd7f
--- /dev/null
+++ b/app/src/main/res/layout/activity_detail.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..5574ab6
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/list_item.xml b/app/src/main/res/layout/list_item.xml
new file mode 100644
index 0000000..e52ac28
--- /dev/null
+++ b/app/src/main/res/layout/list_item.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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-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/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..597d72c
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,9 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+ #cccccc
+ #1f9b06
+ #cc1010
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..1f54bff
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,8 @@
+
+ T2 Modus Android Test
+
+ Loading...
+ Contact Info
+ Bio
+
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/app/src/test/java/com/akilloren/t2modus_android_test/ExampleUnitTest.java b/app/src/test/java/com/akilloren/t2modus_android_test/ExampleUnitTest.java
new file mode 100644
index 0000000..5fe0e2e
--- /dev/null
+++ b/app/src/test/java/com/akilloren/t2modus_android_test/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.akilloren.t2modus_android_test;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file