From a2dcdbfd5b8e91cdb6b086b607683e8a83ffe9a1 Mon Sep 17 00:00:00 2001 From: "james.buxton" Date: Sat, 4 Nov 2017 16:01:18 +0000 Subject: [PATCH 1/7] Added internet permission to manifest. --- app/src/main/AndroidManifest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6ed188b..0430e3a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + Date: Sat, 4 Nov 2017 16:12:11 +0000 Subject: [PATCH 2/7] Fixed ResouceId not found exception, integers converted to Strings set in text boxes. --- .../java/com/salesi/coding/ui/adapter/ContactsAdapter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java b/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java index c458668..e28a242 100644 --- a/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java +++ b/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java @@ -11,6 +11,7 @@ import com.salesi.coding.entity.ContactEntity; import java.util.List; +import java.util.Locale; import javax.inject.Inject; @@ -59,8 +60,8 @@ public ViewHolder(View itemView) { } public void bind(ContactEntity entity) { - mId.setText(entity.ContactID); - mName.setText(entity.FirstName+" "+entity.LastName); + mId.setText(String.valueOf(entity.ContactID)); + mName.setText(String.format(Locale.UK, "%1$s %2$s", entity.FirstName, entity.LastName)); } } } From 3cf65bed97c9a1c6da8da529eda579722a59daef Mon Sep 17 00:00:00 2001 From: "james.buxton" Date: Sat, 4 Nov 2017 16:16:32 +0000 Subject: [PATCH 3/7] Fixed null display for firstnames in listview, renamed attribute in ContactEntity. --- app/src/main/java/com/salesi/coding/entity/ContactEntity.java | 2 +- .../main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/salesi/coding/entity/ContactEntity.java b/app/src/main/java/com/salesi/coding/entity/ContactEntity.java index 6334c88..09d500a 100644 --- a/app/src/main/java/com/salesi/coding/entity/ContactEntity.java +++ b/app/src/main/java/com/salesi/coding/entity/ContactEntity.java @@ -14,6 +14,6 @@ public class ContactEntity { @Expose public Integer ContactID; @Expose public String Title; - @Expose public String FirstName; + @Expose public String FirstNane; @Expose public String LastName; } diff --git a/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java b/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java index e28a242..0523011 100644 --- a/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java +++ b/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java @@ -61,7 +61,7 @@ public ViewHolder(View itemView) { public void bind(ContactEntity entity) { mId.setText(String.valueOf(entity.ContactID)); - mName.setText(String.format(Locale.UK, "%1$s %2$s", entity.FirstName, entity.LastName)); + mName.setText(String.format(Locale.UK, "%1$s %2$s", entity.FirstNane, entity.LastName)); } } } From 290613d9acec648f47d2c8d1d976922757e79e99 Mon Sep 17 00:00:00 2001 From: "james.buxton" Date: Sat, 4 Nov 2017 16:22:23 +0000 Subject: [PATCH 4/7] Cleaned up code. --- .../res/layout/layout_contact_row_item.xml | 48 +++++++++---------- app/src/main/res/values/strings.xml | 4 ++ 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/app/src/main/res/layout/layout_contact_row_item.xml b/app/src/main/res/layout/layout_contact_row_item.xml index a3118bf..bde8ab5 100644 --- a/app/src/main/res/layout/layout_contact_row_item.xml +++ b/app/src/main/res/layout/layout_contact_row_item.xml @@ -2,70 +2,70 @@ + android:textStyle="normal|bold" + tools:targetApi="ICE_CREAM_SANDWICH" /> + app:srcCompat="@android:drawable/sym_action_email" + tools:targetApi="ICE_CREAM_SANDWICH" /> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e30960f..19b21a8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,4 +2,8 @@ CodingTest http://www.mocky.io/ Contacts + + + 885 + Arriva PLC From d20191b0c837d120d197b82212d2a5f009bcad8a Mon Sep 17 00:00:00 2001 From: "james.buxton" Date: Sat, 4 Nov 2017 17:42:20 +0000 Subject: [PATCH 5/7] Added Close app on all tabs feature. --- .../java/com/salesi/coding/MainActivity.java | 20 +++++++++++++++++++ .../coding/ui/adapter/ContactsAdapter.java | 14 +++++++++++++ .../salesi/coding/ui/adapter/TabsAdapter.java | 6 ++---- app/src/main/res/menu/main_activity.xml | 9 +++++++++ app/src/main/res/values/strings.xml | 2 ++ 5 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 app/src/main/res/menu/main_activity.xml diff --git a/app/src/main/java/com/salesi/coding/MainActivity.java b/app/src/main/java/com/salesi/coding/MainActivity.java index d091985..5502aff 100644 --- a/app/src/main/java/com/salesi/coding/MainActivity.java +++ b/app/src/main/java/com/salesi/coding/MainActivity.java @@ -5,6 +5,8 @@ import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; import com.salesi.coding.ui.adapter.TabsAdapter; @@ -30,4 +32,22 @@ protected void onCreate(Bundle savedInstanceState) { mViewPager.setAdapter(adapter); mTabLayout.setupWithViewPager(mViewPager); } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main_activity, menu); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + + if (id == R.id.close_app_option) { + finish(); + } + + return super.onOptionsItemSelected(item); + } } diff --git a/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java b/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java index 0523011..b466754 100644 --- a/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java +++ b/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java @@ -6,6 +6,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import android.widget.Toast; import com.salesi.coding.R; import com.salesi.coding.entity.ContactEntity; @@ -17,6 +18,7 @@ import butterknife.Bind; import butterknife.ButterKnife; +import butterknife.OnClick; /** * Contacts view adapter @@ -54,6 +56,18 @@ class ViewHolder extends RecyclerView.ViewHolder { @Nullable @Bind(R.id.contact_id) protected TextView mId; @Nullable @Bind(R.id.contact_name) protected TextView mName; + @OnClick(R.id.phone) + void callContact() { + //TODO Implement Call feature + Toast.makeText(itemView.getContext(), "Calling contact...", Toast.LENGTH_SHORT).show(); + } + + @OnClick(R.id.email) + void emailContact() { + //TODO Implement Email feature + Toast.makeText(itemView.getContext(), "Emailing contact...", Toast.LENGTH_SHORT).show(); + } + public ViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); diff --git a/app/src/main/java/com/salesi/coding/ui/adapter/TabsAdapter.java b/app/src/main/java/com/salesi/coding/ui/adapter/TabsAdapter.java index 4bbb33e..e01b323 100644 --- a/app/src/main/java/com/salesi/coding/ui/adapter/TabsAdapter.java +++ b/app/src/main/java/com/salesi/coding/ui/adapter/TabsAdapter.java @@ -24,9 +24,8 @@ public TabsAdapter(final FragmentManager fm, final Context context) { @Override public Fragment getItem(int position) { switch(position) { - case 0 : { + case 0 : return FContacts.instance(); - } } return null; } @@ -34,9 +33,8 @@ public Fragment getItem(int position) { @Override public CharSequence getPageTitle(int position) { switch(position) { - case 0 : { + case 0 : return mContext.getString(R.string.title_tab_question_1); - } } return null; } diff --git a/app/src/main/res/menu/main_activity.xml b/app/src/main/res/menu/main_activity.xml new file mode 100644 index 0000000..dea54d2 --- /dev/null +++ b/app/src/main/res/menu/main_activity.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 19b21a8..f6b2fcc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,4 +6,6 @@ 885 Arriva PLC + + Close App From e0bbe2f96fa878114e84d351139f012ebc9af1ec Mon Sep 17 00:00:00 2001 From: "james.buxton" Date: Sun, 5 Nov 2017 15:11:36 +0000 Subject: [PATCH 6/7] Contact details are now displayed along with other contact that share same hobbies and selected contact. --- app/src/main/AndroidManifest.xml | 2 + .../com/salesi/coding/DetailsActivity.java | 46 +++++++++ .../java/com/salesi/coding/MainActivity.java | 12 +++ .../salesi/coding/entity/ContactEntity.java | 54 ++++++++++- .../coding/ui/Fragments/DetailFragment.java | 78 +++++++++++++++ .../coding/ui/adapter/ContactsAdapter.java | 26 ++++- .../salesi/coding/ui/screens/FContacts.java | 96 +++++++++++++++++-- .../java/com/salesi/coding/utils/Utils.java | 19 ++++ .../main/res/layout-large/activity_main.xml | 63 ++++++++++++ app/src/main/res/layout/activity_detail.xml | 31 ++++++ app/src/main/res/layout/fragment_detail.xml | 55 +++++++++++ 11 files changed, 469 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/com/salesi/coding/DetailsActivity.java create mode 100644 app/src/main/java/com/salesi/coding/ui/Fragments/DetailFragment.java create mode 100644 app/src/main/java/com/salesi/coding/utils/Utils.java create mode 100644 app/src/main/res/layout-large/activity_main.xml create mode 100644 app/src/main/res/layout/activity_detail.xml create mode 100644 app/src/main/res/layout/fragment_detail.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0430e3a..f367e34 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,6 +20,8 @@ + + \ No newline at end of file diff --git a/app/src/main/java/com/salesi/coding/DetailsActivity.java b/app/src/main/java/com/salesi/coding/DetailsActivity.java new file mode 100644 index 0000000..4b1c962 --- /dev/null +++ b/app/src/main/java/com/salesi/coding/DetailsActivity.java @@ -0,0 +1,46 @@ +package com.salesi.coding; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; + +import com.salesi.coding.entity.ContactEntity; +import com.salesi.coding.ui.Fragments.DetailFragment; +import com.salesi.coding.ui.screens.FContacts; + +import butterknife.Bind; +import butterknife.ButterKnife; + +/** + * Created by buxtonj on 05/11/2017. + */ + +public class DetailsActivity extends AppCompatActivity { + @Bind(R.id.toolbar) protected Toolbar mToolbar; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_detail); + + ButterKnife.bind(this); + + setSupportActionBar(mToolbar); + + if (savedInstanceState == null) { + // Create the detail fragment and add it to the activity + // using a fragment transaction. + + ContactEntity fContacts = (ContactEntity) getIntent().getSerializableExtra("contact"); + + DetailFragment fragment = new DetailFragment(); + fragment.setData(fContacts); + + getSupportFragmentManager().beginTransaction() + .add(R.id.contact_detail_container, fragment, MainActivity.DETAILFRAGMENT_TAG) + .commit(); + } + } +} diff --git a/app/src/main/java/com/salesi/coding/MainActivity.java b/app/src/main/java/com/salesi/coding/MainActivity.java index 5502aff..e5ec476 100644 --- a/app/src/main/java/com/salesi/coding/MainActivity.java +++ b/app/src/main/java/com/salesi/coding/MainActivity.java @@ -8,6 +8,7 @@ import android.view.Menu; import android.view.MenuItem; +import com.salesi.coding.ui.Fragments.DetailFragment; import com.salesi.coding.ui.adapter.TabsAdapter; import butterknife.Bind; @@ -18,6 +19,9 @@ public class MainActivity extends AppCompatActivity { @Bind(R.id.view_pager) protected ViewPager mViewPager; @Bind(R.id.toolbar) protected Toolbar mToolbar; + public static final String DETAILFRAGMENT_TAG = "DFTAG"; + public static final String CONTACTFRAGMENT_TAG = "CFTAG"; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -28,6 +32,14 @@ protected void onCreate(Bundle savedInstanceState) { setSupportActionBar(mToolbar); getSupportActionBar().setLogo(R.mipmap.ic_launcher); + if (findViewById(R.id.contact_detail_container) != null) { + if (savedInstanceState == null) { + getSupportFragmentManager().beginTransaction() + .replace(R.id.contact_detail_container, new DetailFragment(), DETAILFRAGMENT_TAG) + .commit(); + } + } + TabsAdapter adapter = new TabsAdapter(getSupportFragmentManager(), getApplicationContext()); mViewPager.setAdapter(adapter); mTabLayout.setupWithViewPager(mViewPager); diff --git a/app/src/main/java/com/salesi/coding/entity/ContactEntity.java b/app/src/main/java/com/salesi/coding/entity/ContactEntity.java index 09d500a..51b8404 100644 --- a/app/src/main/java/com/salesi/coding/entity/ContactEntity.java +++ b/app/src/main/java/com/salesi/coding/entity/ContactEntity.java @@ -2,7 +2,10 @@ import com.google.gson.annotations.Expose; +import java.io.Serializable; +import java.security.spec.PSSParameterSpec; import java.util.List; +import java.util.Locale; /** * Contact Entity @@ -11,9 +14,58 @@ * Copyright © 2017 sales­i */ -public class ContactEntity { +public class ContactEntity implements Serializable{ @Expose public Integer ContactID; @Expose public String Title; @Expose public String FirstNane; @Expose public String LastName; + @Expose public String JobTitle; + @Expose public String PhoneNumber; + @Expose public String Email; + + /** + * Address : {"Address1":"Marine Drive","Address2":"","Address3":"Clove Lane","Address4":"","Town":"Solihull","County":"","Postcode":"","Country":"CCV23A"} + * Hobbies : ["table-tennis","badminton"] + */ + + @Expose + public AddressBean Address; + @Expose + public List Hobbies; + + public static class AddressBean implements Serializable { + /** + * Address1 : Marine Drive + * Address2 : + * Address3 : Clove Lane + * Address4 : + * Town : Solihull + * County : + * Postcode : + * Country : CCV23A + */ + + @Expose + public String Address1; + @Expose + public String Address2; + @Expose + public String Address3; + @Expose + public String Address4; + @Expose + public String Town; + @Expose + public String County; + @Expose + public String Postcode; + @Expose + public String Country; + + @Override + public String toString() { + return String.format(Locale.UK, "%s, %s, %s, %s, %s, %s, %s, %s", + Address1, Address2, Address3, Address4, Town, County,Postcode, Country); + } + } } diff --git a/app/src/main/java/com/salesi/coding/ui/Fragments/DetailFragment.java b/app/src/main/java/com/salesi/coding/ui/Fragments/DetailFragment.java new file mode 100644 index 0000000..363255b --- /dev/null +++ b/app/src/main/java/com/salesi/coding/ui/Fragments/DetailFragment.java @@ -0,0 +1,78 @@ +package com.salesi.coding.ui.Fragments; + +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.TextView; + +import com.salesi.coding.R; +import com.salesi.coding.entity.ContactEntity; +import com.salesi.coding.ui.screens.FContacts; + +import java.util.Locale; + +import static com.salesi.coding.MainActivity.CONTACTFRAGMENT_TAG; + +/** + * Created by buxtonj on 05/11/2017. + */ + +public class DetailFragment extends Fragment { + + TextView contactName, jobTitle, phoneNumber, email, address, hobbies; + private ContactEntity contact; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + + + View rootView = inflater.inflate(R.layout.fragment_detail, container, false); + contactName = (TextView) rootView.findViewById(R.id.contact_name); + jobTitle = (TextView) rootView.findViewById(R.id.jobTitle); + phoneNumber = (TextView) rootView.findViewById(R.id.phoneNumber); + email = (TextView) rootView.findViewById(R.id.email); + address = (TextView) rootView.findViewById(R.id.adress); + hobbies = (TextView) rootView.findViewById(R.id.hobbies); + + if (contact != null && rootView.findViewById(R.id.contacts_frag_container) != null) { + if (savedInstanceState == null) { + getActivity().getSupportFragmentManager().beginTransaction() + .replace(R.id.contacts_frag_container, FContacts.instance(), CONTACTFRAGMENT_TAG) + .commit(); + } + } + + return rootView; + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + if (contact != null) { + contactName.setText(String.format(Locale.UK, "%s %s %s", contact.Title, contact.FirstNane, contact.LastName)); + jobTitle.setText(contact.JobTitle); + phoneNumber.setText(contact.PhoneNumber); + email.setText(contact.Email); + + + if (contact.Address != null) + address.setText(contact.Address.toString()); + + if (contact.Hobbies != null) + hobbies.setText(contact.Hobbies.toString()); + } + } + + public void setData(ContactEntity contacts) { + this.contact = contacts; + } + + public ContactEntity getContact() { + return contact; + } +} diff --git a/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java b/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java index b466754..93a5e64 100644 --- a/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java +++ b/app/src/main/java/com/salesi/coding/ui/adapter/ContactsAdapter.java @@ -5,9 +5,11 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.TextView; import android.widget.Toast; +import com.salesi.coding.MainApp; import com.salesi.coding.R; import com.salesi.coding.entity.ContactEntity; @@ -27,12 +29,20 @@ */ public class ContactsAdapter extends RecyclerView.Adapter { private List mContacts; + private OnItemClickListener listener; + + public interface OnItemClickListener { + void onItemClick(ContactEntity item); + } + @Inject - public ContactsAdapter() {} + public ContactsAdapter() { + } - public void setData(List contacts) { - mContacts = contacts; + public void setData(List contacts, OnItemClickListener listener) { + this.mContacts = contacts; + this.listener = listener; } @Override @@ -44,7 +54,7 @@ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { @Override public void onBindViewHolder(ViewHolder holder, int position) { - holder.bind(mContacts.get(position)); + holder.bind(mContacts.get(position), listener); } @Override @@ -73,9 +83,15 @@ public ViewHolder(View itemView) { ButterKnife.bind(this, itemView); } - public void bind(ContactEntity entity) { + public void bind(final ContactEntity entity, final OnItemClickListener listener) { mId.setText(String.valueOf(entity.ContactID)); mName.setText(String.format(Locale.UK, "%1$s %2$s", entity.FirstNane, entity.LastName)); + itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listener.onItemClick(entity); + } + }); } } } diff --git a/app/src/main/java/com/salesi/coding/ui/screens/FContacts.java b/app/src/main/java/com/salesi/coding/ui/screens/FContacts.java index 066c80e..ba5cd0d 100644 --- a/app/src/main/java/com/salesi/coding/ui/screens/FContacts.java +++ b/app/src/main/java/com/salesi/coding/ui/screens/FContacts.java @@ -1,7 +1,9 @@ package com.salesi.coding.ui.screens; import android.content.Context; +import android.content.Intent; import android.os.Bundle; +import android.os.CpuUsageInfo; import android.os.StrictMode; import android.support.v4.app.Fragment; import android.support.v7.widget.DefaultItemAnimator; @@ -11,13 +13,20 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; +import com.salesi.coding.DetailsActivity; +import com.salesi.coding.MainActivity; import com.salesi.coding.MainApp; import com.salesi.coding.R; import com.salesi.coding.entity.ContactEntity; import com.salesi.coding.service.IContactService; +import com.salesi.coding.ui.Fragments.DetailFragment; import com.salesi.coding.ui.adapter.ContactsAdapter; +import com.salesi.coding.ui.adapter.ContactsAdapter.OnItemClickListener; +import com.salesi.coding.utils.Utils; +import java.util.ArrayList; import java.util.List; import javax.inject.Inject; @@ -28,15 +37,22 @@ /** * Fragment matching first tab - * + *

* Copyright © 2017 sales­i */ public class FContacts extends Fragment { - @Inject protected Lazy mContactService; - @Inject protected Lazy mAdapter; + @Inject + protected Lazy mContactService; + @Inject + protected Lazy mAdapter; - @Bind(R.id.list_contacts) protected RecyclerView mRecycler; + @Bind(R.id.list_contacts) + protected RecyclerView mRecycler; + + private ContactEntity selectedContact; + + DetailFragment detailsFrag; public static FContacts instance() { return new FContacts(); @@ -54,19 +70,28 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa ButterKnife.bind(this, view); StrictMode.ThreadPolicy strictPolicy = new StrictMode.ThreadPolicy.Builder() - .permitAll().build(); + .permitAll().build(); StrictMode.setThreadPolicy(strictPolicy); getActivity().runOnUiThread(new Runnable() { @Override public void run() { - List contacts = mContactService.get().fetchContacts(); + + detailsFrag = ((DetailFragment) getActivity().getSupportFragmentManager().findFragmentByTag(MainActivity.DETAILFRAGMENT_TAG)); + + if (detailsFrag != null) { + selectedContact = detailsFrag.getContact(); + } + + List contacts = (selectedContact != null) + ? filterContactData(selectedContact, mContactService.get().fetchContacts()) + : mContactService.get().fetchContacts(); mRecycler.setLayoutManager(new LinearLayoutManager(getActivity())); mRecycler.addItemDecoration(new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL)); mRecycler.setItemAnimator(new DefaultItemAnimator()); - mAdapter.get().setData(contacts); + mAdapter.get().setData(contacts, onItemClickListener); mRecycler.setAdapter(mAdapter.get()); } }); @@ -74,6 +99,63 @@ public void run() { return view; } + private List filterContactData(ContactEntity selectedContact, List contactEntities) { + List filteredDataList = new ArrayList<>(); + + if (selectedContact != null && (selectedContact.Hobbies != null && selectedContact.Hobbies.size() > 0)) { + for (ContactEntity contactEntity : contactEntities) { + + // DOn't add selected contact or contact we've already got + if (contactEntity.ContactID.equals(selectedContact.ContactID) || filteredDataList.contains(contactEntity)) { + continue; + } + + if (contactEntity.Hobbies != null) { + for (String contactHobby : contactEntity.Hobbies) { + if (Utils.containsIgnoreCase(selectedContact.Hobbies, contactHobby)) { + filteredDataList.add(contactEntity); + break; + } + + } + } + } + } + + return filteredDataList; + } + + + + public OnItemClickListener onItemClickListener = new OnItemClickListener() { + @Override + public void onItemClick(ContactEntity item) { + selectedContact = item; + + // If I had more time, I would instead save all the data into local storage, pass across the id, + // and then retrieve the data from the database using a DAO + // Because this way could cause a transaction too large exception + displayDetails(item); + } + }; + + private void displayDetails(ContactEntity contactEntity) { + if (getActivity().findViewById(R.id.contact_detail_container) != null) { + + DetailFragment fragment = new DetailFragment(); + fragment.setData(contactEntity); + + getActivity().getSupportFragmentManager().beginTransaction() + .replace(R.id.contact_detail_container, fragment, MainActivity.DETAILFRAGMENT_TAG) + .commit(); + + } else { + Intent intent = new Intent(getActivity(), DetailsActivity.class); + intent.putExtra("contact", contactEntity); + startActivity(intent); + } + } + @Override public void onDestroyView() { super.onDestroyView(); diff --git a/app/src/main/java/com/salesi/coding/utils/Utils.java b/app/src/main/java/com/salesi/coding/utils/Utils.java new file mode 100644 index 0000000..97020f4 --- /dev/null +++ b/app/src/main/java/com/salesi/coding/utils/Utils.java @@ -0,0 +1,19 @@ +package com.salesi.coding.utils; + +import java.util.List; + +/** + * Created by buxtonj on 05/11/2017. + */ + +public class Utils { + public static boolean containsIgnoreCase(List array, String item) { + for(int i = 0; i < array.size(); i++) { + if (array.get(i).toString().equalsIgnoreCase(item)) { + return true; + } + } + + return false; + } +} diff --git a/app/src/main/res/layout-large/activity_main.xml b/app/src/main/res/layout-large/activity_main.xml new file mode 100644 index 0000000..db75f2c --- /dev/null +++ b/app/src/main/res/layout-large/activity_main.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + 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..f3da6c8 --- /dev/null +++ b/app/src/main/res/layout/activity_detail.xml @@ -0,0 +1,31 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_detail.xml b/app/src/main/res/layout/fragment_detail.xml new file mode 100644 index 0000000..b94ea5e --- /dev/null +++ b/app/src/main/res/layout/fragment_detail.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 3be735b4fed882cb251c5f40f1654dcf6e4c7414 Mon Sep 17 00:00:00 2001 From: "james.buxton" Date: Sun, 5 Nov 2017 15:12:08 +0000 Subject: [PATCH 7/7] Contact details are now displayed along with other contact that share same hobbies and selected contact. --- Confirmation of Submission.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Confirmation of Submission.txt diff --git a/Confirmation of Submission.txt b/Confirmation of Submission.txt new file mode 100644 index 0000000..23e878d --- /dev/null +++ b/Confirmation of Submission.txt @@ -0,0 +1,21 @@ +Dear Sales-i + +The following project contains my submitted code for the requirements specified within your github page +(https://github.com/sales-i/android-coding-test). + +I just wanted to affirm and let you know that I implemented as many of the requirements as I could +within the two hour time limit, unfortunately I couldn't implement them all. + +I didn't get a chance to implement tasks iV and V. + +If I did have enough time I would have done the following: + +*Implement and injected the RuntimePermissions class +*Added the necessary permissions within the manifest +*Checked that the device running the app could make phone calls and had an network connection +*Check if they had permission granted, and if not request them. +*Store the granted permission within the onActivityResult callback + +Looking forward to hearing from you. + +James \ No newline at end of file