Add new activity to show all cast for movies and tv shows

This commit is contained in:
Synced Synapse 2015-07-28 19:27:17 +01:00
parent 47f4875762
commit cbed4d919a
11 changed files with 501 additions and 70 deletions

View File

@ -50,6 +50,7 @@
<activity android:name="org.xbmc.kore.ui.AddonsActivity"/>
<activity android:name="org.xbmc.kore.ui.SettingsActivity"/>
<activity android:name="org.xbmc.kore.ui.FileActivity"/>
<activity android:name="org.xbmc.kore.ui.AllCastActivity"/>
<!-- Providers -->
<provider

View File

@ -0,0 +1,285 @@
/*
* Copyright 2015 Synced Synapse. All rights reserved.
*
* 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 org.xbmc.kore.ui;
import android.app.LoaderManager;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import org.xbmc.kore.R;
import org.xbmc.kore.host.HostManager;
import org.xbmc.kore.provider.MediaContract;
import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.UIUtils;
import org.xbmc.kore.utils.Utils;
import butterknife.ButterKnife;
import butterknife.InjectView;
/**
* Activity that presents all cast of a movie or TV Show
*/
public class AllCastActivity extends BaseActivity
implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = LogUtils.makeLogTag(AllCastActivity.class);
// Extras to be passed to this activity: type (0 - movie, 1 -tv_show) and the corresponding id
public static final String EXTRA_CAST_TYPE = "EXTRA_CAST_TYPE";
public static final String EXTRA_ID = "EXTRA_ID";
public static final String EXTRA_TITLE = "EXTRA_TITLE";
public static final int EXTRA_TYPE_MOVIE = 0;
public static final int EXTRA_TYPE_TVSHOW = 1;
// Loader IDs
private static final int LOADER_CAST = 0;
// Passed arguments
private int cast_type;
private int movie_tvshow_id = -1;
private String movie_tvshow_title;
private CursorAdapter adapter;
NavigationDrawerFragment navigationDrawerFragment;
@InjectView(R.id.cast_list) GridView castGridView;
@InjectView(android.R.id.empty) TextView emptyView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_all_cast);
ButterKnife.inject(this);
// Set up the drawer.
navigationDrawerFragment = (NavigationDrawerFragment)getSupportFragmentManager()
.findFragmentById(R.id.navigation_drawer);
navigationDrawerFragment.setUp(R.id.navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout));
if (savedInstanceState == null) {
cast_type = getIntent().getIntExtra(EXTRA_CAST_TYPE, EXTRA_TYPE_MOVIE);
movie_tvshow_id = getIntent().getIntExtra(EXTRA_ID, -1);
movie_tvshow_title = getIntent().getStringExtra(EXTRA_TITLE);
} else {
cast_type = savedInstanceState.getInt(EXTRA_CAST_TYPE);
movie_tvshow_id = savedInstanceState.getInt(EXTRA_ID);
movie_tvshow_title = savedInstanceState.getString(EXTRA_TITLE);
}
LogUtils.LOGD(TAG, "Showing cast for: " + movie_tvshow_title);
// Configure the adapter and start the loader
castGridView.setEmptyView(emptyView);
castGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Get the name from the tag
Utils.openImdbForPerson(AllCastActivity.this, (String) ((ViewHolder)view.getTag()).castName);
}
});
adapter = new CastAdapter(this, cast_type);
castGridView.setAdapter(adapter);
getLoaderManager().initLoader(LOADER_CAST, null, this);
setupActionBar(movie_tvshow_title);
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
protected void onSaveInstanceState (Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(EXTRA_CAST_TYPE, cast_type);
outState.putInt(EXTRA_ID, movie_tvshow_id);
outState.putString(EXTRA_TITLE, movie_tvshow_title);
}
private void setupActionBar(String title) {
Toolbar toolbar = (Toolbar)findViewById(R.id.default_toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar == null) return;
actionBar.setDisplayHomeAsUpEnabled(true);
navigationDrawerFragment.setDrawerIndicatorEnabled(true);
actionBar.setTitle(getResources().getString(R.string.cast) + " - " + title);
}
/**
* Loader callbacks
*/
/** {@inheritDoc} */
@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
Uri uri;
int hostId = HostManager.getInstance(this).getHostInfo().getId();
switch (cast_type) {
case EXTRA_TYPE_MOVIE:
uri = MediaContract.MovieCast.buildMovieCastListUri(hostId, movie_tvshow_id);
return new CursorLoader(this, uri,
MovieDetailsFragment.MovieCastListQuery.PROJECTION,
null, null,
MovieDetailsFragment.MovieCastListQuery.SORT);
case EXTRA_TYPE_TVSHOW:
uri = MediaContract.TVShowCast.buildTVShowCastListUri(hostId, movie_tvshow_id);
return new CursorLoader(this, uri,
TVShowOverviewFragment.TVShowCastListQuery.PROJECTION,
null, null,
TVShowOverviewFragment.TVShowCastListQuery.SORT);
default:
return null;
}
}
/** {@inheritDoc} */
@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
LogUtils.LOGD(TAG, "cursor count: " + cursor.getCount());
adapter.swapCursor(cursor);
// To prevent the empty text from appearing on the first load, set it now
emptyView.setText(getString(R.string.no_cast_info));
}
/** {@inheritDoc} */
@Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
// Release loader's data
adapter.swapCursor(null);
}
private static class CastAdapter extends CursorAdapter {
Context context;
private HostManager hostManager;
private int artWidth = -1, artHeight = -1;
private int name_idx;
private int role_idx = 3;
private int thumbnail_idx = 4;
public CastAdapter(Context context, int castType) {
super(context, null, false);
this.context = context;
this.hostManager = HostManager.getInstance(context);
// Get the art dimensions
// Resources resources = context.getResources();
// artWidth = (int)(resources.getDimension(R.dimen.movielist_art_width) /
// UIUtils.IMAGE_RESIZE_FACTOR);
// artHeight = (int)(resources.getDimension(R.dimen.movielist_art_heigth) /
// UIUtils.IMAGE_RESIZE_FACTOR);
name_idx = (castType == EXTRA_TYPE_MOVIE) ?
MovieDetailsFragment.MovieCastListQuery.NAME :
TVShowOverviewFragment.TVShowCastListQuery.NAME;
role_idx = (castType == EXTRA_TYPE_MOVIE) ?
MovieDetailsFragment.MovieCastListQuery.ROLE :
TVShowOverviewFragment.TVShowCastListQuery.ROLE;
thumbnail_idx = (castType == EXTRA_TYPE_MOVIE) ?
MovieDetailsFragment.MovieCastListQuery.THUMBNAIL :
TVShowOverviewFragment.TVShowCastListQuery.THUMBNAIL;
}
/** {@inheritDoc} */
@Override
public View newView(Context context, final Cursor cursor, ViewGroup parent) {
final View view = LayoutInflater.from(context)
.inflate(R.layout.grid_item_cast, parent, false);
if (artWidth == -1) {
Resources resources = context.getResources();
int imageMarginPx = resources.getDimensionPixelSize(R.dimen.default_padding);
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
int numColumns = resources.getInteger(R.integer.cast_grid_view_columns);
artWidth = (displayMetrics.widthPixels - (2 + numColumns - 1) * imageMarginPx) / numColumns;
artHeight = (int) (artWidth * 1.5);
LogUtils.LOGD(TAG, "width: " + artWidth);
}
// Setup View holder pattern
ViewHolder viewHolder = new ViewHolder();
viewHolder.roleView = (TextView)view.findViewById(R.id.role);
viewHolder.nameView = (TextView)view.findViewById(R.id.name);
viewHolder.pictureView = (ImageView)view.findViewById(R.id.picture);
view.setTag(viewHolder);
view.getLayoutParams().width = artWidth;
view.getLayoutParams().height = artHeight;
return view;
}
/** {@inheritDoc} */
@Override
public void bindView(View view, Context context, Cursor cursor) {
final ViewHolder viewHolder = (ViewHolder)view.getTag();
String name = cursor.getString(name_idx);
viewHolder.roleView.setText(cursor.getString(role_idx));
viewHolder.nameView.setText(name);
UIUtils.loadImageWithCharacterAvatar(context, hostManager,
cursor.getString(thumbnail_idx), name,
viewHolder.pictureView, artWidth, artHeight);
viewHolder.castName = name;
}
}
/**
* View holder pattern
*/
private static class ViewHolder {
TextView roleView;
TextView nameView;
ImageView pictureView;
String castName;
}
}

View File

@ -37,6 +37,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.GridLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
@ -99,6 +100,7 @@ public class MovieDetailsFragment extends Fragment
// Displayed movie id
private int movieId = -1;
private String movieTitle;
// Info for downloading the movie
private FileDownloadHelper.MovieInfo movieDownloadInfo = null;
@ -134,8 +136,7 @@ public class MovieDetailsFragment extends Fragment
@InjectView(R.id.media_description) TextView mediaDescription;
@InjectView(R.id.directors) TextView mediaDirectors;
@InjectView(R.id.cast_list) GridLayout videoCastList;
@InjectView(R.id.additional_cast_list) TextView videoAdditionalCastList;
@InjectView(R.id.additional_cast_title) TextView videoAdditionalCastTitle;
@InjectView(R.id.see_all_cast) Button seeAllCast;
/**
* Create a new instance of this, initialized to show the movie movieId
@ -287,6 +288,19 @@ public class MovieDetailsFragment extends Fragment
}
}
/**
* Callbacks for injected buttons
*/
@OnClick(R.id.see_all_cast)
public void onSeeAllCastClicked(View v) {
Intent launchIntent = new Intent(getActivity(), AllCastActivity.class)
.putExtra(AllCastActivity.EXTRA_CAST_TYPE, AllCastActivity.EXTRA_TYPE_MOVIE)
.putExtra(AllCastActivity.EXTRA_ID, movieId)
.putExtra(AllCastActivity.EXTRA_TITLE, movieTitle);
startActivity(launchIntent);
getActivity().overridePendingTransition(R.anim.activity_in, R.anim.activity_out);
}
/**
* Loader callbacks
*/
@ -519,7 +533,7 @@ public class MovieDetailsFragment extends Fragment
private void displayMovieDetails(Cursor cursor) {
LogUtils.LOGD(TAG, "Refreshing movie details");
cursor.moveToFirst();
String movieTitle = cursor.getString(MovieDetailsQuery.TITLE);
movieTitle = cursor.getString(MovieDetailsQuery.TITLE);
mediaTitle.setText(movieTitle);
mediaUndertitle.setText(cursor.getString(MovieDetailsQuery.TAGLINE));
@ -620,8 +634,10 @@ public class MovieDetailsFragment extends Fragment
cursor.getString(MovieCastListQuery.THUMBNAIL)));
} while (cursor.moveToNext());
UIUtils.setupCastInfo(getActivity(), castList, videoCastList,
videoAdditionalCastTitle, videoAdditionalCastList);
UIUtils.setupCastInfo(getActivity(), castList, videoCastList);
seeAllCast.setVisibility(
(cursor.getCount() <= Settings.DEFAULT_MAX_CAST_PICTURES) ?
View.GONE : View.VISIBLE);
}
}
@ -690,7 +706,7 @@ public class MovieDetailsFragment extends Fragment
/**
* Movie cast list query parameters.
*/
private interface MovieCastListQuery {
public interface MovieCastListQuery {
String[] PROJECTION = {
BaseColumns._ID,
MediaContract.MovieCast.NAME,

View File

@ -26,11 +26,13 @@ import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.AppCompatButton;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.ScrollView;
@ -55,6 +57,7 @@ import java.util.List;
import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;
import de.greenrobot.event.EventBus;
/**
@ -77,6 +80,7 @@ public class TVShowOverviewFragment extends Fragment
// Displayed movie id
private int tvshowId = -1;
private String tvshowTitle;
// Controls whether a automatic sync refresh has been issued for this show
private static boolean hasIssuedOutdatedRefresh = false;
@ -102,8 +106,7 @@ public class TVShowOverviewFragment extends Fragment
@InjectView(R.id.media_description) TextView mediaDescription;
@InjectView(R.id.cast_list) GridLayout videoCastList;
@InjectView(R.id.additional_cast_list) TextView videoAdditionalCastList;
@InjectView(R.id.additional_cast_title) TextView videoAdditionalCastTitle;
@InjectView(R.id.see_all_cast) Button seeAllCast;
/**
* Create a new instance of this, initialized to show tvshowId
@ -250,6 +253,19 @@ public class TVShowOverviewFragment extends Fragment
}
}
/**
* Callbacks for injected buttons
*/
@OnClick(R.id.see_all_cast)
public void onSeeAllCastClicked(View v) {
Intent launchIntent = new Intent(getActivity(), AllCastActivity.class)
.putExtra(AllCastActivity.EXTRA_CAST_TYPE, AllCastActivity.EXTRA_TYPE_TVSHOW)
.putExtra(AllCastActivity.EXTRA_ID, tvshowId)
.putExtra(AllCastActivity.EXTRA_TITLE, tvshowTitle);
startActivity(launchIntent);
getActivity().overridePendingTransition(R.anim.activity_in, R.anim.activity_out);
}
/**
* Loader callbacks
*/
@ -312,7 +328,7 @@ public class TVShowOverviewFragment extends Fragment
*/
private void displayTVShowDetails(Cursor cursor) {
cursor.moveToFirst();
String tvshowTitle = cursor.getString(TVShowDetailsQuery.TITLE);
tvshowTitle = cursor.getString(TVShowDetailsQuery.TITLE);
mediaTitle.setText(tvshowTitle);
int numEpisodes = cursor.getInt(TVShowDetailsQuery.EPISODE),
watchedEpisodes = cursor.getInt(TVShowDetailsQuery.WATCHEDEPISODES);
@ -375,8 +391,10 @@ public class TVShowOverviewFragment extends Fragment
cursor.getString(TVShowCastListQuery.THUMBNAIL)));
} while (cursor.moveToNext());
UIUtils.setupCastInfo(getActivity(), castList, videoCastList,
videoAdditionalCastTitle, videoAdditionalCastList);
UIUtils.setupCastInfo(getActivity(), castList, videoCastList);
seeAllCast.setVisibility(
(cursor.getCount() <= Settings.DEFAULT_MAX_CAST_PICTURES) ?
View.GONE : View.VISIBLE);
}
}
@ -441,7 +459,7 @@ public class TVShowOverviewFragment extends Fragment
/**
* Movie cast list query parameters.
*/
private interface TVShowCastListQuery {
public interface TVShowCastListQuery {
String[] PROJECTION = {
BaseColumns._ID,
MediaContract.TVShowCast.NAME,

View File

@ -252,7 +252,7 @@ public class UIUtils {
int layoutMarginPx = 2 * resources.getDimensionPixelSize(R.dimen.remote_content_hmargin);
int imageMarginPx = 2 * resources.getDimensionPixelSize(R.dimen.image_grid_margin);
int imageWidth = (displayMetrics.widthPixels - layoutMarginPx - numColumns * imageMarginPx) / numColumns;
int imageHeight = (int)(imageWidth * 1.2);
int imageHeight = (int)(imageWidth * 1.5);
List<VideoType.Cast> noPicturesCastList = new ArrayList<VideoType.Cast>();
int maxCastPictures = Settings.DEFAULT_MAX_CAST_PICTURES;
@ -260,8 +260,7 @@ public class UIUtils {
for (int i = 0; i < castList.size(); i++) {
VideoType.Cast actor = castList.get(i);
if (((maxCastPictures == -1) || (currentPictureNumber < maxCastPictures)) &&
(actor.thumbnail != null)) {
if ((currentPictureNumber < maxCastPictures) && (actor.thumbnail != null)) {
// Present the picture
currentPictureNumber++;
View castView = LayoutInflater.from(context).inflate(R.layout.grid_item_cast, castListView, false);
@ -270,7 +269,7 @@ public class UIUtils {
TextView castRole = (TextView) castView.findViewById(R.id.role);
castView.getLayoutParams().width = imageWidth;
castView.getLayoutParams().height = (int) (imageHeight * 1.2);
castView.getLayoutParams().height = imageHeight;
castView.setTag(actor.name);
castView.setOnClickListener(castListClickListener);
@ -308,6 +307,68 @@ public class UIUtils {
}
}
/**
* Fills the standard cast info list, consisting of a {@link android.widget.GridLayout}
* with actor images and a Textview with the name and the role of the additional cast.
* The number of actor presented on the {@link android.widget.GridLayout} is controlled
* through the global setting, and only actors with images are presented.
* The rest are presented in the additionalCastView TextView
*
* @param context Activity
* @param castList Cast list
* @param castListView GridLayout on which too show actors that have images
*/
public static void setupCastInfo(final Context context,
List<VideoType.Cast> castList, GridLayout castListView) {
HostManager hostManager = HostManager.getInstance(context);
Resources resources = context.getResources();
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
View.OnClickListener castListClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Utils.openImdbForPerson(context, (String)v.getTag());
}
};
castListView.removeAllViews();
int numColumns = castListView.getColumnCount();
int layoutMarginPx = 2 * resources.getDimensionPixelSize(R.dimen.remote_content_hmargin);
int imageMarginPx = 2 * resources.getDimensionPixelSize(R.dimen.image_grid_margin);
int imageWidth = (displayMetrics.widthPixels - layoutMarginPx - numColumns * imageMarginPx) / numColumns;
int imageHeight = (int)(imageWidth * 1.5);
int maxCastPictures = Settings.DEFAULT_MAX_CAST_PICTURES;
int currentPictureNumber = 0;
for (int i = 0; i < castList.size(); i++) {
VideoType.Cast actor = castList.get(i);
if ((currentPictureNumber < maxCastPictures) && (actor.thumbnail != null)) {
// Present the picture
currentPictureNumber++;
View castView = LayoutInflater.from(context).inflate(R.layout.grid_item_cast, castListView, false);
ImageView castPicture = (ImageView) castView.findViewById(R.id.picture);
TextView castName = (TextView) castView.findViewById(R.id.name);
TextView castRole = (TextView) castView.findViewById(R.id.role);
castView.getLayoutParams().width = imageWidth;
castView.getLayoutParams().height = imageHeight;
castView.setTag(actor.name);
castView.setOnClickListener(castListClickListener);
castName.setText(actor.name);
castRole.setText(actor.role);
UIUtils.loadImageWithCharacterAvatar(context, hostManager,
actor.thumbnail, actor.name,
castPicture, imageWidth, imageHeight);
castListView.addView(castView);
}
}
}
/**
* Simple wrapper to {@link NetUtils#sendWolMagicPacket(String, String, int)}
* that sends a WoL magic packet in a new thread

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 Synced Synapse. All rights reserved.
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.
-->
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar_default" />
<include layout="@layout/empty_view"/>
<GridView
android:id="@+id/cast_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/default_padding"
android:stretchMode="columnWidth"
android:numColumns="@integer/cast_grid_view_columns"
android:horizontalSpacing="@dimen/default_padding"
android:verticalSpacing="@dimen/default_padding"
android:fastScrollEnabled="false"
android:choiceMode="none"
android:listSelector="?attr/selectableItemBackground"
android:drawSelectorOnTop="true"
/>
</LinearLayout>
<fragment android:id="@+id/navigation_drawer"
android:layout_width="@dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:name="org.xbmc.kore.ui.NavigationDrawerFragment"/>
</android.support.v4.widget.DrawerLayout>

View File

@ -49,6 +49,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/remote_content_hmargin"
android:layout_marginRight="@dimen/remote_content_hmargin"
android:paddingBottom="@dimen/default_padding"
android:transitionGroup="true">
<TextView
@ -246,27 +247,16 @@
android:columnCount="@integer/cast_grid_view_columns"
android:orientation="horizontal"/>
<TextView
android:id="@+id/additional_cast_title"
android:layout_width="match_parent"
<Button
android:id="@+id/see_all_cast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/cast_list"
style="@style/TextAppearance.Media.Title"
android:layout_marginTop="@dimen/default_padding"
android:paddingLeft="@dimen/default_padding"
android:paddingRight="@dimen/default_padding"
android:text="@string/additional_cast"/>
<TextView
android:id="@+id/additional_cast_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/additional_cast_title"
style="@style/TextAppearance.Media.Info"
android:textColor="?attr/appTextColorSecondary"
android:layout_marginBottom="@dimen/default_padding"
android:paddingLeft="@dimen/default_padding"
android:paddingRight="@dimen/default_padding"/>
android:layout_alignRight="@id/cast_list"
android:layout_alignEnd="@id/cast_list"
android:layout_marginRight="@dimen/small_padding"
android:layout_marginEnd="@dimen/small_padding"
android:text="@string/see_all_cast"/>
</RelativeLayout>
</com.melnykov.fab.ObservableScrollView>

View File

@ -47,6 +47,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/remote_content_hmargin"
android:layout_marginRight="@dimen/remote_content_hmargin"
android:paddingBottom="@dimen/default_padding"
android:transitionGroup="true">
<TextView
android:id="@+id/media_title"
@ -179,27 +180,16 @@
android:columnCount="@integer/cast_grid_view_columns"
android:orientation="horizontal"/>
<TextView
android:id="@+id/additional_cast_title"
android:layout_width="match_parent"
<Button
android:id="@+id/see_all_cast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/cast_list"
style="@style/TextAppearance.Media.Title"
android:layout_marginTop="@dimen/default_padding"
android:paddingLeft="@dimen/default_padding"
android:paddingRight="@dimen/default_padding"
android:text="@string/additional_cast"/>
<TextView
android:id="@+id/additional_cast_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/additional_cast_title"
style="@style/TextAppearance.Media.Info"
android:textColor="?attr/appTextColorSecondary"
android:layout_marginBottom="@dimen/default_padding"
android:paddingLeft="@dimen/default_padding"
android:paddingRight="@dimen/default_padding"/>
android:layout_alignRight="@id/cast_list"
android:layout_alignEnd="@id/cast_list"
android:layout_marginRight="@dimen/small_padding"
android:layout_marginEnd="@dimen/small_padding"
android:text="@string/see_all_cast"/>
</RelativeLayout>
</ScrollView>

View File

@ -16,15 +16,16 @@
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:layout_margin="@dimen/image_grid_margin">
<ImageView
android:id="@+id/picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"/>
<!--android:src="?attr/iconPerson"/>-->
@ -35,23 +36,34 @@
<!--android:layout_height="match_parent"-->
<!--android:src="?attr/imageViewShade"/>-->
<TextView
android:id="@+id/role"
<!--
Somehow i can't make the TextViews work correctly, one below the other when this RelativeLayout is inside a
Gridview, so i resort to a LinearLayout to position them
-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
style="@style/TextAppearance.Media.Cast"
android:textColor="?attr/appTextColorSecondary"
android:background="?attr/contentBackgroundColor"/>
android:background="?attr/contentBackgroundColor">
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.Media.Cast"/>
<TextView
android:id="@+id/role"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.Media.Cast"
android:textColor="?attr/appTextColorSecondary"/>
</LinearLayout>
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/role"
android:layout_above="@id/role"
style="@style/TextAppearance.Media.Cast"
android:background="?attr/contentBackgroundColor"/>
</RelativeLayout>

View File

@ -216,6 +216,7 @@
<string name="cast">Cast</string>
<string name="additional_cast">Additional cast</string>
<string name="cast_list_text">%1$s as %2$s</string>
<string name="see_all_cast">See all</string>
<string name="general_error_executing_action">Error executing action: %1$s</string>
<string name="error_getting_playlist">Error fetching playlist</string>
@ -233,6 +234,7 @@
<string name="no_addons_found_refresh">No addons found or not connected\n\nSwipe down to refresh</string>
<string name="no_music_videos_found_refresh">No videos found\n\nSwipe down to refresh</string>
<string name="pull_to_refresh">Pull to refresh</string>
<string name="no_cast_info">No cast info to display</string>
<string name="minutes_abbrev">%1$s min</string>
<string name="sync_successful">Sync successful</string>

View File

@ -43,6 +43,8 @@
<!--<item name="colorControlHighlight">@color/color_accent</item>-->
<!--<item name="colorControlActivated">@color/color_accent</item>-->
<item name="colorButtonNormal">?attr/colorPrimary</item>
<item name="appTextColorPrimary">@color/white</item>
<item name="appTextColorSecondary">@color/white_dim_50pct</item>