/* * Copyright (C) ${YEAR} Raul Hernandez Lopez * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.raulh82vlc.topratemovies.activities; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Build; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityOptionsCompat; import android.support.v4.view.ViewCompat; import android.support.v7.graphics.Palette; import android.support.v7.widget.CardView; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.transition.Slide; import android.transition.Transition; import android.view.View; import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ScrollView; import android.widget.TextView; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; import com.raulh82vlc.topratemovies.R; import com.raulh82vlc.topratemovies.models.Constants; import com.raulh82vlc.topratemovies.models.FilmDetailsJSONEntity; import com.raulh82vlc.topratemovies.models.FilmJSONEntity; import com.raulh82vlc.topratemovies.widgets.CompatUtils; import com.raulh82vlc.topratemovies.widgets.TransitionFlowAdapter; import java.util.List; import butterknife.ButterKnife; import butterknife.InjectView; import retrofit.Callback; import retrofit.RetrofitError; import retrofit.client.Response; /** * Created by Raul Hernandez Lopez on 22/02/2015. * CardView where the further details are filled */ public class CardFilmDetailsActivity extends BaseActivity implements View.OnClickListener { // constant private static final String TAG_DETAIL = "FilmDetails"; @InjectView(R.id.imgExtended) ImageView imgExtended; @InjectView(R.id.txtTitle) TextView txtTitle; @InjectView(R.id.txtYear) TextView txtYear; @InjectView(R.id.txtMetaScore) TextView txtMetaScore; @InjectView(R.id.txtGenres) TextView txtGenres; @InjectView(R.id.txtPlot) TextView txtPlot; @InjectView(R.id.txtWriters) TextView txtWriters; @InjectView(R.id.txtDirectors) TextView txtDirectors; @InjectView(R.id.card_film_detail) CardView cardFilmDetail; @InjectView(R.id.toolbar_id) Toolbar mToolbar; @InjectView(R.id.scroll_id) ScrollView mScrollView; @InjectView(R.id.frame_layout) FrameLayout mFrameLayout; @InjectView(R.id.imgRetryCard) ImageButton imgRetryCard; // variable private int ranking = 0; private String mNameOfFilm = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); startAllTransitions(); setContentView(R.layout.card_film_details_view); ActivityCompat.postponeEnterTransition(this); ButterKnife.inject(this); setSupportActionBar(mToolbar); ViewCompat.setTransitionName(imgExtended, Constants.A_NAME_IMG); if (getIntent().getExtras() != null) { Bundle extra = getIntent().getExtras(); String nameOfFilm = extra.getString(Constants.A_NAME_FILM); setmNameOfFilm(nameOfFilm); ranking = extra.getInt(Constants.A_RANKING); // now start the transition ActivityCompat.startPostponedEnterTransition(this); if (isInternetConnectionAvailable()) { getTopRatedFilms(nameOfFilm); } else { seeToast(getString(R.string.try_again)); imgRetryCard.setVisibility(View.VISIBLE); imgRetryCard.setOnClickListener(this); } } } /** * Method getTopRatedFilms * this does the getting from the network's API * then fills all corresponding model entities * and does the UI settings for providing the info corresponding * to each aspect of the film * * @param iFilmName */ private void getTopRatedFilms(final String iFilmName) { getWebServicesApiCalls().getFilmsByName(iFilmName, new Callback<List<FilmDetailsJSONEntity>>() { @Override public void success(List<FilmDetailsJSONEntity> filmDetails, Response response) { if (filmDetails != null && filmDetails.size() > 0) { // Getting the instance of the object from the array returned by the API final FilmDetailsJSONEntity filmDetail = filmDetails.get(0); if (filmDetail != null && !TextUtils.isEmpty(filmDetail.getTitle()) && !TextUtils.isEmpty(filmDetail.getUrlIMDB())) { fillInfo(filmDetail); } else { seeToast(getString(R.string.error_server) + " " + iFilmName); } } } @Override public void failure(RetrofitError error) { } }); } /** * Method fillInfo * all written info is filled * * @param filmDetail */ private void fillInfo(FilmDetailsJSONEntity filmDetail) { fillColors(); /* Setting Film info for the card view */ txtTitle.setText(filmDetail.getTitle()); txtMetaScore.setText("Score: " + filmDetail.getMetascore()); txtYear.setText("Year: " + filmDetail.getYear()); txtPlot.setText(filmDetail.getPlot()); /* Now the collections composed info */ // Writers String aWriters = "Writers: "; aWriters += filmDetail.getToString(filmDetail.getWriters()); txtWriters.setText(aWriters); // Genres txtGenres.setText(filmDetail.getToStringGenres()); // Directors String aDirectors = "Directors: "; aDirectors += filmDetail.getToString(filmDetail.getDirectors()); txtDirectors.setText(aDirectors); fillImage(filmDetail); } /** * Method fillColors * colors of each row are drawn * and the highlight effect of the score */ private void fillColors() { // Setting color if (ranking % 2 == 1) { cardFilmDetail.setCardBackgroundColor(getResources().getColor(R.color.primary)); } else { cardFilmDetail.setCardBackgroundColor(getResources().getColor(R.color.primary_dark)); } txtMetaScore.setBackgroundColor(getResources().getColor(R.color.accent)); } /** * Method fillInfo * all written info is filled * * @param filmDetail */ private void fillImage(FilmDetailsJSONEntity filmDetail) { // Finally the image loaded by Universal Image Loader library final String titleOfFilm = filmDetail.getTitle(); // Load image, decode it to Bitmap and return Bitmap to callback ImageLoader.getInstance().displayImage(filmDetail.getUrlPoster(), imgExtended, new SimpleImageLoadingListener() { @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { // Do whatever you want with Bitmap Palette.generateAsync(loadedImage, new Palette.PaletteAsyncListener() { public void onGenerated(Palette palette) { applyPalette(palette, titleOfFilm); } }); } }); } /** * Method applyPalette * takes the principal colors and set the toolbar * muted color as well as the fade in and starts to pospone the transaction * * @param iPalette input palette * @param titleOfFilm */ private void applyPalette(Palette iPalette, String titleOfFilm) { if (iPalette != null) { int primaryDark = getResources().getColor(R.color.primary_dark); int primary = getResources().getColor(R.color.primary); mToolbar.setBackgroundColor(iPalette.getMutedColor(primary)); CompatUtils.setToolBarColor(getWindow(), iPalette.getDarkMutedColor(primaryDark)); startScrollFadeIn(titleOfFilm); ActivityCompat.startPostponedEnterTransition(this); } } /** * Method startScrollFadeIn * starts the scroll setting the components * and adding the scroll listener when changing it * * @param titleOfFilm */ private void startScrollFadeIn(final String titleOfFilm) { setComponentFeatures(titleOfFilm); mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { setComponentFeatures(titleOfFilm); } }); } /** * Method setComponentFeatures * sets the dynamic translation in y-axis * when users moves the scroll * then calculates the alpha from the color * sets colors and the title in the tootbar * * @param titleOfFilm */ private void setComponentFeatures(String titleOfFilm) { int scrollY = mScrollView.getScrollY(); imgExtended.setTranslationY(-scrollY / 2); ColorDrawable background = (ColorDrawable) mToolbar.getBackground(); int padding = mScrollView.getPaddingTop(); double alphaColor = (1 - (((double) padding - (double) scrollY) / (double) padding)) * 255.0; alphaColor = alphaColor < 0 ? 0 : alphaColor; alphaColor = alphaColor > 255 ? 255 : alphaColor; background.setAlpha((int) alphaColor); mFrameLayout.setBackgroundColor(background.getColor()); float scrollRatio = (float) (alphaColor / 255f); int titleColor = getItsAlphaColor(Color.WHITE, scrollRatio); mToolbar.setTitleTextColor(titleColor); mToolbar.setTitle(titleOfFilm); } /** * Method getItsAlphaColor * if API 21 then effects are settled * * @param iColor alpha of a color * @param scrollRatio float variant */ private int getItsAlphaColor(int iColor, float scrollRatio) { return Color.argb((int) (scrollRatio * 255f), Color.red(iColor), Color.green(iColor), Color.blue(iColor)); } /** * Method startAllTransitions * if API 21 then effects are settled */ private void startAllTransitions() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Slide transition = new Slide(); transition.excludeTarget(android.R.id.statusBarBackground, true); getWindow().setEnterTransition(transition); getWindow().setReturnTransition(transition); } } /** * Method startDetailsActivity * handles and launches the parameters to the Intent * with its corresponding transition * * @param context Activity which should be launched (own CardFilmDetailsActivity) * @param transitionFromPrevImage view * @param iFilm data structure which corresponds to the Film Entity itself */ public static void startDetailsActivity(Activity context, View transitionFromPrevImage, FilmJSONEntity iFilm) { Intent aIntentDetails = new Intent(context, CardFilmDetailsActivity.class); aIntentDetails.putExtra(Constants.A_NAME_FILM, iFilm.getTitle()); aIntentDetails.putExtra(Constants.A_NAME_IMG, iFilm.getUrlPoster()); aIntentDetails.putExtra(Constants.A_RANKING, iFilm.getRanking()); ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(context, transitionFromPrevImage, Constants.A_NAME_IMG); ActivityCompat.startActivity(context, aIntentDetails, optionsCompat.toBundle()); } @Override public void onBackPressed() { fallbackActionBar(); super.onBackPressed(); } /** * Method fallbackActionBar * restores the action bar when back pressed */ private void fallbackActionBar() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (mToolbar != null) { if (getWindow() != null && getWindow().getReturnTransition() != null) { getWindow().getReturnTransition().addListener(new TransitionFlowAdapter() { @Override public void onTransitionEnd(Transition transition) { if (mToolbar != null) { mToolbar.setTitleTextColor(Color.WHITE); if (mToolbar.getBackground() != null) mToolbar.getBackground().setAlpha(255); } } }); } } } } @Override public void onClick(View view) { switch (view.getId()) { case R.id.imgRetryCard: if(isInternetConnectionAvailable()) { getTopRatedFilms(mNameOfFilm); imgRetryCard.setVisibility(View.GONE); } else { seeToast(getString(R.string.try_again)); } break; } } public void setmNameOfFilm(String mNameOfFilm) { this.mNameOfFilm = mNameOfFilm; } }