UI (Recycle and Card View)
Recycle View
We will use Recycle view for showing list of the cupcakes. Inspired from Airbnb android web, we are going to keep it simple. A title text on top of ImageView would be an ideal candidate for us.
The main layout file for ItemListActivity is activity_item_list.xml
. You will find a FrameLayout below Appbar which includes following
<include layout="@layout/item_list" />
Add a ProgressBar
below FrameLayout
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar"
android:visibility="gone"
android:layout_gravity="center"/>
CardView
Open item_list
file, you will find tools:listitem="@layout/item_list_content"
. Click on item_list_content
and open it in new window. For now it will be a simple TextView. Replace it with following content.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.v7.widget.CardView
android:id="@+id/cardview"
android:layout_width="match_parent"
android:layout_height="300dp"
android:elevation="100dp"
card_view:cardCornerRadius="8dp"
>
<ImageView
android:id="@+id/cupcakeImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/android_cup_cake"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:text="@string/app_name"
android:layout_gravity="center"
android:textColor="@android:color/white"
android:textStyle="bold"
android:textSize="@dimen/text_size"/>
</android.support.v7.widget.CardView>
</LinearLayout>
We are using a CardView and placing title text on top of it. Let's update our RecycleView Code. Declare following variables in your ItemListActivity
private List<CupcakeResponse> mCupcakeList;
private ProgressBar progessBar;
private View recyclerView;
and in onCreate
method
progessBar = (ProgressBar) findViewById(R.id.progressBar);
recyclerView = findViewById(R.id.cupcake_list);
Ideally, we would like to check results in onCreate method. If we have no cupcakes, then we can fetch them from the network
final RealmResults<Cupcake> cupCakes = getRealmResults();
if(cupCakes.size() == 0) {
initiateCupcakeApi(recyclerView);
}
else {
setupRecyclerView((RecyclerView) recyclerView,cupCakes);
}
Let's focus on setupRecyclerView
method. As soon as this method is called, make progress bar visible
private void setupRecyclerView(@NonNull RecyclerView recyclerView, RealmResults<Cupcake> results) {
progessBar.setVisibility(View.GONE);
recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(results));
}
For recycle view we have a simple adapter which we named as SimpleItemRecyclerViewAdapter
. We pass on our realm data results to it's constructor.
For showing data in the UI, we need an ImageView and TextView instance. The adapter's class code is as follows.
public class SimpleItemRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {
private final RealmResults<Cupcake> mRealmObjects;
public SimpleItemRecyclerViewAdapter(RealmResults<Cupcake> realmObjects) {
mRealmObjects = realmObjects;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cupcake_list_content, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mRealmObject = mRealmObjects.get(position);
holder.mTitle.setText(mRealmObjects.get(position).getName());
Glide.with(holder.mImage.getContext())
.load(API_URL_PROD + mRealmObjects.get(position).getImage())
.centerCrop()
// .placeholder(R.drawable.loading_spinner)
.crossFade()
.into(holder.mImage);
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mTwoPane) {
//TODO: TO be implemented in next chapter
}
else {
//TODO: TO be implemented in next chapter
}
}
});
}
@Override
public int getItemCount() {
return mRealmObjects.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mTitle;
public final ImageView mImage;
public Cupcake mRealmObject;
public ViewHolder(View view) {
super(view);
mView = view;
mTitle = (TextView) view.findViewById(R.id.title);
mImage = (ImageView) view.findViewById(R.id.cupcakeImage);
}
@Override
public String toString() {
return super.toString() + " '" + mTitle.getText() + "'";
}
}
}
FOr now we have SimpleItemRecyclerViewAdapter as an internal class. You can also move it to a new Java file. I will leave it for you as TO-DO work :)
Go ahead and run your app. You will see a progress bar being displayed at the beginning. After data fetch is completed, your data will be shown in Recycle View.
Homework
Realm provides a nice API for data change listener. Implement Realm Listener for change in results and update UI. See more here https://realm.io/docs/java/latest/#notifications
Move on to next chapter for Implementing Detail view.