diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 30aa626..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0b6820d..93d072d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,4 +26,7 @@ dependencies { androidTestImplementation 'com.android.support.test:runner:1.0.2' implementation project(':congressdataapiaccess-debug') androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation "android.arch.lifecycle:extensions:1.1.0" + implementation "android.arch.lifecycle:viewmodel:1.1.0" + implementation 'com.android.support:recyclerview-v7:28.0.0-rc02' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 26b1cb9..bc688bf 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + + diff --git a/app/src/main/java/com/lambdaschool/congressdetails/CongresspeopleAdapter.java b/app/src/main/java/com/lambdaschool/congressdetails/CongresspeopleAdapter.java new file mode 100644 index 0000000..a672932 --- /dev/null +++ b/app/src/main/java/com/lambdaschool/congressdetails/CongresspeopleAdapter.java @@ -0,0 +1,72 @@ +package com.lambdaschool.congressdetails; + +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.lambdaschool.congressdataapiaccess.CongresspersonOverview; + +import java.util.ArrayList; + +public class CongresspeopleAdapter extends RecyclerView.Adapter { + + private ArrayList congresspersonOverviews = new ArrayList<>(); + private OnCongresspersonClickListener onCongresspersonClickListener; + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + return new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_congressperson, viewGroup, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) { + final CongresspersonOverview congresspersonOverview = congresspersonOverviews.get(i); + + String text = congresspersonOverview.getFirstName() + " " + congresspersonOverview.getLastName() + ", " + + congresspersonOverview.getParty() + ", " + congresspersonOverview.getState(); + viewHolder.detailsTextView.setText(text); + + viewHolder.detailsTextView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onCongresspersonClickListener != null) { + onCongresspersonClickListener.onClick(congresspersonOverview); + } + } + }); + } + + @Override + public int getItemCount() { + return congresspersonOverviews.size(); + } + + public void setCongresspersonOverviews(@NonNull ArrayList congresspersonOverviews) { + this.congresspersonOverviews = congresspersonOverviews; + notifyDataSetChanged(); + } + + public class ViewHolder extends RecyclerView.ViewHolder { + + public ViewHolder(@NonNull View itemView) { + super(itemView); + + detailsTextView = itemView.findViewById(R.id.item_congressperson_text_details); + } + + private TextView detailsTextView; + + } + + public interface OnCongresspersonClickListener { + void onClick(CongresspersonOverview congresspersonOverview); + } + + public void setOnCongresspersonClickListener(OnCongresspersonClickListener l) { + onCongresspersonClickListener = l; + } +} diff --git a/app/src/main/java/com/lambdaschool/congressdetails/CongresspeopleViewModel.java b/app/src/main/java/com/lambdaschool/congressdetails/CongresspeopleViewModel.java new file mode 100644 index 0000000..c9d7602 --- /dev/null +++ b/app/src/main/java/com/lambdaschool/congressdetails/CongresspeopleViewModel.java @@ -0,0 +1,36 @@ +package com.lambdaschool.congressdetails; + +import android.arch.lifecycle.LiveData; +import android.arch.lifecycle.MutableLiveData; +import android.arch.lifecycle.ViewModel; +import android.support.annotation.AnyThread; + +import com.lambdaschool.congressdataapiaccess.CongresspersonOverview; + +import java.util.ArrayList; + +public class CongresspeopleViewModel extends ViewModel { + + private MutableLiveData> m_CongresspeopleLD; + private CongresspersonOverviewRepository repository; + + public LiveData> getCongresspeopleLD() { + if (m_CongresspeopleLD == null) { + loadCongresspeople(); + } + + return m_CongresspeopleLD; + } + + private void loadCongresspeople() { + repository = new CongresspersonOverviewRepository(); + m_CongresspeopleLD = repository.getData(); + } + + @AnyThread + public void reload() { + repository.reload(m_CongresspeopleLD); + } + + +} diff --git a/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonDetailsActivity.java b/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonDetailsActivity.java new file mode 100644 index 0000000..911fa1d --- /dev/null +++ b/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonDetailsActivity.java @@ -0,0 +1,74 @@ +package com.lambdaschool.congressdetails; + +import android.arch.lifecycle.Observer; +import android.arch.lifecycle.ViewModelProviders; +import android.content.Intent; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.lambdaschool.congressdataapiaccess.CongresspersonDetails; + +public class CongresspersonDetailsActivity extends AppCompatActivity { + + private CongresspersonDetailsViewModel congresspersonDetailsViewModel; + private LinearLayout m_congresspersonLinearLayout; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_congressperson_details); + + m_congresspersonLinearLayout = findViewById(R.id.linear_layout_congressperson_details); + + congresspersonDetailsViewModel = ViewModelProviders.of(this).get(CongresspersonDetailsViewModel.class); + + Intent intent = getIntent(); + String congresspersonId = intent.getStringExtra(ListActivity.KEY_EXTRA_CONGRESSPERSON_ID); + + congresspersonDetailsViewModel.getCongresspersonDetailsLD(congresspersonId).observe(this, new CongresspersonDetailsObserver()); + } + + private class CongresspersonDetailsObserver implements Observer { + + @Override + public void onChanged(@Nullable CongresspersonDetails congresspersonDetails) { + if (congresspersonDetails == null) { + return; + } + + // full name + TextView textViewFullName = new TextView(CongresspersonDetailsActivity.this); + String fullName = "Name: "; + fullName += congresspersonDetails.getFirstName(); + if (!congresspersonDetails.getMiddleName().equals("null")) { + fullName += " " + congresspersonDetails.getMiddleName(); + } + if (!congresspersonDetails.getLastName().equals("null")) { + fullName += " " + congresspersonDetails.getLastName(); + } + textViewFullName.setText(fullName); + textViewFullName.setTextSize(25.f); + m_congresspersonLinearLayout.addView(textViewFullName); + + // party + TextView textViewParty = new TextView(CongresspersonDetailsActivity.this); + String party = "Party: "; + party += congresspersonDetails.getCurrentParty(); + textViewParty.setText(party); + textViewParty.setTextSize(25.f); + m_congresspersonLinearLayout.addView(textViewParty); + + // bInOffice + TextView textViewInOffice = new TextView(CongresspersonDetailsActivity.this); + String inOffice = "In office: "; + inOffice += congresspersonDetails.isInOffice() ? "Yes" : "No"; + textViewInOffice.setText(inOffice); + textViewInOffice.setTextSize(25.f); + m_congresspersonLinearLayout.addView(textViewInOffice); + + } + } +} diff --git a/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonDetailsRepository.java b/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonDetailsRepository.java new file mode 100644 index 0000000..a4977bc --- /dev/null +++ b/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonDetailsRepository.java @@ -0,0 +1,28 @@ +package com.lambdaschool.congressdetails; + +import android.arch.lifecycle.MutableLiveData; + +import com.lambdaschool.congressdataapiaccess.CongressDao; +import com.lambdaschool.congressdataapiaccess.CongresspersonDetails; + +public class CongresspersonDetailsRepository { + + public MutableLiveData getData(String id) { + final MutableLiveData liveData = new MutableLiveData<>(); + + requestDetails(liveData, id); + + liveData.setValue(null); + return liveData; + } + + private void requestDetails(final MutableLiveData liveData, final String id) { + new Thread(new Runnable() { + @Override + public void run() { + liveData.postValue(CongressDao.getMemberDetails(id)); + } + }).start(); + } + +} diff --git a/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonDetailsViewModel.java b/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonDetailsViewModel.java new file mode 100644 index 0000000..eeb5463 --- /dev/null +++ b/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonDetailsViewModel.java @@ -0,0 +1,27 @@ +package com.lambdaschool.congressdetails; + +import android.arch.lifecycle.LiveData; +import android.arch.lifecycle.MutableLiveData; +import android.arch.lifecycle.ViewModel; + +import com.lambdaschool.congressdataapiaccess.CongresspersonDetails; + +public class CongresspersonDetailsViewModel extends ViewModel { + private MutableLiveData m_CongresspersonDetailsLD; + private CongresspersonDetailsRepository repository; + private String id; + + public LiveData getCongresspersonDetailsLD(String id) { + if (m_CongresspersonDetailsLD == null) { + this.id = id; + loadCongresspersonDetails(); + } + return m_CongresspersonDetailsLD; + } + + private void loadCongresspersonDetails() { + repository = new CongresspersonDetailsRepository(); + m_CongresspersonDetailsLD = repository.getData(id); + } + +} diff --git a/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonOverviewRepository.java b/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonOverviewRepository.java new file mode 100644 index 0000000..1777645 --- /dev/null +++ b/app/src/main/java/com/lambdaschool/congressdetails/CongresspersonOverviewRepository.java @@ -0,0 +1,36 @@ +package com.lambdaschool.congressdetails; + +import android.arch.lifecycle.MutableLiveData; +import android.support.annotation.AnyThread; + +import com.lambdaschool.congressdataapiaccess.CongressDao; +import com.lambdaschool.congressdataapiaccess.CongresspersonOverview; + +import java.util.ArrayList; + +public class CongresspersonOverviewRepository { + + public MutableLiveData> getData() { + final MutableLiveData> liveData = new MutableLiveData<>(); + + requestAllMembers(liveData); + + liveData.setValue(new ArrayList()); + return liveData; + } + + @AnyThread + public void reload(MutableLiveData> liveData) { + requestAllMembers(liveData); + } + + private void requestAllMembers(final MutableLiveData> liveData) { + new Thread(new Runnable() { + @Override + public void run() { + liveData.postValue(CongressDao.getAllMembers()); + } + }).start(); + } + +} diff --git a/app/src/main/java/com/lambdaschool/congressdetails/ListActivity.java b/app/src/main/java/com/lambdaschool/congressdetails/ListActivity.java index 8be745a..16ad49d 100644 --- a/app/src/main/java/com/lambdaschool/congressdetails/ListActivity.java +++ b/app/src/main/java/com/lambdaschool/congressdetails/ListActivity.java @@ -1,18 +1,71 @@ package com.lambdaschool.congressdetails; + +import android.arch.lifecycle.ViewModelProviders; +import android.content.Intent; +import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; -import com.lambdaschool.congressdataapiaccess.CongressDao; +import com.lambdaschool.congressdataapiaccess.CongresspersonOverview; + +import android.arch.lifecycle.Observer; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.util.ArrayList; public class ListActivity extends AppCompatActivity { + public static final String TAG = "MyDebug"; + public static final String KEY_EXTRA_CONGRESSPERSON_ID = "congressperson_id"; + + private CongresspeopleViewModel congresspeopleViewModel; + private CongresspeopleAdapter congresspeopleAdapter; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list); - CongressDao.getAllMembers(); + RecyclerView congresspeopleRecyclerView = findViewById(R.id.activity_list_recycler_congresspeople); + congresspeopleRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); + + congresspeopleAdapter = new CongresspeopleAdapter(); + congresspeopleAdapter.setOnCongresspersonClickListener(new CongresspeopleAdapter.OnCongresspersonClickListener() { + @Override + public void onClick(CongresspersonOverview congresspersonOverview) { + Intent intent = new Intent(ListActivity.this, CongresspersonDetailsActivity.class); + intent.putExtra(KEY_EXTRA_CONGRESSPERSON_ID, congresspersonOverview.getId()); + startActivity(intent); + } + }); + congresspeopleRecyclerView.setAdapter(congresspeopleAdapter); + + // this will create the ViewModel + congresspeopleViewModel = ViewModelProviders.of(this).get(CongresspeopleViewModel.class); + + // bind + congresspeopleViewModel.getCongresspeopleLD().observe(this, new CongresspersonObserver()); + + } + + private class CongresspersonObserver implements Observer> { + + @Override + public void onChanged(ArrayList arg) { + String threadName = Thread.currentThread().getName(); // @NOTE: UI thread + Log.d(TAG, "Observer onChanged Thread: " + threadName); + + congresspeopleAdapter.setCongresspersonOverviews(arg); + + } } + } + diff --git a/app/src/main/res/layout/activity_congressperson_details.xml b/app/src/main/res/layout/activity_congressperson_details.xml new file mode 100644 index 0000000..a625013 --- /dev/null +++ b/app/src/main/res/layout/activity_congressperson_details.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_list.xml b/app/src/main/res/layout/activity_list.xml index 1884df2..37e8d32 100644 --- a/app/src/main/res/layout/activity_list.xml +++ b/app/src/main/res/layout/activity_list.xml @@ -1,18 +1,16 @@ - - + - \ No newline at end of file + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_congressperson.xml b/app/src/main/res/layout/item_congressperson.xml new file mode 100644 index 0000000..fb8a1e7 --- /dev/null +++ b/app/src/main/res/layout/item_congressperson.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 077cb2f..af70df7 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.4' + classpath 'com.android.tools.build:gradle:3.3.2' // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 95d3e5f..c764f4e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Sep 04 14:01:16 MDT 2018 +#Tue Mar 19 09:55:26 CDT 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip