/*
* Copyright 2015 sourcestream GmbH
*
* 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 de.sourcestream.movieDB.controller;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.ParseException;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.wearable.view.CircledImageView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.AbsListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import de.sourcestream.movieDB.MainActivity;
import de.sourcestream.movieDB.MovieDB;
import de.sourcestream.movieDB.R;
import de.sourcestream.movieDB.adapter.TVDetailsSlideAdapter;
import de.sourcestream.movieDB.helper.ObservableScrollViewCallbacks;
import de.sourcestream.movieDB.helper.ScrollState;
import de.sourcestream.movieDB.helper.Scrollable;
import de.sourcestream.movieDB.model.CastModel;
import de.sourcestream.movieDB.model.SeasonModel;
import de.sourcestream.movieDB.model.SimilarModel;
import de.sourcestream.movieDB.view.MovieDetailsSlidingTabLayout;
import de.sourcestream.movieDB.view.ObservableParallaxScrollView;
public class TVDetails extends Fragment implements ObservableScrollViewCallbacks {
private MainActivity activity;
private View rootView;
private int currentId;
private int timeOut;
private HttpURLConnection conn;
private String title;
private Bundle save;
private ArrayList<SeasonModel> seasonList;
private ArrayList<CastModel> castList;
private ProgressBar spinner;
private int moreIconCheck;
private CircledImageView moreIcon;
private CircledImageView homeIcon;
private int homeIconCheck;
private int galleryIconCheck;
private CircledImageView galleryIcon;
private ArrayList<String> galleryList;
private onGalleryIconClick onGalleryIconClick;
private onMoreIconClick onMoreIconClick;
private onHomeIconClick onHomeIconClick;
private MovieDetailsSlidingTabLayout mSlidingTabLayout;
private ViewPager mViewPager;
private TVDetailsSlideAdapter tvDetailsSlideAdapter;
private onPageChangeSelected onPageChangeSelected;
private TranslateAnimation downAnimation;
private DownAnimationListener downAnimationListener;
private TranslateAnimation upAnimation;
private UpAnimationListener upAnimationListener;
private TranslateAnimation iconUpAnimation;
private IconUpAnimationListener iconUpAnimationListener;
private TranslateAnimation iconDownAnimation;
private IconDownAnimationListener iconDownAnimationListener;
private TVDetailsInfo tvDetailsInfo;
private TVDetailsCast tvDetailsCast;
private TVDetailsOverview tvDetailsOverview;
private int tvDetailsInfoScrollY;
private boolean addToBackStack;
private String homeIconUrl;
private float oldScrollY;
private float dy;
private float upDy;
private float downDy;
private float downDyTrans;
private boolean upDyKey;
private boolean downDyKey;
private float scrollSpeed = 2.2F;
private int currPos;
private boolean infoTabScrollPosUpdated;
private JSONAsyncTask request;
private int iconMarginConstant;
private int iconMarginLandscape;
private int iconConstantSpecialCase;
private int twoIcons;
private int twoIconsToolbar;
private int oneIcon;
private int oneIconToolbar;
private float scale;
private boolean phone;
private int hideThreshold;
private int minThreshold;
private int iconDirection;
private boolean noCast;
public TVDetails() {
}
/**
* Called to do initial creation of a fragment.
* This is called after onAttach(Activity) and before onCreateView(LayoutInflater, ViewGroup, Bundle).
*
* @param savedInstanceState If the fragment is being re-created from a previous saved state, this is the state.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null)
save = savedInstanceState.getBundle("save");
}
/**
* Called to have the fragment instantiate its user interface view.
*
* @param inflater sets the layout for the current view.
* @param container the container which holds the current view.
* @param savedInstanceState If non-null, this fragment is being re-constructed from a previous saved state as given here.
* Return the View for the fragment's UI, or null.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
activity = ((MainActivity) getActivity());
onGalleryIconClick = new onGalleryIconClick();
onMoreIconClick = new onMoreIconClick();
onHomeIconClick = new onHomeIconClick();
onPageChangeSelected = new onPageChangeSelected();
downAnimationListener = new DownAnimationListener();
upAnimationListener = new UpAnimationListener();
iconUpAnimationListener = new IconUpAnimationListener();
iconDownAnimationListener = new IconDownAnimationListener();
phone = getResources().getBoolean(R.bool.portrait_only);
scale = getResources().getDisplayMetrics().density;
if (phone) {
hideThreshold = (int) (-105 * scale);
minThreshold = (int) (-49 * scale);
} else {
hideThreshold = (int) (-100 * scale);
minThreshold = (int) (-42 * scale);
}
if (currentId != this.getArguments().getInt("id") || this.timeOut == 1) {
rootView = inflater.inflate(R.layout.tvdetails, container, false);
spinner = (ProgressBar) rootView.findViewById(R.id.progressBar);
homeIcon = (CircledImageView) rootView.findViewById(R.id.homeIcon);
homeIcon.bringToFront();
homeIcon.setVisibility(View.INVISIBLE);
galleryIcon = (CircledImageView) rootView.findViewById(R.id.galleryIcon);
galleryIcon.bringToFront();
galleryIcon.setVisibility(View.INVISIBLE);
// Highest Z-index has to be declared last
moreIcon = (CircledImageView) rootView.findViewById(R.id.moreIcon);
moreIcon.bringToFront();
}
moreIcon.setOnClickListener(onMoreIconClick);
return rootView;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (activity.getTvDetailsBundle().size() > 0 && activity.getRestoreMovieDetailsState()) {
save = activity.getTvDetailsBundle().get(activity.getTvDetailsBundle().size() - 1);
activity.removeTvDetailsBundle(activity.getTvDetailsBundle().size() - 1);
if (activity.getSearchViewCount())
activity.decSearchTvDetails();
activity.setRestoreMovieDetailsState(false);
}
if (save != null && save.getInt("timeOut") == 1)
activity.setRestoreMovieDetailsAdapterState(true);
// Get the ViewPager and set it's PagerAdapter so that it can display items
tvDetailsSlideAdapter = new TVDetailsSlideAdapter(getChildFragmentManager(), getResources(), activity);
if (mViewPager != null)
currPos = mViewPager.getCurrentItem();
mViewPager = (ViewPager) rootView.findViewById(R.id.tvDetailsPager);
mViewPager.setOffscreenPageLimit(3);
mViewPager.setAdapter(tvDetailsSlideAdapter);
// Give the SlidingTabLayout the ViewPager, this must be done AFTER the ViewPager has had
// it's PagerAdapter set.
mSlidingTabLayout = (MovieDetailsSlidingTabLayout) rootView.findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setViewPager(mViewPager);
mSlidingTabLayout.setSelectedIndicatorColors(ContextCompat.getColor(activity, R.color.tabSelected));
mSlidingTabLayout.bringToFront();
}
/**
* @param savedInstanceState if the fragment is being re-created from a previous saved state, this is the state.
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (save != null) {
setTitle(save.getString("title"));
currentId = save.getInt("currentId");
timeOut = save.getInt("timeOut");
if (timeOut == 0) {
spinner.setVisibility(View.GONE);
onOrientationChange(save);
}
}
if (currentId != this.getArguments().getInt("id") || this.timeOut == 1) {
currentId = this.getArguments().getInt("id");
moreIcon.setVisibility(View.INVISIBLE);
mSlidingTabLayout.setVisibility(View.INVISIBLE);
mViewPager.setVisibility(View.INVISIBLE);
spinner.setVisibility(View.VISIBLE);
request = new JSONAsyncTask();
new Thread(new Runnable() {
public void run() {
try {
request.execute(MovieDB.url + "tv/" + currentId + "?append_to_response=images,credits,similar&api_key=" + MovieDB.key).get(10000, TimeUnit.MILLISECONDS);
} catch (TimeoutException | ExecutionException | InterruptedException | CancellationException e) {
request.cancel(true);
// we abort the http request, else it will cause problems and slow connection later
if (conn != null)
conn.disconnect();
if (spinner != null)
activity.hideView(spinner);
if (mViewPager != null)
activity.hideLayout(mViewPager);
if (getActivity() != null && !(e instanceof CancellationException)) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getActivity(), getResources().getString(R.string.timeout), Toast.LENGTH_SHORT).show();
}
});
}
setTimeOut(1);
}
}
}).start();
}
activity.setTitle(getTitle());
activity.setTvDetailsFragment(this);
if (activity.getSaveInTVDetailsSimFragment()) {
activity.setSaveInTVDetailsSimFragment(false);
activity.setTvDetailsSimFragment(this);
}
new Handler().post(new Runnable() {
@Override
public void run() {
tvDetailsInfo = (TVDetailsInfo) tvDetailsSlideAdapter.getRegisteredFragment(0);
tvDetailsCast = (TVDetailsCast) tvDetailsSlideAdapter.getRegisteredFragment(1);
tvDetailsOverview = (TVDetailsOverview) tvDetailsSlideAdapter.getRegisteredFragment(2);
}
});
showInstantToolbar();
iconMarginConstant = activity.getIconMarginConstant();
iconMarginLandscape = activity.getIconMarginLandscape();
iconConstantSpecialCase = activity.getIconConstantSpecialCase();
twoIcons = activity.getTwoIcons();
twoIconsToolbar = activity.getTwoIconsToolbar();
oneIcon = activity.getOneIcon();
oneIconToolbar = activity.getOneIconToolbar();
Tracker t = ((MovieDB) activity.getApplication()).getTracker();
t.setScreenName("TVDetails - " + getTitle());
t.send(new HitBuilders.ScreenViewBuilder().build());
}
/**
* This class handles the connection to our backend server.
* If the connection is successful we set information on our views.
*/
class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Boolean doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(10000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
int status = conn.getResponseCode();
if (status == 200) {
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
br.close();
JSONObject jsonData = new JSONObject(sb.toString());
// is added checks if we are still on the same view, if we don't do this check the program will crash
while (tvDetailsInfo == null) {
Thread.sleep(200);
}
if (isAdded() && tvDetailsInfo != null) {
// Backdrop path
if (!jsonData.getString("backdrop_path").equals("null") && !jsonData.getString("backdrop_path").isEmpty()) {
activity.setBackDropImage(tvDetailsInfo.getBackDropPath(), jsonData.getString("backdrop_path"));
activity.setImageTag(tvDetailsInfo.getBackDropPath(), jsonData.getString("backdrop_path"));
} else if (!jsonData.getString("poster_path").equals("null") && !jsonData.getString("poster_path").isEmpty()) {
activity.setBackDropImage(tvDetailsInfo.getBackDropPath(), jsonData.getString("poster_path"));
activity.setImageTag(tvDetailsInfo.getBackDropPath(), jsonData.getString("poster_path"));
} else
tvDetailsInfo.setBackDropCheck(1);
// Title
activity.setText(tvDetailsInfo.getTitle(), jsonData.getString("name"));
// Poster path
if (!jsonData.getString("poster_path").equals("null") && !jsonData.getString("poster_path").isEmpty()) {
activity.setImage(tvDetailsInfo.getPosterPath(), jsonData.getString("poster_path"));
activity.setImageTag(tvDetailsInfo.getPosterPath(), jsonData.getString("poster_path"));
}
// Status
if (!jsonData.getString("status").equals("null") && !jsonData.getString("status").isEmpty())
activity.setText(tvDetailsInfo.getStatusText(), jsonData.getString("status"));
else
activity.hideTextView(tvDetailsInfo.getStatusText());
// Type
if (!jsonData.getString("type").equals("null") && !jsonData.getString("type").isEmpty())
activity.setText(tvDetailsInfo.getTypeText(), getResources().getString(R.string.type) + " " + jsonData.getString("type"));
else
activity.hideTextView(tvDetailsInfo.getTypeText());
// Episode runTime
JSONArray episodeRunTimeArray = jsonData.getJSONArray("episode_run_time");
String episodeRunTimeData = "";
if (episodeRunTimeArray.length() == 1)
episodeRunTimeData = episodeRunTimeArray.getString(0) + " " + getResources().getString(R.string.min);
if (episodeRunTimeArray.length() == 2)
episodeRunTimeData = episodeRunTimeArray.getString(0) + " - " + episodeRunTimeArray.getString(1) + " " + getResources().getString(R.string.min);
if (episodeRunTimeArray.length() > 2) {
for (int i = 0; i < episodeRunTimeArray.length(); i++) {
if (i + 1 == episodeRunTimeArray.length())
episodeRunTimeData += episodeRunTimeArray.getString(i) + " " + getResources().getString(R.string.min);
else
episodeRunTimeData += episodeRunTimeArray.getString(i) + ", ";
}
}
if (episodeRunTimeData.isEmpty())
activity.hideTextView(tvDetailsInfo.getEpisodeRuntime());
else
activity.setText(tvDetailsInfo.getEpisodeRuntime(), episodeRunTimeData);
// Number of episodes
if (!jsonData.getString("number_of_episodes").equals("null") && !jsonData.getString("number_of_episodes").isEmpty())
activity.setText(tvDetailsInfo.getNumberOfEpisodesText(), getResources().getString(R.string.numberOfEpisodes) + " " + jsonData.getString("number_of_episodes"));
else
activity.hideTextView(tvDetailsInfo.getNumberOfEpisodesText());
// Number of seasons
if (!jsonData.getString("number_of_seasons").equals("null") && !jsonData.getString("number_of_seasons").isEmpty())
activity.setText(tvDetailsInfo.getNumberOfSeasonsText(), getResources().getString(R.string.numberOfSeasons) + " " + jsonData.getString("number_of_seasons"));
else
activity.hideTextView(tvDetailsInfo.getNumberOfSeasonsText());
// First air date
if (!jsonData.getString("first_air_date").equals("null") && !jsonData.getString("first_air_date").isEmpty()) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
try {
Date date = sdf.parse(jsonData.getString("first_air_date"));
String formattedDate = activity.getDateFormat().format(date);
activity.setText(tvDetailsInfo.getFirstAirDateText(), getResources().getString(R.string.firstAirDate) + " " + formattedDate);
} catch (java.text.ParseException e) {
activity.hideTextView(tvDetailsInfo.getFirstAirDateText());
}
} else
activity.hideTextView(tvDetailsInfo.getFirstAirDateText());
// Last air date
if (!jsonData.getString("last_air_date").equals("null") && !jsonData.getString("last_air_date").isEmpty()) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
try {
Date date = sdf.parse(jsonData.getString("last_air_date"));
String formattedDate = activity.getDateFormat().format(date);
activity.setText(tvDetailsInfo.getLastAirDateText(), getResources().getString(R.string.lastAirDate) + " " + formattedDate);
} catch (java.text.ParseException e) {
activity.hideTextView(tvDetailsInfo.getLastAirDateText());
}
} else
activity.hideTextView(tvDetailsInfo.getLastAirDateText());
// Homepage icon
if (!jsonData.getString("homepage").isEmpty() && !jsonData.getString("homepage").equals("null")) {
homeIconUrl = jsonData.getString("homepage");
homeIconCheck = 0;
} else {
activity.invisibleView(homeIcon);
homeIconCheck = 1;
}
// Gallery
JSONObject galleryObject = jsonData.getJSONObject("images");
JSONArray galleryBackdropsArray = galleryObject.getJSONArray("backdrops");
JSONArray galleryPosterArray = galleryObject.getJSONArray("posters");
galleryList = new ArrayList<>();
if (galleryPosterArray.length() > 0 || galleryBackdropsArray.length() > 0) {
for (int i = 0; i < galleryBackdropsArray.length(); i++) {
JSONObject object = galleryBackdropsArray.getJSONObject(i);
galleryList.add(object.getString("file_path"));
}
for (int i = 0; i < galleryPosterArray.length(); i++) {
JSONObject object = galleryPosterArray.getJSONObject(i);
galleryList.add(object.getString("file_path"));
}
galleryIconCheck = 0;
} else {
activity.invisibleView(galleryIcon);
galleryIconCheck = 1;
}
// Genres
JSONArray genresArray = jsonData.getJSONArray("genres");
String genresData = "";
for (int i = 0; i < genresArray.length(); i++) {
if (i + 1 == genresArray.length())
genresData += genresArray.getJSONObject(i).get("name");
else
genresData += genresArray.getJSONObject(i).get("name") + ", ";
}
if (genresData.isEmpty())
activity.hideTextView(tvDetailsInfo.getGenres());
else {
activity.setText(tvDetailsInfo.getGenres(), genresData);
}
// Origin countries
JSONArray countriesArray = jsonData.getJSONArray("origin_country");
String countriesData = "";
for (int i = 0; i < countriesArray.length(); i++) {
if (i + 1 == countriesArray.length())
countriesData += countriesArray.getString(i);
else
countriesData += countriesArray.getString(i) + "\n";
}
if (countriesData.isEmpty())
activity.hideTextView(tvDetailsInfo.getCountries());
else {
activity.setText(tvDetailsInfo.getCountries(), countriesData);
}
// Production companies
JSONArray companiesArray = jsonData.getJSONArray("production_companies");
String companiesData = "";
for (int i = 0; i < companiesArray.length(); i++) {
if (i + 1 == companiesArray.length())
companiesData += companiesArray.getJSONObject(i).get("name");
else
companiesData += companiesArray.getJSONObject(i).get("name") + "\n";
}
if (companiesData.isEmpty())
activity.hideTextView(tvDetailsInfo.getCompanies());
else {
activity.setText(tvDetailsInfo.getCompanies(), companiesData);
// if countries is empty we need to set the margin on companies
if (countriesData.isEmpty()) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) tvDetailsInfo.getCompanies().getLayoutParams();
lp.setMargins(0, (int) (28 * scale), 0, 0);
}
});
}
}
// Rating
if (Float.parseFloat(jsonData.getString("vote_average")) == 0.0f) {
activity.hideRatingBar(tvDetailsInfo.getRatingBar());
activity.hideTextView(tvDetailsInfo.getVoteCount());
} else {
activity.setRatingBarValue(tvDetailsInfo.getRatingBar(), (Float.parseFloat(jsonData.getString("vote_average")) / 2));
activity.setText(tvDetailsInfo.getVoteCount(), jsonData.getString("vote_count") + " " + getString(R.string.voteCount));
}
/* //Season info
JSONArray seasonArray = jsonData.getJSONArray("seasons");
seasonList = new ArrayList<>();
for (int i = 0; i < seasonArray.length(); i++) {
JSONObject object = seasonArray.getJSONObject(i);
SeasonModel season = new SeasonModel();
season.setId(object.getInt("id"));
if (!object.getString("season_number").equals("null") && !object.getString("season_number").isEmpty())
season.setTitle(jsonData.getString("original_name") + " " + getResources().getString(R.string.season) + " " + object.getString("season_number"));
else
season.setTitle(jsonData.getString("original_name"));
if (!object.getString("episode_count").equals("null") && !object.getString("episode_count").isEmpty())
season.setEpisodeCount(getResources().getString(R.string.episodes) + " " + object.getString("episode_count"));
if (!object.getString("air_date").equals("null") && !object.getString("air_date").isEmpty())
season.setAirDate(getResources().getString(R.string.airDate) + " " + object.getString("air_date"));
if (!object.getString("poster_path").equals("null") && !object.getString("poster_path").isEmpty())
season.setPosterPath(MovieDB.imageUrl + getResources().getString(R.string.imageSize) + object.getString("poster_path"));
seasonList.add(season);
}*/
//Cast info
JSONObject casts = jsonData.getJSONObject("credits");
JSONArray castsArray = casts.getJSONArray("cast");
castList = new ArrayList<>();
for (int i = 0; i < castsArray.length(); i++) {
JSONObject object = castsArray.getJSONObject(i);
CastModel cast = new CastModel();
cast.setId(object.getInt("id"));
cast.setName(object.getString("name"));
cast.setCharacter(object.getString("character"));
if (!object.getString("profile_path").equals("null") && !object.getString("profile_path").isEmpty())
cast.setProfilePath(MovieDB.imageUrl + getResources().getString(R.string.imageSize) + object.getString("profile_path"));
castList.add(cast);
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (castList.size() == 0) {
noCast = true;
mSlidingTabLayout.disableTabClickListener(1);
}
// Cast
if (isAdded())
tvDetailsCast.setAdapter(castList);
}
});
//Overview
final String overview = jsonData.getString("overview");
if (!overview.equals("null") && !overview.isEmpty())
activity.setText(tvDetailsOverview.getOverview(), overview);
else
activity.setText(tvDetailsOverview.getOverview(), getResources().getString(R.string.noOverview));
// Similar
JSONObject similarObj = jsonData.getJSONObject("similar");
JSONArray similarArray = similarObj.getJSONArray("results");
int similarLen = similarArray.length();
if (similarLen > 6)
similarLen = 6;
if (similarLen == 0)
activity.hideView(tvDetailsInfo.getSimilarHolder());
else {
final ArrayList<SimilarModel> similarList = new ArrayList<>();
for (int i = 0; i < similarLen; i++) {
JSONObject object = similarArray.getJSONObject(i);
SimilarModel similarModel = new SimilarModel();
similarModel.setId(object.getInt("id"));
similarModel.setTitle(object.getString("name"));
if (!object.getString("poster_path").equals("null") && !object.getString("poster_path").isEmpty())
similarModel.setPosterPath(MovieDB.imageUrl + getResources().getString(R.string.imageSize) + object.getString("poster_path"));
if (!object.getString("first_air_date").equals("null") && !object.getString("first_air_date").isEmpty())
similarModel.setReleaseDate(object.getString("first_air_date"));
similarList.add(similarModel);
}
activity.runOnUiThread(new Runnable() {
public void run() {
if (isAdded())
tvDetailsInfo.setSimilarList(similarList);
}
});
}
return true;
}
}
} catch (ParseException | IOException | JSONException e) {
if (conn != null)
conn.disconnect();
} catch (InterruptedException e) {
} finally {
if (conn != null)
conn.disconnect();
}
return false;
}
/**
* Fired after doInBackground() has finished
*
* @param result true if connection is successful, false if connection has failed.
*/
protected void onPostExecute(Boolean result) {
// is added checks if we are still on the same view, if we don't do this check the program will cra
if (isAdded()) {
if (!result) {
Toast.makeText(getActivity(), R.string.noConnection, Toast.LENGTH_LONG).show();
setTimeOut(1);
spinner.setVisibility(View.GONE);
mViewPager.setVisibility(View.GONE);
} else {
setTimeOut(0);
currPos = 0;
mViewPager.setCurrentItem(0);
spinner.setVisibility(View.GONE);
mSlidingTabLayout.setVisibility(View.VISIBLE);
mViewPager.setVisibility(View.VISIBLE);
mSlidingTabLayout.setOnPageChangeListener(onPageChangeSelected);
if (homeIconCheck == 1 && galleryIconCheck == 1) {
moreIconCheck = 1;
activity.hideView(moreIcon);
activity.hideView(tvDetailsInfo.getMoreIcon());
} else {
moreIconCheck = 0;
activity.showView(tvDetailsInfo.getMoreIcon());
// set listener on backdrop and poster path click to open gallery
if (galleryIconCheck == 0) {
tvDetailsInfo.getBackDropPath().setOnClickListener(onGalleryIconClick);
tvDetailsInfo.getPosterPath().setOnClickListener(onGalleryIconClick);
}
adjustIconsPos(homeIcon, galleryIcon);
adjustIconsPos(tvDetailsInfo.getHomeIcon(), tvDetailsInfo.getGalleryIcon());
}
}
} else setTimeOut(1);
}
}
/**
* We use this key to know if the user has tried to open this movie and the connection failed.
* So if he tries to load again the same movie we know that the connection has failed and we need to make a new request.
*/
public void setTimeOut(int timeOut) {
this.timeOut = timeOut;
}
/**
* Updates the timeOut value.
*/
public int getTimeOut() {
return timeOut;
}
/**
* Update the title. We use this method to save our title and then to set it on the Toolbar.
*/
public void setTitle(String title) {
this.title = title;
}
/**
* Get the title.
*/
private String getTitle() {
return this.title;
}
/**
* Called to ask the fragment to save its current dynamic state,
* so it can later be reconstructed in a new instance of its process is restarted.
*
* @param outState Bundle in which to place your saved state.
*/
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Used to avoid bug where we add item in the back stack
// and if we change orientation twice the item from the back stack has null values
if (save != null && save.getInt("timeOut") == 1)
save = null;
save = null;
if (save != null) {
if (tvDetailsCast != null)
save.putInt("lastVisitedPerson", tvDetailsCast.getLastVisitedPerson());
outState.putBundle("save", save);
if (addToBackStack) {
activity.addTvDetailsBundle(save);
addToBackStack = false;
}
} else {
Bundle send = new Bundle();
send.putInt("currentId", currentId);
if (request != null && request.getStatus() == AsyncTask.Status.RUNNING) {
timeOut = 1;
request.cancel(true);
}
send.putInt("timeOut", timeOut);
send.putString("title", title);
if (timeOut == 0) {
// HomePage
send.putInt("homeIconCheck", homeIconCheck);
if (homeIconCheck == 0)
send.putString("homepage", homeIconUrl);
// Gallery icon
send.putInt("galleryIconCheck", galleryIconCheck);
if (galleryIconCheck == 0)
send.putStringArrayList("galleryList", galleryList);
// More icon
send.putInt("moreIconCheck", moreIconCheck);
// used to pass the data to the castList view
send.putParcelableArrayList("seasonList", seasonList);
}
// TV details info begins here
if (tvDetailsInfo != null) {
// Backdrop path
send.putInt("backDropCheck", tvDetailsInfo.getBackDropCheck());
if (tvDetailsInfo.getBackDropCheck() == 0 && tvDetailsInfo.getBackDropPath().getTag() != null)
send.putString("backDropUrl", tvDetailsInfo.getBackDropPath().getTag().toString());
// Poster path url
if (tvDetailsInfo.getPosterPath().getTag() != null)
send.putString("posterPathURL", tvDetailsInfo.getPosterPath().getTag().toString());
// Rating
send.putFloat("rating", tvDetailsInfo.getRatingBar().getRating());
send.putString("voteCount", tvDetailsInfo.getVoteCount().getText().toString());
// Title
send.putString("titleText", tvDetailsInfo.getTitle().getText().toString());
// Status
send.putString("status", tvDetailsInfo.getStatusText().getText().toString());
// Type
send.putString("typeText", tvDetailsInfo.getTypeText().getText().toString());
// Episode runtime
send.putString("episodeRuntime", tvDetailsInfo.getEpisodeRuntime().getText().toString());
// Number of episodes
send.putString("numberOfEpisodesText", tvDetailsInfo.getNumberOfEpisodesText().getText().toString());
// Number of seasons
send.putString("numberOfSeasonsText", tvDetailsInfo.getNumberOfSeasonsText().getText().toString());
// First air date
send.putString("firstAirDateText", tvDetailsInfo.getFirstAirDateText().getText().toString());
// Last air date
send.putString("lastAirDateText", tvDetailsInfo.getLastAirDateText().getText().toString());
// Genres
send.putString("genres", tvDetailsInfo.getGenres().getText().toString());
// Production countries
send.putString("productionCountries", tvDetailsInfo.getCountries().getText().toString());
// Production companies
send.putString("productionCompanies", tvDetailsInfo.getCompanies().getText().toString());
// Similar list
if (tvDetailsInfo.getSimilarList() != null && tvDetailsInfo.getSimilarList().size() > 0)
send.putParcelableArrayList("similarList", tvDetailsInfo.getSimilarList());
}
// TV details info ends here
// TV details cast starts here
if (tvDetailsCast != null) {
send.putParcelableArrayList("castList", castList);
send.putInt("lastVisitedPerson", tvDetailsCast.getLastVisitedPerson());
}
// TV details cast ends here
if (tvDetailsOverview != null)
send.putString("overview", tvDetailsOverview.getOverview().getText().toString());
outState.putBundle("save", send);
save = send;
if (addToBackStack) {
activity.addTvDetailsBundle(send);
addToBackStack = false;
}
}
}
/**
* Fired when are restoring from backState or orientation has changed.
*
* @param args our bundle with saved state.
*/
private void onOrientationChange(Bundle args) {
// Home page
homeIconCheck = args.getInt("homeIconCheck");
if (homeIconCheck == 0)
homeIconUrl = args.getString("homepage");
// Gallery
galleryIconCheck = args.getInt("galleryIconCheck");
if (galleryIconCheck == 0) {
galleryList = new ArrayList<>();
galleryList = args.getStringArrayList("galleryList");
if (galleryList.size() == 0)
activity.hideView(galleryIcon);
}
// More icon
moreIconCheck = args.getInt("moreIconCheck");
if (homeIconCheck == 1 && galleryIconCheck == 1) {
moreIconCheck = 1;
moreIcon.setVisibility(View.GONE);
} else moreIconCheck = 0;
mSlidingTabLayout.setOnPageChangeListener(onPageChangeSelected);
activity.setTVDetailsInfoBundle(save);
activity.setTVDetailsCastBundle(save);
activity.setTVDetailsOverviewBundle(save);
castList = save.getParcelableArrayList("castList");
if (castList != null && castList.size() == 0) {
noCast = true;
mSlidingTabLayout.disableTabClickListener(1);
}
new Handler().post(new Runnable() {
@Override
public void run() {
tvDetailsInfo = (TVDetailsInfo) tvDetailsSlideAdapter.getRegisteredFragment(0);
if (currPos == 0) {
moreIcon.setVisibility(View.INVISIBLE);
} else if (moreIconCheck == 0) {
tvDetailsInfo.getMoreIcon().setVisibility(View.INVISIBLE);
updateDownPos();
}
if (moreIconCheck == 1)
tvDetailsInfo.getMoreIcon().setVisibility(View.GONE);
else {
// set listener on backdrop and poster path click to open gallery
if (galleryIconCheck == 0 && galleryList.size() > 0) {
tvDetailsInfo.getBackDropPath().setOnClickListener(onGalleryIconClick);
tvDetailsInfo.getPosterPath().setOnClickListener(onGalleryIconClick);
}
adjustIconsPos(homeIcon, galleryIcon);
adjustIconsPos(tvDetailsInfo.getHomeIcon(), tvDetailsInfo.getGalleryIcon());
}
// disable orientation changing, enable nav drawer sliding, show toolbar
if (galleryIconCheck == 0 && galleryList.size() == 1) {
activity.getWindow().getDecorView().setBackgroundColor(ContextCompat.getColor(activity, R.color.background_material_light));
if (activity.getSupportActionBar() != null)
activity.getSupportActionBar().show();
activity.getMDrawerLayout().setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
if (Build.VERSION.SDK_INT >= 19)
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
// Check orientation and lock to portrait if we are on phone
if (getResources().getBoolean(R.bool.portrait_only))
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
});
}
/**
* Class which listens when the user has tapped on More icon button.
*/
public class onMoreIconClick implements View.OnClickListener {
private boolean key;
private boolean toolbarHidden;
private int items;
private View toolbarView = activity.findViewById(R.id.toolbar);
private int currScroll;
public onMoreIconClick() {
// keep references for your onClick logic
}
public boolean getKey() {
return key;
}
public void setKey(boolean key) {
this.key = key;
}
@Override
public void onClick(View v) {
items = homeIconCheck + galleryIconCheck;
toolbarHidden = toolbarView.getTranslationY() == -toolbarView.getHeight();
currScroll = tvDetailsInfo.getRootView().getScrollY();
if (!key) {
iconDirection = 1;
if (currPos == 0) {
// 2 icons
if (items == 0) {
if (toolbarHidden && currScroll / scale > twoIcons) {
iconDirection = -1;
} else if (!toolbarHidden && currScroll / scale > twoIconsToolbar) {
iconDirection = -1;
}
}
// 1 icon
if (items == 1) {
if (toolbarHidden && currScroll / scale > oneIcon) {
iconDirection = -1;
} else if (!toolbarHidden && currScroll / scale > oneIconToolbar) {
iconDirection = -1;
}
}
}
if (currPos == 0) {
tvDetailsInfo.getMoreIcon().setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.ic_close_white_36dp));
showHideImages(View.VISIBLE, tvDetailsInfo.getHomeIcon(), tvDetailsInfo.getGalleryIcon());
} else {
moreIcon.setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.ic_close_white_36dp));
showHideImages(View.VISIBLE, homeIcon, galleryIcon);
}
key = true;
} else {
if (currPos == 0) {
tvDetailsInfo.getMoreIcon().setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.ic_more_vert_white_36dp));
showHideImages(View.INVISIBLE, tvDetailsInfo.getHomeIcon(), tvDetailsInfo.getGalleryIcon());
} else {
moreIcon.setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.ic_more_vert_white_36dp));
showHideImages(View.INVISIBLE, homeIcon, galleryIcon);
}
key = false;
}
}
}
/**
* Class which listens when the user has tapped on Home icon button.
*/
public class onHomeIconClick implements View.OnClickListener {
public onHomeIconClick() {
// keep references for your onClick logic
}
@Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(homeIcon.getTag().toString()));
startActivity(i);
}
}
/**
* Class which listens when the user has tapped on Gallery icon button.
*/
public class onGalleryIconClick implements View.OnClickListener {
public onGalleryIconClick() {
// keep references for your onClick logic
}
@Override
public void onClick(View v) {
if (activity.getSearchViewCount())
activity.incSearchTvDetails();
if (galleryList.size() == 1) {
setAddToBackStack(true);
onSaveInstanceState(new Bundle());
if (activity.getSupportActionBar() != null)
activity.getSupportActionBar().hide();
activity.getWindow().getDecorView().setBackgroundColor(ContextCompat.getColor(activity, R.color.black));
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.frame_container, GalleryPreviewDetail.newInstance(MovieDB.imageUrl + getResources().getString(R.string.galleryPreviewImgSize) + galleryList.get(0)));
// add the current transaction to the back stack:
transaction.addToBackStack("movieDetails");
transaction.commit();
} else {
try {
setAddToBackStack(true);
onSaveInstanceState(new Bundle());
showInstantToolbar();
activity.getGalleryListView().setTitle(getTitle());
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
Bundle args = new Bundle();
args.putStringArrayList("galleryList", galleryList);
activity.getGalleryListView().setArguments(args);
transaction.replace(R.id.frame_container, activity.getGalleryListView());
// add the current transaction to the back stack:
transaction.addToBackStack("movieDetails");
transaction.commit();
} catch (java.lang.IllegalStateException e) {
GalleryList galleryListView = new GalleryList();
galleryListView.setTitle(getTitle());
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
Bundle args = new Bundle();
args.putStringArrayList("galleryList", galleryList);
galleryListView.setArguments(args);
transaction.replace(R.id.frame_container, galleryListView);
// add the current transaction to the back stack:
transaction.addToBackStack("movieDetails");
transaction.commit();
}
}
}
}
/**
* Class which listens when the user has changed the tap in Movie details
*/
public class onPageChangeSelected implements ViewPager.OnPageChangeListener {
private boolean toolbarHidden;
private View toolbarView = activity.findViewById(R.id.toolbar);
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (noCast) {
if (position == 1 && currPos == 2) {
mViewPager.setCurrentItem(0);
return;
}
if (position == 1 && currPos == 0) {
mViewPager.setCurrentItem(2);
return;
}
}
if (toolbarView != null)
toolbarHidden = toolbarView.getTranslationY() == -toolbarView.getHeight();
if (position == 0) {
scrollSpeed = 2.2F;
if (tvDetailsInfo != null) {
if (119 * scale <= (tvDetailsInfo.getScrollView().getChildAt(0).getHeight() - (567 * scale)) && tvDetailsInfo.canScroll()) {
if (toolbarHidden) {
final ObservableParallaxScrollView scrollView = tvDetailsInfo.getScrollView();
if (scrollView.getCurrentScrollY() / scale < 119) {
infoTabScrollPosUpdated = true;
scrollView.post(new Runnable() {
@Override
public void run() {
scrollView.scrollTo(0, (int) (119 * scale));
}
});
}
}
} else
showInstantToolbar();
}
} else scrollSpeed = 1;
if (position == 1 && tvDetailsCast != null) {
if (tvDetailsCast.getCastList() != null && tvDetailsCast.getCastList().size() > 0) {
final AbsListView listView = tvDetailsCast.getListView();
if (tvDetailsCast.canScroll()) {
listView.post(new Runnable() {
@Override
public void run() {
if (toolbarHidden && ((Scrollable) listView).getCurrentScrollY() < minThreshold) {
if (phone)
listView.smoothScrollBy((int) (56 * scale), 0);
else
listView.smoothScrollBy((int) (65 * scale), 0);
}
}
});
} else {
if (toolbarHidden)
showInstantToolbar();
}
} else {
if (toolbarHidden)
showInstantToolbar();
}
}
if (position == 2 && tvDetailsOverview != null) {
tvDetailsOverview.getScrollView().post(new Runnable() {
@Override
public void run() {
if (toolbarHidden)
tvDetailsOverview.getScrollView().scrollTo(0, (int) (56 * scale));
else
tvDetailsOverview.getScrollView().scrollTo(0, 0);
}
});
}
if (moreIconCheck == 0) {
if (tvDetailsInfo != null) {
tvDetailsInfoScrollY = tvDetailsInfo.getRootView().getScrollY();
galleryIcon.clearAnimation();
homeIcon.clearAnimation();
homeIcon.setVisibility(View.INVISIBLE);
tvDetailsInfo.getHomeIcon().setVisibility(View.INVISIBLE);
galleryIcon.setVisibility(View.INVISIBLE);
tvDetailsInfo.getGalleryIcon().setVisibility(View.INVISIBLE);
moreIcon.setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.ic_more_vert_white_36dp));
if (position == 0) {
tvDetailsInfo.getMoreIcon().setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.ic_more_vert_white_36dp));
moreIcon.setVisibility(View.INVISIBLE);
} else {
tvDetailsInfo.getMoreIcon().setVisibility(View.INVISIBLE);
}
onMoreIconClick.setKey(false);
if (currPos == 0 && position == 1) {
updateUpPos();
createDownAnimation();
moreIcon.startAnimation(downAnimation);
}
if (currPos == 0 && position == 2) {
updateUpPos();
createDownAnimation();
moreIcon.startAnimation(downAnimation);
}
if (currPos == 1 && position == 0) {
updateDownPos();
// we have a special case here if this is true, this means that we have been in the cast tab
// we have hidden the toolbar and we are returning to the info tab where the scrollY was 0
// so earlier in this function we updated the scrollY value and now we need to update the
// animation value else the icon will "jump"
if (infoTabScrollPosUpdated) {
infoTabScrollPosUpdated = false;
createUpAnimation((119 * scale) - tvDetailsInfo.getScrollView().getCurrentScrollY());
} else
createUpAnimation(0);
moreIcon.startAnimation(upAnimation);
}
if (currPos == 2 && position == 0) {
updateDownPos();
if (infoTabScrollPosUpdated) {
infoTabScrollPosUpdated = false;
createUpAnimation((119 * scale) - tvDetailsInfo.getScrollView().getCurrentScrollY());
} else
createUpAnimation(0);
moreIcon.startAnimation(upAnimation);
}
}
}
if (!noCast || position != 1)
currPos = position;
}
}
/**
* Listener which updates the icons position after the animation ended.
*/
private class DownAnimationListener implements Animation.AnimationListener {
@Override
public void onAnimationEnd(Animation animation) {
moreIcon.clearAnimation();
updateDownPos();
moreIcon.setVisibility(View.VISIBLE);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) moreIcon.getLayoutParams();
layoutParams.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
layoutParams.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
moreIcon.setLayoutParams(layoutParams);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationStart(Animation animation) {
}
}
/**
* Updates the icons position when called.
*/
public void updateDownPos() {
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(moreIcon.getWidth(), moreIcon.getHeight());
RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams(homeIcon.getWidth(), homeIcon.getHeight());
RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams(galleryIcon.getWidth(), galleryIcon.getHeight());
lp.addRule(RelativeLayout.ALIGN_PARENT_END);
lp1.addRule(RelativeLayout.ALIGN_PARENT_END);
lp2.addRule(RelativeLayout.ALIGN_PARENT_END);
lp.setMargins(0, (int) (scale * (496 + iconMarginConstant - iconMarginLandscape + iconConstantSpecialCase) + 0.5f), (int) (scale * 15 + 0.5f), 0);
moreIcon.setLayoutParams(lp);
lp1.setMargins(0, (int) (scale * (439 + iconMarginConstant - iconMarginLandscape + iconConstantSpecialCase) + 0.5f), (int) (scale * 23 + 0.5f), 0);
homeIcon.setLayoutParams(lp1);
lp2.setMargins(0, (int) (scale * (383.3 + iconMarginConstant - iconMarginLandscape + iconConstantSpecialCase) + 0.5f), (int) (scale * 23 + 0.5f), 0);
galleryIcon.setLayoutParams(lp2);
}
/**
* Listener which updates the icons position after the animation ended.
*/
private class UpAnimationListener implements Animation.AnimationListener {
@Override
public void onAnimationEnd(Animation animation) {
tvDetailsInfo.getMoreIcon().clearAnimation();
tvDetailsInfo.getMoreIcon().setVisibility(View.VISIBLE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationStart(Animation animation) {
}
}
/**
* Updates the icons position when called.
*/
public void updateUpPos() {
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(moreIcon.getWidth(), moreIcon.getHeight());
RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams(homeIcon.getWidth(), homeIcon.getHeight());
RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams(galleryIcon.getWidth(), galleryIcon.getHeight());
lp.addRule(RelativeLayout.ALIGN_PARENT_END);
lp1.addRule(RelativeLayout.ALIGN_PARENT_END);
lp2.addRule(RelativeLayout.ALIGN_PARENT_END);
lp.setMargins(0, (int) (scale * (346 + iconMarginConstant) + 0.5f - tvDetailsInfoScrollY), (int) (scale * 15 + 0.5f), 0);
moreIcon.setLayoutParams(lp);
}
/**
* Creates animation for the More Icon with down direction.
*/
public void createDownAnimation() {
// if this is 300 this means that we are on tablet and orientation is landscape
// we do this else the animation will go off screen
// so if we are on landscape we change the direction of the animation
if (iconMarginLandscape == 300)
downAnimation = new TranslateAnimation(0, 0, 0, -scale * 150 + 0.5f + tvDetailsInfoScrollY);
else
downAnimation = new TranslateAnimation(0, 0, 0, scale * (150 + iconConstantSpecialCase) + 0.5f + tvDetailsInfoScrollY);
downAnimation.setDuration(500);
downAnimation.setFillAfter(false);
downAnimation.setAnimationListener(downAnimationListener);
}
/**
* Creates animation for the More Icon with up direction.
*/
public void createUpAnimation(float dy) {
// if this is 300 this means that we are on tablet and orientation is landscape
// we do this else the animation will go off screen
// so if we are on landscape we change the direction of the animation
if (iconMarginLandscape == 300)
upAnimation = new TranslateAnimation(0, 0, 0, scale * 150 + 0.5f - tvDetailsInfoScrollY - dy);
else
upAnimation = new TranslateAnimation(0, 0, 0, -scale * (150 + iconConstantSpecialCase) + 0.5f - tvDetailsInfoScrollY - dy);
upAnimation.setDuration(500);
upAnimation.setFillAfter(false);
upAnimation.setAnimationListener(upAnimationListener);
}
public TVDetails.onMoreIconClick getOnMoreIconClick() {
return onMoreIconClick;
}
public Bundle getSave() {
return save;
}
public void setSave(Bundle save) {
this.save = save;
}
public void setAddToBackStack(boolean addToBackStack) {
this.addToBackStack = addToBackStack;
}
/**
* This method calculates what icons do we have.
*
* @param homeIcon the first icon
* @param galleryIcon the second icon
*/
public void adjustIconsPos(CircledImageView homeIcon, CircledImageView galleryIcon) {
int iconCount[] = {homeIconCheck, galleryIconCheck};
ArrayList<CircledImageView> circledImageViews = new ArrayList<>();
circledImageViews.add(homeIcon);
circledImageViews.add(galleryIcon);
for (int i = 0; i < iconCount.length; i++) {
if (iconCount[i] == 1)
circledImageViews.get(circledImageViews.size() - 1).setVisibility(View.INVISIBLE);
else {
CircledImageView temp = circledImageViews.get(0);
switch (i) {
case 0:
temp.setOnClickListener(onHomeIconClick);
temp.setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.ic_home_white_24dp));
temp.setTag(homeIconUrl);
break;
case 1:
temp.setOnClickListener(onGalleryIconClick);
temp.setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.ic_photo_camera_white_24dp));
break;
}
circledImageViews.remove(0);
}
}
}
/**
* Fired from the on More Icon click listeners. Updates the visibility of the gallery and homePage icon.
* And creates animation for them also.
*
* @param visibility visibility value
* @param homeIcon first icon
* @param galleryIcon second icon
*/
public void showHideImages(int visibility, CircledImageView homeIcon, CircledImageView galleryIcon) {
float dy[] = {0.7f, 56.7f};
float infoTabDy[] = {-2.4f, 53.5f};
int currDy = 0;
int delay = 100;
int iconCount[] = {homeIconCheck, galleryIconCheck};
ArrayList<CircledImageView> circledImageViews = new ArrayList<>();
circledImageViews.add(homeIcon);
circledImageViews.add(galleryIcon);
if (visibility == View.VISIBLE) {
if (currPos != 0)
updateIconDownPos();
else
updateIconDownPosInInfoTab();
} else {
if (currPos != 0)
updateIconUpPos();
else
updateIconUpPosInInfoTab();
}
for (int i = 0; i < iconCount.length; i++) {
if (iconCount[i] == 1)
circledImageViews.get(circledImageViews.size() - 1).setVisibility(View.INVISIBLE);
else {
CircledImageView temp = circledImageViews.get(0);
if (visibility == View.VISIBLE) {
if (currPos == 0)
createIconUpAnimation(infoTabDy[currDy], delay);
else
createIconUpAnimation(dy[currDy], delay);
temp.startAnimation(iconUpAnimation);
} else {
if (currPos == 0)
createIconDownAnimation(infoTabDy[currDy]);
else
createIconDownAnimation(dy[currDy]);
temp.startAnimation(iconDownAnimation);
}
currDy++;
delay -= 50;
temp.setVisibility(visibility);
circledImageViews.remove(0);
}
}
}
/**
* Creates animation for the gallery and homePage Icons with up direction.
*/
public void createIconUpAnimation(float dy, int delay) {
iconUpAnimation = new TranslateAnimation(0, 0, 0, (-(scale * 67.3f) + 0.5f - (dy * scale)) * iconDirection);
iconUpAnimation.setDuration(250);
iconUpAnimation.setFillAfter(false);
iconUpAnimation.setStartOffset(delay);
iconUpAnimation.setAnimationListener(iconUpAnimationListener);
}
/**
* Creates animation for the gallery and homePage Icons with down direction.
*/
public void createIconDownAnimation(float dy) {
iconDownAnimation = new TranslateAnimation(0, 0, 0, ((scale * 67.3f) + 0.5f + (dy * scale)) * iconDirection);
iconDownAnimation.setDuration(250);
iconDownAnimation.setFillAfter(false);
iconDownAnimation.setAnimationListener(iconDownAnimationListener);
}
/**
* Listener which updates the icons position after the animation ended.
*/
private class IconUpAnimationListener implements Animation.AnimationListener {
@Override
public void onAnimationEnd(Animation animation) {
if (currPos != 0) {
updateIconUpPos();
homeIcon.clearAnimation();
galleryIcon.clearAnimation();
} else {
updateIconUpPosInInfoTab();
tvDetailsInfo.getHomeIcon().clearAnimation();
tvDetailsInfo.getGalleryIcon().clearAnimation();
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationStart(Animation animation) {
}
}
/**
* Listener which updates the icons position after the animation ended.
*/
private class IconDownAnimationListener implements Animation.AnimationListener {
@Override
public void onAnimationEnd(Animation animation) {
if (currPos != 0) {
updateIconDownPos();
homeIcon.clearAnimation();
galleryIcon.clearAnimation();
} else {
updateIconDownPosInInfoTab();
tvDetailsInfo.getHomeIcon().clearAnimation();
tvDetailsInfo.getGalleryIcon().clearAnimation();
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationStart(Animation animation) {
}
}
/**
* Updates the icons position when called.
*/
public void updateIconDownPos() {
RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams(homeIcon.getWidth(), homeIcon.getHeight());
RelativeLayout.LayoutParams lp3 = new RelativeLayout.LayoutParams(galleryIcon.getWidth(), galleryIcon.getHeight());
lp1.addRule(RelativeLayout.ALIGN_PARENT_END);
lp3.addRule(RelativeLayout.ALIGN_PARENT_END);
lp1.setMargins(0, (int) (scale * (506 + iconMarginConstant - iconMarginLandscape + iconConstantSpecialCase) + 0.5f), (int) (scale * 23 + 0.5f), 0);
homeIcon.setLayoutParams(lp1);
lp3.setMargins(0, (int) (scale * (506 + iconMarginConstant - iconMarginLandscape + iconConstantSpecialCase) + 0.5f), (int) (scale * 23 + 0.5f), 0);
galleryIcon.setLayoutParams(lp3);
}
/**
* Updates the icons position when called.
*/
public void updateIconUpPos() {
RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams(homeIcon.getWidth(), homeIcon.getHeight());
RelativeLayout.LayoutParams lp3 = new RelativeLayout.LayoutParams(galleryIcon.getWidth(), galleryIcon.getHeight());
lp1.addRule(RelativeLayout.ALIGN_PARENT_END);
lp3.addRule(RelativeLayout.ALIGN_PARENT_END);
lp1.setMargins(0, (int) (scale * (439 + iconMarginConstant - iconMarginLandscape + iconConstantSpecialCase) + 0.5f), (int) (scale * 23 + 0.5f), 0);
homeIcon.setLayoutParams(lp1);
lp3.setMargins(0, (int) (scale * (383.3 + iconMarginConstant - iconMarginLandscape + iconConstantSpecialCase) + 0.5f), (int) (scale * 23 + 0.5f), 0);
galleryIcon.setLayoutParams(lp3);
}
/**
* Updates the icons position in the movie info tap when called.
*/
public void updateIconDownPosInInfoTab() {
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) tvDetailsInfo.getGalleryIcon().getLayoutParams();
p.removeRule(RelativeLayout.ABOVE);
p.removeRule(RelativeLayout.BELOW);
p.addRule(RelativeLayout.ABOVE, R.id.moreIcon);
p.setMargins(0, 0, (int) (23 * scale), (int) (-20 * scale));
tvDetailsInfo.getGalleryIcon().setLayoutParams(p);
tvDetailsInfo.getHomeIcon().setLayoutParams(p);
}
/**
* Updates the icons position in the movie info tap when called.
*/
public void updateIconUpPosInInfoTab() {
RelativeLayout.LayoutParams p3 = new RelativeLayout.LayoutParams(homeIcon.getWidth(), homeIcon.getHeight());
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(galleryIcon.getWidth(), galleryIcon.getHeight());
p3.addRule(RelativeLayout.ALIGN_PARENT_END);
p.addRule(RelativeLayout.ALIGN_PARENT_END);
if (iconDirection == 1) {
p3.addRule(RelativeLayout.ABOVE, R.id.moreIcon);
p3.setMargins(0, 0, (int) (23 * scale), (int) (44 * scale));
p.addRule(RelativeLayout.ABOVE, R.id.homeIcon);
p.setMargins(0, 0, (int) (23 * scale), (int) (15.5f * scale));
} else {
p3.addRule(RelativeLayout.BELOW, R.id.moreIcon);
p3.setMargins(0, (int) (16 * scale), (int) (23 * scale), 0);
p.addRule(RelativeLayout.BELOW, R.id.homeIcon);
p.setMargins(0, (int) (15.5f * scale), (int) (23 * scale), 0);
}
tvDetailsInfo.getHomeIcon().setLayoutParams(p3);
tvDetailsInfo.getGalleryIcon().setLayoutParams(p);
}
@Override
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
float scroll = scrollY;
if (mViewPager.getCurrentItem() == 0) {
scroll = (scroll / scrollSpeed);
if (scrollY / scale >= 0 && onMoreIconClick.getKey())
onMoreIconClick.onClick(null);
}
if (dragging) {
View toolbarView = getActivity().findViewById(R.id.toolbar);
if (scroll > oldScrollY) {
if (upDyKey) {
upDy = scroll;
upDyKey = false;
} else {
dy = upDy - scroll;
if (dy >= -toolbarView.getHeight()) {
toolbarView.setTranslationY(dy);
mSlidingTabLayout.setTranslationY(dy);
} else {
toolbarView.setTranslationY(-toolbarView.getHeight());
mSlidingTabLayout.setTranslationY(-toolbarView.getHeight());
}
downDyKey = true;
}
}
if (scroll < oldScrollY) {
if (downDyKey) {
downDy = scroll;
downDyTrans = toolbarView.getTranslationY();
downDyKey = false;
} else {
dy = (downDyTrans + (downDy - scroll));
if (dy <= 0) {
toolbarView.setTranslationY(dy);
mSlidingTabLayout.setTranslationY(dy);
} else {
toolbarView.setTranslationY(0);
mSlidingTabLayout.setTranslationY(0);
}
upDyKey = true;
}
}
}
oldScrollY = scroll;
}
@Override
public void onDownMotionEvent() {
}
@Override
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
adjustToolbar(scrollState);
}
private Scrollable getCurrentScrollable() {
Fragment fragment = getCurrentFragment();
if (fragment == null) {
return null;
}
View view = fragment.getView();
if (view == null) {
return null;
}
switch (mViewPager.getCurrentItem()) {
case 0:
return (Scrollable) view.findViewById(R.id.tvdetailsinfo);
case 1:
return (Scrollable) view.findViewById(R.id.castList);
case 2:
return (Scrollable) view.findViewById(R.id.tvdetailsoverview);
default:
return (Scrollable) view.findViewById(R.id.tvdetailsinfo);
}
}
/**
* Fixes the position of the toolbar
*
* @param scrollState
*/
private void adjustToolbar(ScrollState scrollState) {
View toolbarView = getActivity().findViewById(R.id.toolbar);
int toolbarHeight = toolbarView.getHeight();
final Scrollable scrollable = getCurrentScrollable();
if (scrollable == null) {
return;
}
int scrollY = scrollable.getCurrentScrollY();
if (scrollState == ScrollState.DOWN) {
showToolbar();
} else if (scrollState == ScrollState.UP) {
switch (currPos) {
case 0:
if (119 * scale <= scrollY) {
hideToolbar();
} else {
showToolbar();
}
break;
case 1:
if (toolbarHeight <= scrollY - hideThreshold) {
hideToolbar();
} else {
showToolbar();
}
break;
case 2:
if (toolbarHeight <= scrollY) {
hideToolbar();
} else {
showToolbar();
}
break;
}
}
}
/**
* Returns the current active fragment for the given position
*/
private Fragment getCurrentFragment() {
return tvDetailsSlideAdapter.getRegisteredFragment(mViewPager.getCurrentItem());
}
private void showToolbar() {
animateToolbar(0);
}
private void hideToolbar() {
View toolbarView = getActivity().findViewById(R.id.toolbar);
animateToolbar(-toolbarView.getHeight());
}
/**
* Animates our toolbar to the given direction
*
* @param toY our translation length.
*/
private void animateToolbar(final float toY) {
if (activity != null) {
View toolbarView = activity.findViewById(R.id.toolbar);
if (toolbarView != null) {
toolbarView.animate().translationY(toY).setInterpolator(new DecelerateInterpolator(2)).setDuration(200).start();
mSlidingTabLayout.animate().translationY(toY).setInterpolator(new DecelerateInterpolator(2)).setDuration(200).start();
if (toY == 0) {
upDyKey = true;
downDyKey = false;
downDy = 9999999;
} else {
downDyKey = true;
upDyKey = false;
upDy = -9999999;
}
}
}
}
/**
* Instant shows our toolbar. Used when click on movie details from movies list and toolbar is hidden.
*/
public void showInstantToolbar() {
if (activity != null) {
View toolbarView = activity.findViewById(R.id.toolbar);
if (toolbarView != null) {
toolbarView.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).setDuration(0).start();
mSlidingTabLayout.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).setDuration(0).start();
upDyKey = true;
downDyKey = false;
downDy = 9999999;
}
}
}
/**
* Fired when fragment is destroyed.
*/
public void onDestroyView() {
super.onDestroyView();
onPageChangeSelected = null;
onGalleryIconClick = null;
onMoreIconClick = null;
onHomeIconClick = null;
onPageChangeSelected = null;
downAnimationListener = null;
upAnimationListener = null;
iconUpAnimationListener = null;
iconDownAnimationListener = null;
}
}