Skip to content

Commit

Permalink
Setup Cast Recyclerview and navigation between trending and detail fr…
Browse files Browse the repository at this point in the history
…agment
  • Loading branch information
ShashankSinha98 committed Apr 3, 2022
1 parent b422d21 commit 06dca25
Show file tree
Hide file tree
Showing 25 changed files with 460 additions and 104 deletions.
2 changes: 2 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
id 'com.android.application'
id 'androidx.navigation.safeargs'
}

def apikeyPropertiesFile = rootProject.file("apikey.properties")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.shashank.moviedb.common;

public interface MovieOnClickListener {

void onMovieClick(Long movieId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public void fetchNowPlayingMovies(ResourceCallback resourceCallback) {
movieApi.fetchNowPlayingMovie(QueryParams.PARAMS_NOW_PLAYING_MOVIE_API)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.delay(Constants.DUMMY_NETWORK_DELAY, TimeUnit.MILLISECONDS)
.subscribe(new Observer<MovieResponse>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Expand Down Expand Up @@ -75,6 +76,7 @@ public void fetchTrendingMovies(ResourceCallback resourceCallback) {
movieApi.fetchTrendingMovie(TRENDING_TIME_WINDOW, QueryParams.PARAMS_TRENDING_MOVIE_API)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.delay(Constants.DUMMY_NETWORK_DELAY, TimeUnit.MILLISECONDS)
.subscribe(new Observer<MovieResponse>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.shashank.moviedb.di.trending;

import com.shashank.moviedb.ui.detail.DetailFragment;
import com.shashank.moviedb.ui.nowplaying.NowPlayingFragment;
import com.shashank.moviedb.ui.trending.TrendingFragment;

Expand All @@ -14,4 +15,7 @@ public abstract class HomeFragmentBuildersModule {

@ContributesAndroidInjector
abstract NowPlayingFragment contributeNowPlayingFragment();

@ContributesAndroidInjector
abstract DetailFragment contributeDetailFragment();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.RequestManager;
import com.shashank.moviedb.ui.detail.adapter.CastRecyclerAdapter;
import com.shashank.moviedb.ui.trending.adapter.MovieRecyclerAdapter;

import dagger.Module;
Expand All @@ -16,13 +17,8 @@ public class HomeModule {

@HomeScope
@Provides
public static MovieRecyclerAdapter provideMovieRecyclerAdapter(RequestManager requestManager) {
return new MovieRecyclerAdapter(requestManager);
public static CastRecyclerAdapter provideCastRecyclerAdapter(RequestManager requestManager) {
return new CastRecyclerAdapter(requestManager);
}

@HomeScope
@Provides
public static RecyclerView.LayoutManager provideGridLayoutManager(Application application) {
return new GridLayoutManager(application, 2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import androidx.lifecycle.ViewModel;

import com.shashank.moviedb.di.ViewModelKey;
import com.shashank.moviedb.ui.detail.DetailViewModel;
import com.shashank.moviedb.ui.nowplaying.NowPlayingViewModel;
import com.shashank.moviedb.ui.trending.TrendingViewModel;

Expand All @@ -23,4 +24,9 @@ public abstract class HomeViewModelModule {
@IntoMap
@ViewModelKey(NowPlayingViewModel.class)
abstract ViewModel bindNowPlayingViewModel(NowPlayingViewModel nowPlayingViewModel);

@Binds
@IntoMap
@ViewModelKey(DetailViewModel.class)
abstract ViewModel bindDetailViewModel(DetailViewModel detailViewModel);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@

import com.google.gson.annotations.SerializedName;

public class Actor {
public class Cast {

@NonNull private Long id;
@NonNull private String name;
@Nullable @SerializedName("profile_path") private String profilePath;

public Actor() {}
public Cast() {}

public Actor(@NonNull Long id, @NonNull String name, @Nullable String profilePath) {
public Cast(@NonNull Long id, @NonNull String name, @Nullable String profilePath) {
this.id = id;
this.name = name;
this.profilePath = profilePath;
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/java/com/shashank/moviedb/model/Credits.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@

public class Credits {

@Nullable private List<Actor> cast;
@Nullable private List<Cast> cast;

public Credits() {}

public Credits(@Nullable List<Actor> cast) {
public Credits(@Nullable List<Cast> cast) {
this.cast = cast;
}

@Nullable
public List<Actor> getCast() {
public List<Cast> getCast() {
return cast;
}

public void setCast(@Nullable List<Actor> cast) {
public void setCast(@Nullable List<Cast> cast) {
this.cast = cast;
}

Expand Down
41 changes: 4 additions & 37 deletions app/src/main/java/com/shashank/moviedb/ui/HomeActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,43 +76,6 @@ public boolean onSupportNavigateUp() {
return NavigationUI.navigateUp(navController, drawerLayout);
}

/* @Override
public void onDestinationChanged(@NonNull NavController controller,
@NonNull NavDestination destination,
@Nullable Bundle arguments) {
switch (destination.getId()) {
case R.id.nav_trending:
toolbar.setVisibility(View.VISIBLE);
toolbarTextView.setText(destination.getLabel());
break;
}
}*/

/* @Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_trending_movie:
if(isValidDestination(R.id.nav_trending)) {
NavOptions navOptions = new NavOptions.Builder().setPopUpTo(R.id.main_nav_graph, true).build();
Navigation.findNavController(this, R.id.nav_host_fragment).navigate(R.id.nav_trending, null, navOptions);
}
break;
case R.id.menu_now_playing_movie:
if(isValidDestination(R.id.nav_now_playing)) {
Navigation.findNavController(this, R.id.nav_host_fragment).navigate(R.id.nav_now_playing);
}
break;
}
item.setChecked(true);
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}*/

private boolean isValidDestination(int destination) {
return destination != Navigation.findNavController(this, R.id.nav_host_fragment).getCurrentDestination().getId();
Expand All @@ -133,6 +96,10 @@ public void onDestinationChanged(@NonNull NavController controller, @NonNull Nav
toolbarTextView.setText(destination.getLabel());
break;

case R.id.nav_detail:
toolbar.setVisibility(View.GONE);
break;

}
}
}
140 changes: 140 additions & 0 deletions app/src/main/java/com/shashank/moviedb/ui/detail/DetailFragment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package com.shashank.moviedb.ui.detail;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.RequestManager;
import com.shashank.moviedb.R;
import com.shashank.moviedb.common.ViewModelProviderFactory;
import com.shashank.moviedb.data.Resource;
import com.shashank.moviedb.model.Genre;
import com.shashank.moviedb.model.MovieDetail;
import com.shashank.moviedb.ui.detail.adapter.CastRecyclerAdapter;
import com.shashank.moviedb.ui.trending.TrendingViewModel;
import com.shashank.moviedb.util.Constants;

import java.util.List;

import javax.inject.Inject;

import dagger.android.support.DaggerFragment;

public class DetailFragment extends DaggerFragment {

private static final String TAG = "DetailFragment";
private AppCompatImageView ivBackdrop, ivPoster;
private TextView tvMovieTitle, tvVoteAverage, tvDuration, tvGenre, tvDescription, tvQuote;
private RecyclerView castRecyclerView;
private ConstraintLayout detailLayout;

@Inject public ViewModelProviderFactory providerFactory;
@Inject public RequestManager requestManager;
@Inject public CastRecyclerAdapter castRecyclerAdapter;
private DetailViewModel detailViewModel;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.fragment_detail, null);
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

detailViewModel = new ViewModelProvider(this, providerFactory).get(DetailViewModel.class);
initViews(view);
initUI();
initObservers();

Long movieId = DetailFragmentArgs.fromBundle(getArguments()).getMovieId();
detailViewModel.getMovieDetail(movieId);
}

private void initObservers() {
detailViewModel.getMovieDetailLiveData().observe(getViewLifecycleOwner(), new Observer<Resource<MovieDetail>>() {
@Override
public void onChanged(Resource<MovieDetail> movieDetailResource) {
switch (movieDetailResource.getStatus()) {
case SUCCESS:
MovieDetail movieDetail = ((MovieDetail)movieDetailResource.getData());
updateLayoutWithMovieData(movieDetail);
break;
}
}
});
}

private void updateLayoutWithMovieData(MovieDetail movieDetail) {
Log.d(TAG,"xlr8: movieDetail: "+movieDetail);
detailLayout.setVisibility(View.VISIBLE);
tvMovieTitle.setText(movieDetail.getTitle());
tvVoteAverage.setText(movieDetail.getVoteAverage().toString());
tvDuration.setText(getDurationString(movieDetail.getRuntime()));
tvGenre.setText(getGenreString(movieDetail.getGenres()));
tvDescription.setText(movieDetail.getOverview());
tvQuote.setText(movieDetail.getTagline());

requestManager.load(Constants.BASE_IMAGE_URL_API+movieDetail.getPosterPath())
.into(ivPoster);

requestManager.load(Constants.BASE_IMAGE_URL_w500_API+movieDetail.getBackdropPath())
.into(ivBackdrop);
if(movieDetail.getCredits()!=null && movieDetail.getCredits().getCast()!=null)
castRecyclerAdapter.setCast(movieDetail.getCredits().getCast());
}

private String getDurationString(Integer duration) {

if(duration==null) return Constants.CONST_DATA_NA;

int hours = duration/60;
int minutes = duration%60;

return String.format(" %sh %smin", hours, minutes);
}

private String getGenreString(List<Genre> genres) {
if(genres==null || genres.isEmpty()) return Constants.CONST_DATA_NA;

String genreStr = "";
for(Genre genre: genres) {
genreStr += genre.getName() +", ";
}

return genreStr.substring(0,genreStr.length()-1);
}

private void initViews(View view) {
ivBackdrop = view.findViewById(R.id.ivBackdrop);
ivPoster = view.findViewById(R.id.ivPoster);
tvMovieTitle = view.findViewById(R.id.tvMovieTitleValue);
tvVoteAverage = view.findViewById(R.id.tvVoteAverage);
tvDuration = view.findViewById(R.id.tvDuration);
tvGenre = view.findViewById(R.id.tvGenreValue);
tvDescription = view.findViewById(R.id.tvDescriptionValue);
tvQuote = view.findViewById(R.id.tvQuoteValue);
castRecyclerView = view.findViewById(R.id.rvCast);
detailLayout = view.findViewById(R.id.clDetail);
}

private void initUI() {
castRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
castRecyclerView.setAdapter(castRecyclerAdapter);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.shashank.moviedb.ui.detail;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import com.shashank.moviedb.data.Resource;
import com.shashank.moviedb.data.ResourceCallback;
import com.shashank.moviedb.data.remote.MovieRepository;
import com.shashank.moviedb.model.MovieDetail;

import javax.inject.Inject;

public class DetailViewModel extends ViewModel {

private MovieRepository movieRepository;
private MutableLiveData<Resource<MovieDetail>> _movieDetailResponse = new MutableLiveData<>();


@Inject
public DetailViewModel(MovieRepository movieRepository) {
this.movieRepository = movieRepository;
}

public void getMovieDetail(Long movieId) {
movieRepository.fetchMovieDetail(movieId, new ResourceCallback() {
@Override
public void onResponse(Resource resource) {
_movieDetailResponse.postValue(resource);
}
});
}

public LiveData<Resource<MovieDetail>> getMovieDetailLiveData() {
return _movieDetailResponse;
}


}
Loading

0 comments on commit 06dca25

Please sign in to comment.