jeudi 24 mai 2018

Volley & Glide Tutorial | Send Data and show details in Collapsing Toolbar Part 2



Hello guys and welcome to Volley and Glide Tutorial Part 2 in the first tutorial we learned how to parse our json file and display the result into a recyclerview in this part we will create and design the detail activity which will contain the anime inforamations.

the detail activty will contain a collapsigntoolbarlayout and in order to implement that view we need to add the design library to our project
open build.gradle (module:app) and add the following line :

// Design Library
implementation 'com.android.support:design:27.0.2'
view raw build.gradle hosted with ❤ by GitHub
I previously made a tutorial about collapsing toolbar, check this link if you want to know more.
now lets create AnimeActivity : under Activities Package create an empty activity :
open anime_activity.xml and add the following code

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.demotxt.myapp.myapplication.activities.AnimeActivity"
>
<android.support.design.widget.AppBarLayout
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:layout_width="match_parent"
android:layout_height="300dp"
android:id="@+id/appbarlayout_id">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/collapsingtoolbar_id"
app:layout_scrollFlags="exitUntilCollapsed|scroll"
app:title="Anime Title"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp"
>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
android:theme="@style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
>
<ImageView
android:layout_width="100dp"
android:layout_height="match_parent"
android:background="@drawable/loading_shape"
android:id="@+id/aa_thumbnail"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="130dp"
android:orientation="vertical"
android:layout_margin="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/aa_anime_name"
android:text="Anime Title"
android:textStyle="bold"
android:textSize="18sp"/>
<TextView
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Category"
android:id="@+id/aa_categorie"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/aa_rating"
android:text="0.0"
android:layout_marginTop="10dp"
android:background="@drawable/rating_background"
android:textColor="#fff"
android:textSize="15sp"
android:textStyle="bold"
android:drawableLeft="@drawable/ic_star_black_24dp"
android:paddingRight="5dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Studio"
android:layout_marginTop="5dp"
android:id="@+id/aa_studio"/>
</LinearLayout>
</LinearLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:padding="16dp" >
<TextView
android:text="Anime Description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/aa_description"/>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
After we designed the anime activity we need to add the click event to the recyclerview
when the user click on any anime item we should send its related informations to anime activity
open RecyclerViewAdapter under adapters package and update your code to the following


package com.demotxt.myapp.myapplication.adapters;
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.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.demotxt.myapp.myapplication.activities.AnimeActivity;
import com.demotxt.myapp.myapplication.model.Anime;
import com.demotxt.myapp.myapplication.R ;
import java.util.List;
/**
* Created by Aws on 11/03/2018.
*/
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
private Context mContext ;
private List<Anime> mData ;
RequestOptions option;
public RecyclerViewAdapter(Context mContext, List<Anime> mData) {
this.mContext = mContext;
this.mData = mData;
// Request option for Glide
option = new RequestOptions().centerCrop().placeholder(R.drawable.loading_shape).error(R.drawable.loading_shape);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view ;
LayoutInflater inflater = LayoutInflater.from(mContext);
view = inflater.inflate(R.layout.anime_row_item,parent,false) ;
final MyViewHolder viewHolder = new MyViewHolder(view) ;
viewHolder.view_container.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(mContext, AnimeActivity.class);
// sending data process
i.putExtra("anime_name",mData.get(viewHolder.getAdapterPosition()).getName());
i.putExtra("anime_description",mData.get(viewHolder.getAdapterPosition()).getDescription());
i.putExtra("anime_studio",mData.get(viewHolder.getAdapterPosition()).getStudio());
i.putExtra("anime_category",mData.get(viewHolder.getAdapterPosition()).getCategorie());
i.putExtra("anime_nb_episode",mData.get(viewHolder.getAdapterPosition()).getNb_episode());
i.putExtra("anime_rating",mData.get(viewHolder.getAdapterPosition()).getRating());
i.putExtra("anime_img",mData.get(viewHolder.getAdapterPosition()).getImage_url());
mContext.startActivity(i);
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tv_name.setText(mData.get(position).getName());
holder.tv_rating.setText(mData.get(position).getRating());
holder.tv_studio.setText(mData.get(position).getStudio());
holder.tv_category.setText(mData.get(position).getCategorie());
// Load Image from the internet and set it into Imageview using Glide
Glide.with(mContext).load(mData.get(position).getImage_url()).apply(option).into(holder.img_thumbnail);
}
@Override
public int getItemCount() {
return mData.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv_name ;
TextView tv_rating ;
TextView tv_studio ;
TextView tv_category;
ImageView img_thumbnail;
LinearLayout view_container;
public MyViewHolder(View itemView) {
super(itemView);
view_container = itemView.findViewById(R.id.container);
tv_name = itemView.findViewById(R.id.anime_name);
tv_category = itemView.findViewById(R.id.categorie);
tv_rating = itemView.findViewById(R.id.rating);
tv_studio = itemView.findViewById(R.id.studio);
img_thumbnail = itemView.findViewById(R.id.thumbnail);
}
}
}
last step is to manage the recieved informations open your AnimeActivity.java and add the following codes :


package com.demotxt.myapp.myapplication.activities;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.demotxt.myapp.myapplication.R ;
public class AnimeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anime);
// hide the default actionbar
getSupportActionBar().hide();
// Recieve data
String name = getIntent().getExtras().getString("anime_name");
String description = getIntent().getExtras().getString("anime_description");
String studio = getIntent().getExtras().getString("anime_studio") ;
String category = getIntent().getExtras().getString("anime_category");
int nb_episode = getIntent().getExtras().getInt("anime_nb_episode") ;
String rating = getIntent().getExtras().getString("anime_rating") ;
String image_url = getIntent().getExtras().getString("anime_img") ;
// ini views
CollapsingToolbarLayout collapsingToolbarLayout = findViewById(R.id.collapsingtoolbar_id);
collapsingToolbarLayout.setTitleEnabled(true);
TextView tv_name = findViewById(R.id.aa_anime_name);
TextView tv_studio = findViewById(R.id.aa_studio);
TextView tv_categorie = findViewById(R.id.aa_categorie) ;
TextView tv_description = findViewById(R.id.aa_description);
TextView tv_rating = findViewById(R.id.aa_rating) ;
ImageView img = findViewById(R.id.aa_thumbnail);
// setting values to each view
tv_name.setText(name);
tv_categorie.setText(category);
tv_description.setText(description);
tv_rating.setText(rating);
tv_studio.setText(studio);
collapsingToolbarLayout.setTitle(name);
RequestOptions requestOptions = new RequestOptions().centerCrop().placeholder(R.drawable.loading_shape).error(R.drawable.loading_shape);
// set image using Glide
Glide.with(this).load(image_url).apply(requestOptions).into(img);
}
}
Drawable files : loading_shape.xml / rating_background.xml / rippleeffect.xml

loading_shape.xml

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#fafafa"/>
</shape>
rating_background.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorPrimary" />
<corners android:radius="5dp" />
</shape>
rippleeffect.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#e4e4e4"
tools:targetApi="lollipop"> <!-- ripple effect color -->
<item android:id="@android:id/background">
<shape android:shape="rectangle">
<solid android:color="#fcfcfc" /> <!-- background color -->
</shape>
</item>
</ripple>