Add support to see all cast on now playing screen
This commit is contained in:
parent
d48b95d86e
commit
a07a819898
|
@ -15,6 +15,9 @@
|
|||
*/
|
||||
package org.xbmc.kore.jsonrpc.type;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import org.xbmc.kore.utils.JsonUtils;
|
||||
|
@ -29,7 +32,7 @@ import java.util.List;
|
|||
public class VideoType {
|
||||
private static final String TAG = LogUtils.makeLogTag(VideoType.class);
|
||||
|
||||
public static class Cast {
|
||||
public static class Cast implements Parcelable {
|
||||
public static final String NAME = "name";
|
||||
public static final String ORDER = "order";
|
||||
public static final String ROLE = "role";
|
||||
|
@ -72,6 +75,29 @@ public class VideoType {
|
|||
}
|
||||
return castList;
|
||||
}
|
||||
|
||||
// Parcelable interface implementation
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(name);
|
||||
out.writeInt(order);
|
||||
out.writeString(role);
|
||||
out.writeString(thumbnail);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<Cast> CREATOR
|
||||
= new Parcelable.Creator<Cast>() {
|
||||
public Cast createFromParcel(Parcel in) {
|
||||
return new Cast(in.readString(), in.readInt(), in.readString(), in.readString());
|
||||
}
|
||||
|
||||
public Cast[] newArray(int size) {
|
||||
return new Cast[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class Resume {
|
||||
|
|
|
@ -33,17 +33,21 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
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.jsonrpc.type.VideoType;
|
||||
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 java.util.ArrayList;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.InjectView;
|
||||
|
||||
|
@ -58,9 +62,11 @@ public class AllCastActivity extends BaseActivity
|
|||
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 String EXTRA_CAST_LIST = "EXTRA_CAST_LIST";
|
||||
|
||||
public static final int EXTRA_TYPE_MOVIE = 0;
|
||||
public static final int EXTRA_TYPE_TVSHOW = 1;
|
||||
public static final int EXTRA_TYPE_CAST_LIST = 2;
|
||||
|
||||
// Loader IDs
|
||||
private static final int LOADER_CAST = 0;
|
||||
|
@ -70,7 +76,9 @@ public class AllCastActivity extends BaseActivity
|
|||
private int movie_tvshow_id = -1;
|
||||
private String movie_tvshow_title;
|
||||
|
||||
private CursorAdapter adapter;
|
||||
private ArrayList<VideoType.Cast> castArrayList;
|
||||
|
||||
private CursorAdapter cursorAdapter;
|
||||
NavigationDrawerFragment navigationDrawerFragment;
|
||||
|
||||
@InjectView(R.id.cast_list) GridView castGridView;
|
||||
|
@ -99,7 +107,7 @@ public class AllCastActivity extends BaseActivity
|
|||
|
||||
LogUtils.LOGD(TAG, "Showing cast for: " + movie_tvshow_title);
|
||||
|
||||
// Configure the adapter and start the loader
|
||||
// Configure the grid
|
||||
castGridView.setEmptyView(emptyView);
|
||||
castGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
|
@ -109,10 +117,19 @@ public class AllCastActivity extends BaseActivity
|
|||
}
|
||||
});
|
||||
|
||||
adapter = new CastAdapter(this, cast_type);
|
||||
castGridView.setAdapter(adapter);
|
||||
|
||||
getLoaderManager().initLoader(LOADER_CAST, null, this);
|
||||
if (cast_type == EXTRA_TYPE_CAST_LIST) {
|
||||
if (savedInstanceState == null) {
|
||||
castArrayList = getIntent().getParcelableArrayListExtra(EXTRA_CAST_LIST);
|
||||
} else {
|
||||
castArrayList = savedInstanceState.getParcelableArrayList(EXTRA_CAST_LIST);
|
||||
}
|
||||
CastArrayAdapter arrayAdapter = new CastArrayAdapter(this, castArrayList);
|
||||
castGridView.setAdapter(arrayAdapter);
|
||||
} else {
|
||||
cursorAdapter = new CastCursorAdapter(this, cast_type);
|
||||
castGridView.setAdapter(cursorAdapter);
|
||||
getLoaderManager().initLoader(LOADER_CAST, null, this);
|
||||
}
|
||||
|
||||
setupActionBar(movie_tvshow_title);
|
||||
}
|
||||
|
@ -133,6 +150,8 @@ public class AllCastActivity extends BaseActivity
|
|||
outState.putInt(EXTRA_CAST_TYPE, cast_type);
|
||||
outState.putInt(EXTRA_ID, movie_tvshow_id);
|
||||
outState.putString(EXTRA_TITLE, movie_tvshow_title);
|
||||
if (cast_type == EXTRA_TYPE_CAST_LIST)
|
||||
outState.putParcelableArrayList(EXTRA_CAST_LIST, castArrayList);
|
||||
}
|
||||
|
||||
private void setupActionBar(String title) {
|
||||
|
@ -178,7 +197,7 @@ public class AllCastActivity extends BaseActivity
|
|||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
|
||||
LogUtils.LOGD(TAG, "cursor count: " + cursor.getCount());
|
||||
adapter.swapCursor(cursor);
|
||||
cursorAdapter.swapCursor(cursor);
|
||||
// To prevent the empty text from appearing on the first load, set it now
|
||||
emptyView.setText(getString(R.string.no_cast_info));
|
||||
}
|
||||
|
@ -187,10 +206,67 @@ public class AllCastActivity extends BaseActivity
|
|||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> cursorLoader) {
|
||||
// Release loader's data
|
||||
adapter.swapCursor(null);
|
||||
cursorAdapter.swapCursor(null);
|
||||
}
|
||||
|
||||
private static class CastAdapter extends CursorAdapter {
|
||||
public static class CastArrayAdapter extends ArrayAdapter<VideoType.Cast> {
|
||||
private HostManager hostManager;
|
||||
private int artWidth = -1, artHeight = -1;
|
||||
|
||||
public CastArrayAdapter(Context context, ArrayList<VideoType.Cast> castArrayList) {
|
||||
super(context, 0, castArrayList);
|
||||
this.hostManager = HostManager.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(getContext())
|
||||
.inflate(R.layout.grid_item_cast, parent, false);
|
||||
|
||||
if (artWidth == -1) {
|
||||
Resources resources = getContext().getResources();
|
||||
int imageMarginPx = resources.getDimensionPixelSize(R.dimen.small_padding);
|
||||
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
WindowManager windowManager = (WindowManager) getContext().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) convertView.findViewById(R.id.role);
|
||||
viewHolder.nameView = (TextView) convertView.findViewById(R.id.name);
|
||||
viewHolder.pictureView = (ImageView) convertView.findViewById(R.id.picture);
|
||||
|
||||
convertView.setTag(viewHolder);
|
||||
|
||||
convertView.getLayoutParams().width = artWidth;
|
||||
convertView.getLayoutParams().height = artHeight;
|
||||
}
|
||||
|
||||
final ViewHolder viewHolder = (ViewHolder)convertView.getTag();
|
||||
VideoType.Cast cast = getItem(position);
|
||||
|
||||
viewHolder.roleView.setText(cast.role);
|
||||
viewHolder.nameView.setText(cast.name);
|
||||
UIUtils.loadImageWithCharacterAvatar(getContext(), hostManager,
|
||||
cast.thumbnail, cast.name,
|
||||
viewHolder.pictureView, artWidth, artHeight);
|
||||
viewHolder.castName = cast.name;
|
||||
|
||||
return convertView;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static class CastCursorAdapter extends CursorAdapter {
|
||||
Context context;
|
||||
private HostManager hostManager;
|
||||
private int artWidth = -1, artHeight = -1;
|
||||
|
@ -199,7 +275,7 @@ public class AllCastActivity extends BaseActivity
|
|||
private int role_idx = 3;
|
||||
private int thumbnail_idx = 4;
|
||||
|
||||
public CastAdapter(Context context, int castType) {
|
||||
public CastCursorAdapter(Context context, int castType) {
|
||||
super(context, null, false);
|
||||
this.context = context;
|
||||
this.hostManager = HostManager.getInstance(context);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package org.xbmc.kore.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Bundle;
|
||||
|
@ -28,6 +29,7 @@ import android.view.MenuItem;
|
|||
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;
|
||||
|
@ -39,6 +41,7 @@ import android.widget.TextView;
|
|||
import android.widget.Toast;
|
||||
|
||||
import org.xbmc.kore.R;
|
||||
import org.xbmc.kore.Settings;
|
||||
import org.xbmc.kore.host.HostConnectionObserver;
|
||||
import org.xbmc.kore.host.HostInfo;
|
||||
import org.xbmc.kore.host.HostManager;
|
||||
|
@ -54,11 +57,13 @@ import org.xbmc.kore.jsonrpc.type.ApplicationType;
|
|||
import org.xbmc.kore.jsonrpc.type.GlobalType;
|
||||
import org.xbmc.kore.jsonrpc.type.ListType;
|
||||
import org.xbmc.kore.jsonrpc.type.PlayerType;
|
||||
import org.xbmc.kore.jsonrpc.type.VideoType;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
import org.xbmc.kore.utils.RepeatListener;
|
||||
import org.xbmc.kore.utils.UIUtils;
|
||||
import org.xbmc.kore.utils.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
|
@ -160,8 +165,7 @@ public class NowPlayingFragment 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;
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
|
@ -637,8 +641,8 @@ public class NowPlayingFragment extends Fragment
|
|||
* @param getItemResult Return from method {@link org.xbmc.kore.jsonrpc.method.Player.GetItem}
|
||||
*/
|
||||
private void setNowPlayingInfo(PlayerType.PropertyValue getPropertiesResult,
|
||||
ListType.ItemsAll getItemResult) {
|
||||
String title, underTitle, art, poster, genreSeason, year,
|
||||
final ListType.ItemsAll getItemResult) {
|
||||
final String title, underTitle, art, poster, genreSeason, year,
|
||||
descriptionPlot, votes, maxRating;
|
||||
double rating;
|
||||
|
||||
|
@ -839,8 +843,6 @@ public class NowPlayingFragment extends Fragment
|
|||
(getPropertiesResult.audiostreams.size() > 0)) {
|
||||
overflowButton.setVisibility(View.VISIBLE);
|
||||
videoCastList.setVisibility(View.VISIBLE);
|
||||
videoAdditionalCastTitle.setVisibility(View.VISIBLE);
|
||||
videoAdditionalCastList.setVisibility(View.VISIBLE);
|
||||
|
||||
// Save subtitles and audiostreams list
|
||||
availableAudioStreams = getPropertiesResult.audiostreams;
|
||||
|
@ -849,12 +851,28 @@ public class NowPlayingFragment extends Fragment
|
|||
currentSubtitleIndex = getPropertiesResult.currentsubtitle.index;
|
||||
|
||||
// Cast list
|
||||
UIUtils.setupCastInfo(getActivity(), getItemResult.cast, videoCastList, videoAdditionalCastTitle, videoAdditionalCastList);
|
||||
UIUtils.setupCastInfo(getActivity(), getItemResult.cast, videoCastList);
|
||||
|
||||
seeAllCast.setVisibility(
|
||||
(getItemResult.cast.size() <= Settings.DEFAULT_MAX_CAST_PICTURES) ?
|
||||
View.GONE : View.VISIBLE);
|
||||
seeAllCast.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent launchIntent = new Intent(getActivity(), AllCastActivity.class)
|
||||
.putExtra(AllCastActivity.EXTRA_CAST_TYPE, AllCastActivity.EXTRA_TYPE_CAST_LIST)
|
||||
.putExtra(AllCastActivity.EXTRA_ID, 0)
|
||||
.putExtra(AllCastActivity.EXTRA_TITLE, title)
|
||||
.putParcelableArrayListExtra(AllCastActivity.EXTRA_CAST_LIST,
|
||||
(ArrayList<VideoType.Cast>)getItemResult.cast);
|
||||
startActivity(launchIntent);
|
||||
getActivity().overridePendingTransition(R.anim.activity_in, R.anim.activity_out);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
overflowButton.setVisibility(View.GONE);
|
||||
videoCastList.setVisibility(View.GONE);
|
||||
videoAdditionalCastTitle.setVisibility(View.GONE);
|
||||
videoAdditionalCastList.setVisibility(View.GONE);
|
||||
seeAllCast.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -219,97 +219,6 @@ public class UIUtils {
|
|||
view.setImageResource((speed == 1) ? iconPauseResId: iconPlayResId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param additionalCastTitleView View with additional cast title
|
||||
* @param additionalCastView Additional cast
|
||||
*/
|
||||
public static void setupCastInfo(final Context context,
|
||||
List<VideoType.Cast> castList, GridLayout castListView,
|
||||
TextView additionalCastTitleView, TextView additionalCastView) {
|
||||
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);
|
||||
|
||||
List<VideoType.Cast> noPicturesCastList = new ArrayList<VideoType.Cast>();
|
||||
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);
|
||||
} else {
|
||||
noPicturesCastList.add(actor);
|
||||
}
|
||||
}
|
||||
|
||||
// Additional cast
|
||||
if (noPicturesCastList.size() > 0) {
|
||||
additionalCastTitleView.setVisibility(View.VISIBLE);
|
||||
additionalCastView.setVisibility(View.VISIBLE);
|
||||
StringBuilder castListText = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (VideoType.Cast cast : noPicturesCastList) {
|
||||
if (!first) castListText.append("\n");
|
||||
first = false;
|
||||
if (!TextUtils.isEmpty(cast.role)) {
|
||||
castListText.append(String.format(context.getString(R.string.cast_list_text),
|
||||
cast.name, cast.role));
|
||||
} else {
|
||||
castListText.append(cast.name);
|
||||
}
|
||||
}
|
||||
additionalCastView.setText(castListText);
|
||||
} else {
|
||||
additionalCastTitleView.setVisibility(View.GONE);
|
||||
additionalCastView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
|
|
@ -42,7 +42,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/remote_content_hmargin"
|
||||
android:layout_marginRight="@dimen/remote_content_hmargin">
|
||||
android:layout_marginRight="@dimen/remote_content_hmargin"
|
||||
android:paddingBottom="@dimen/default_padding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/media_title"
|
||||
|
@ -305,27 +306,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>
|
||||
|
|
Loading…
Reference in New Issue