Detail Activity & Fragment

Our boiler plate code already created a Detail Activity and Fragment. Let's change Layout file first. Add following code to item_detail.xml file.


<?xml version="1.0" encoding="utf-8"?>
<layout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable name="cake"
            type="com.hassanabid.androidcupcake.model.Cupcake"/>
    </data>
<LinearLayout
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_margin="@dimen/text_margin"
    android:layout_height="match_parent"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:gravity="center_vertical"
        android:layout_height="wrap_content">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/text_margin"
            android:src="@drawable/ic_star_black_36dp"/>
        <TextView
            android:id="@+id/cupcake_rating"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="?android:attr/textAppearanceMedium"
            android:padding="16dp"
            android:text='@{String.valueOf(cake.rating)}'
            android:textColor="@android:color/black"
            android:textIsSelectable="true"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:gravity="center_vertical"
        android:layout_height="wrap_content">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/text_margin"
        android:src="@drawable/ic_attach_money_black_36dp"/>
    <TextView
        android:id="@+id/cupcake_price"
        style="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="@{cake.price}"
        android:textColor="@android:color/black"
        android:textIsSelectable="true" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:gravity="center_vertical"
        android:layout_height="wrap_content">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/text_margin"
            android:src="@drawable/ic_person_black_36dp"/>
        <TextView
            android:id="@+id/cupcake_writer"
            style="?android:attr/textAppearanceMedium"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="@android:color/black"
            android:padding="16dp"
            android:text="@{cake.writer}"
            android:textIsSelectable="true"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:gravity="center_vertical"
        android:layout_height="wrap_content">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/text_margin"
            android:src="@drawable/ic_date_range_black_36dp"/>
        <TextView
            android:id="@+id/cupcake_date"
            style="?android:attr/textAppearanceMedium"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp"
            android:text="@{cake.createdAt}"
            android:textIsSelectable="true" />
    </LinearLayout>

</LinearLayout>
</layout>

If you closely look at the UI element, you will see that we added few icons. You can download them from here https://design.google.com/icons/ or drawable-xxxhdpi folder from Github.

Following part of the xml layout might be new to you?


 <data>
        <variable name="cake"
            type="com.hassanabid.androidcupcake.model.Cupcake"/>
    </data>

We are using new Data binding Library to connect UI elements with data directly in layout. You can read more about it here https://developer.android.com/topic/libraries/data-binding/index.html

Firstly, we have to pass data from ItemListActivity to ItemDetailActivity and then Fragment.

In SimpleItemRecyclerViewAdapter add the following code in onClick method.

holder.mView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mTwoPane) {
                        Bundle arguments = new Bundle();
                        arguments.putString(CupcakeDetailFragment.ARG_NAME_ID, holder.mRealmObject.getName());
                        arguments.putString(CupcakeDetailFragment.ARG_IMAGE_ID,holder.mRealmObject.getImage());

                        CupcakeDetailFragment fragment = new CupcakeDetailFragment();
                        fragment.setArguments(arguments);
                        getSupportFragmentManager().beginTransaction()
                                .replace(R.id.cupcake_detail_container, fragment)
                                .commit();
                    } else {
                        Context context = v.getContext();
                        Intent intent = new Intent(context, CupcakeDetailActivity.class);
                        intent.putExtra(CupcakeDetailFragment.ARG_NAME_ID, holder.mRealmObject.getName());
                        intent.putExtra(CupcakeDetailFragment.ARG_IMAGE_ID, holder.mRealmObject.getImage());

                        context.startActivity(intent);
                    }
                }
            });

Make sure to have these static variables declared in ItemDetailFragment

 public static final String ARG_NAME_ID = "item_name_id";
    public static final String ARG_IMAGE_ID = "item_image_id";

Then in ItemDetailActivity update the following code. (Final version will be as follows)

if (savedInstanceState == null) {
            // Create the detail fragment and add it to the activity
            // using a fragment transaction.
            Bundle arguments = new Bundle();
            arguments.putString(CupcakeDetailFragment.ARG_NAME_ID,
                    getIntent().getStringExtra(CupcakeDetailFragment.ARG_NAME_ID));
            arguments.putString(CupcakeDetailFragment.ARG_IMAGE_ID,
                    getIntent().getStringExtra(CupcakeDetailFragment.ARG_IMAGE_ID));
            CupcakeDetailFragment fragment = new CupcakeDetailFragment();
            fragment.setArguments(arguments);
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.cupcake_detail_container, fragment)
                    .commit();
        }

Finally in ItemDetailFragment, We will are going to receive intent items.


 // Create a RealmConfiguration that saves the Realm file in the app's "files" directory.
        RealmConfiguration realmConfig = new RealmConfiguration.Builder(getActivity()).build();
        Realm.setDefaultConfiguration(realmConfig);

        // Get a Realm instance for this thread
        Realm realm = Realm.getDefaultInstance();
        if (getArguments().containsKey(ARG_NAME_ID)) {

            mTitle = getArguments().getString(ARG_NAME_ID);
            mImageURL = getArguments().getString(ARG_IMAGE_ID);
            cake = realm.where(Cupcake.class).equalTo("name", mTitle).findFirst();
            if(cake != null)
                Log.d(LOG_TAG,"realm object retrieved : " + cake.getName());

            Activity activity = this.getActivity();
            CollapsingToolbarLayout appBarLayout = (CollapsingToolbarLayout) activity.findViewById(R.id.toolbar_layout);
            if (appBarLayout != null) {
                appBarLayout.setTitle(mTitle);
            }
        }

We need little more code for our data binding to work. In onCreateView method add the following code.


        CupcakeDetailBinding binding  = DataBindingUtil.inflate(inflater, R.layout.cupcake_detail, container, false);
        View rootView = binding.getRoot();
        binding.setCake(cake);

        if(mImageURL != null) {
            loadBackdrop(CupcakeListActivity.API_URL_PROD  + mImageURL,rootView);
        } else {
            Log.d(LOG_TAG,"imageurl is null");
        }
        return rootView;

and loadBackdrop method is as follows

private void loadBackdrop(String image_url, View root) {
        final ImageView imageView = (ImageView) getActivity().findViewById(R.id.cake_image);
        Glide.with(getActivity())
                .load(image_url)
                .centerCrop()
                .crossFade()
                .into(imageView);
    }

If you have reached this far! Well-done :) Build the app and run on your device. If you run into any error, don's hestiate to ask me!

Part-2 of this tutorial is coming soon where you will implement Login, Signup and Add/Delete/Modify features.

Good luck !

results matching ""

    No results matching ""