Commit 7cbcfe7e authored by Geoffrey Métais's avatar Geoffrey Métais

data binding for video grid

parent 5dbe9435
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
card_view:cardUseCompatPadding="true"
card_view:cardPreventCornerOverlap="false"
card_view:cardElevation="1sp" >
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View"/>
<variable
name="media"
type="org.videolan.vlc.MediaWrapper"/>
<variable
name="time"
type="String"/>
<variable
name="max"
type="int"/>
<variable
name="progress"
type="int"/>
<variable
name="resolution"
type="String"/>
<variable
name="group"
type="boolean"/>
<variable
name="cover"
type="android.graphics.drawable.BitmapDrawable"/>
<variable
name="scaleType"
type="android.widget.ImageView.ScaleType"/>
<variable
name="handler"
type="org.videolan.vlc.gui.video.VideoListAdapter.ClickHandler"/>
</data>
<android.support.v7.widget.CardView
android:id="@+id/card_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
card_view:cardUseCompatPadding="true"
card_view:cardPreventCornerOverlap="false"
card_view:cardElevation="1sp" >
<RelativeLayout
android:id="@+id/layout_item"
android:layout_width="@dimen/grid_card_width"
android:layout_height="@dimen/grid_card_height"
android:gravity="center_vertical"
android:orientation="vertical"
android:background="?attr/background_default">
<RelativeLayout
android:id="@+id/layout_item"
android:layout_width="@dimen/grid_card_width"
android:layout_height="@dimen/grid_card_height"
android:gravity="center_vertical"
android:orientation="vertical"
android:background="?attr/background_default">
<ImageView
android:id="@+id/ml_item_thumbnail"
android:layout_width="@dimen/grid_card_thumb_width"
android:layout_height="@dimen/grid_card_thumb_height"
android:layout_alignParentTop="true"
android:background="?attr/background_default_darker"
android:scaleType="fitCenter" />
<ImageView
android:id="@+id/ml_item_thumbnail"
android:layout_width="@dimen/grid_card_thumb_width"
android:layout_height="@dimen/grid_card_thumb_height"
android:layout_alignParentTop="true"
android:background="?attr/background_default_darker"
android:src="@{cover}"
android:scaleType="@{scaleType}" />
<TextView
android:id="@+id/ml_item_title"
android:textSize="@dimen/grid_card_title_text_size"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/ml_item_thumbnail"
android:layout_above="@+id/ml_item_time"
android:layout_toLeftOf="@+id/item_more"
android:layout_marginTop="5dp"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:ellipsize="end"
android:maxLines="2" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/ml_item_title"
android:textSize="@dimen/grid_card_title_text_size"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_title"
android:layout_below="@id/ml_item_thumbnail"
android:layout_above="@+id/ml_item_time"
android:layout_toLeftOf="@+id/item_more"
android:layout_marginTop="5dp"
android:text="@{media.title}"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:ellipsize="end"
android:maxLines="2" />
<ImageView
android:id="@+id/item_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/ml_item_thumbnail"
android:layout_above="@+id/ml_item_resolution"
android:layout_marginTop="5dp"
android:scaleType="fitCenter"
android:contentDescription="@string/more_actions"
android:clickable="true"
android:src="@drawable/ic_more" />
<ImageView
android:id="@+id/item_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/ml_item_thumbnail"
android:layout_above="@+id/ml_item_resolution"
android:layout_marginTop="5dp"
android:scaleType="fitCenter"
android:contentDescription="@string/more_actions"
android:clickable="true"
android:onClick="@{handler.onMoreClick}"
android:src="@drawable/ic_more"
android:visibility="@{group ? View.INVISIBLE : View.VISIBLE}" />
<TextView
android:id="@+id/ml_item_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@+id/ml_item_resolution"
android:gravity="left"
android:layout_marginBottom="3dp"
android:layout_marginLeft="5dp"
android:singleLine="true"
android:textSize="@dimen/grid_card_subtitle_text_size"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_subtitle" />
<TextView
android:id="@+id/ml_item_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@+id/ml_item_resolution"
android:gravity="left"
android:layout_marginBottom="3dp"
android:layout_marginLeft="5dp"
android:text="@{time}"
android:singleLine="true"
android:textSize="@dimen/grid_card_subtitle_text_size"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_subtitle" />
<TextView
android:id="@+id/ml_item_resolution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="3dp"
android:layout_marginRight="5dp"
android:singleLine="true"
android:textSize="@dimen/grid_card_subtitle_text_size"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_subtitle" />
<TextView
android:id="@+id/ml_item_resolution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="3dp"
android:layout_marginRight="5dp"
android:text="@{resolution}"
android:singleLine="true"
android:textSize="@dimen/grid_card_subtitle_text_size"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_subtitle" />
<ProgressBar
android:id="@+id/ml_item_progress"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:focusable="false"
android:indeterminate="false"
android:maxHeight="2dip"
android:minHeight="2dip"
android:progressDrawable="?attr/gridview_progressbar" />
<ProgressBar
android:id="@+id/ml_item_progress"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:focusable="false"
android:indeterminate="false"
android:maxHeight="2dip"
android:minHeight="2dip"
android:max="@{max}"
android:progress="@{progress}"
android:progressDrawable="?attr/gridview_progressbar" />
</RelativeLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
\ No newline at end of file
</android.support.v7.widget.CardView>
</layout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/layout_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
card_view:cardUseCompatPadding="true"
card_view:cardPreventCornerOverlap="false"
card_view:cardElevation="1sp" >
<RelativeLayout
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View"/>
<variable
name="media"
type="org.videolan.vlc.MediaWrapper"/>
<variable
name="time"
type="String"/>
<variable
name="max"
type="int"/>
<variable
name="progress"
type="int"/>
<variable
name="resolution"
type="String"/>
<variable
name="group"
type="boolean"/>
<variable
name="cover"
type="android.graphics.drawable.BitmapDrawable"/>
<variable
name="scaleType"
type="android.widget.ImageView.ScaleType"/>
<variable
name="handler"
type="org.videolan.vlc.gui.video.VideoListAdapter.ClickHandler"/>
</data>
<android.support.v7.widget.CardView
android:id="@+id/layout_item"
android:layout_width="match_parent"
android:layout_height="75dip"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="?attr/background_default" >
card_view:cardUseCompatPadding="true"
card_view:cardPreventCornerOverlap="false"
card_view:cardElevation="1sp" >
<ImageView
android:id="@+id/ml_item_thumbnail"
android:layout_width="120dip"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="75dip"
android:layout_alignParentLeft="true"
android:scaleType="fitCenter"
android:background="?attr/background_default_darker" />
android:orientation="horizontal"
android:background="?attr/background_default" >
<TextView
android:id="@+id/ml_item_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/ml_item_thumbnail"
android:layout_toLeftOf="@+id/item_more"
android:layout_above="@+id/ml_item_time"
android:layout_alignParentTop="true"
android:gravity="center_vertical"
android:ellipsize="end"
android:maxLines="2"
android:paddingLeft="12dip"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_title"
android:textSize="17sp" />
<ImageView
android:id="@+id/ml_item_thumbnail"
android:layout_width="120dip"
android:layout_height="75dip"
android:layout_alignParentLeft="true"
android:src="@{cover}"
android:scaleType="@{scaleType}"
android:background="?attr/background_default_darker" />
<ImageView
android:id="@+id/item_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_above="@+id/ml_item_resolution"
android:clickable="true"
android:contentDescription="@string/more_actions"
android:src="@drawable/ic_more"
android:scaleType="fitCenter" />
<TextView
android:id="@+id/ml_item_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/ml_item_thumbnail"
android:layout_toLeftOf="@+id/item_more"
android:layout_above="@+id/ml_item_time"
android:layout_alignParentTop="true"
android:text="@{media.title}"
android:gravity="center_vertical"
android:ellipsize="end"
android:maxLines="2"
android:paddingLeft="12dip"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_title"
android:textSize="17sp" />
<TextView
android:id="@+id/ml_item_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/ml_item_thumbnail"
android:layout_toLeftOf="@+id/ml_item_resolution"
android:layout_above="@id/ml_item_progress"
android:gravity="left"
android:paddingLeft="12dip"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_subtitle"
android:textSize="14sp" />
<TextView
android:id="@+id/ml_item_resolution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/ml_item_progress"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_subtitle"
android:textSize="14sp" />
<ImageView
android:id="@+id/item_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_above="@+id/ml_item_resolution"
android:clickable="true"
android:onClick="@{handler.onMoreClick}"
android:contentDescription="@string/more_actions"
android:src="@drawable/ic_more"
android:scaleType="fitCenter"
android:visibility="@{group ? View.INVISIBLE : View.VISIBLE}" />
<ProgressBar
android:id="@+id/ml_item_progress"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/ml_item_thumbnail"
android:layout_alignParentBottom="true"
android:layout_marginTop="1dp"
android:layout_marginRight="10dip"
android:layout_marginLeft="10dip"
android:paddingBottom="3dip"
android:focusable="false"
android:indeterminate="false"
android:maxHeight="2dip"
android:minHeight="2dip"
android:progressDrawable="?attr/gridview_progressbar" />
</RelativeLayout>
<TextView
android:id="@+id/ml_item_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/ml_item_thumbnail"
android:layout_toLeftOf="@+id/ml_item_resolution"
android:layout_above="@id/ml_item_progress"
android:gravity="left"
android:paddingLeft="12dip"
android:text="@{time}"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_subtitle"
android:textSize="14sp" />
<TextView
android:id="@+id/ml_item_resolution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/ml_item_progress"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:text="@{resolution}"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_subtitle"
android:textSize="14sp" />
<ProgressBar
android:id="@+id/ml_item_progress"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/ml_item_thumbnail"
android:layout_alignParentBottom="true"
android:layout_marginTop="1dp"
android:layout_marginRight="10dip"
android:layout_marginLeft="10dip"
android:paddingBottom="3dip"
android:visibility="@{time != null ? View.VISIBLE : View.INVISIBLE}"
android:focusable="false"
android:indeterminate="false"
android:maxHeight="2dip"
android:minHeight="2dip"
android:max="@{max}"
android:progress="@{progress}"
android:progressDrawable="?attr/gridview_progressbar" />
</RelativeLayout>
</android.support.v7.widget.CardView>
\ No newline at end of file
</android.support.v7.widget.CardView>
</layout>
......@@ -21,26 +21,25 @@
package org.videolan.vlc.gui.video;
import android.content.Context;
import android.content.res.ColorStateList;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.support.v4.util.ArrayMap;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.videolan.vlc.BR;
import org.videolan.vlc.MediaGroup;
import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.R;
import org.videolan.vlc.util.BitmapCache;
import org.videolan.vlc.util.BitmapUtil;
import org.videolan.vlc.util.Strings;
import org.videolan.vlc.util.Util;
import java.util.Comparator;
import java.util.Locale;
......@@ -160,83 +159,67 @@ public class VideoListAdapter extends ArrayAdapter<MediaWrapper>
ViewHolder holder;
View v = convertView;
if (v == null || (((ViewHolder)v.getTag()).listmode != mListMode)) {
if (v == null || (((ViewHolder)v.getTag(R.layout.video_grid)).listmode != mListMode)) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (!mListMode)
v = inflater.inflate(R.layout.video_grid_card, parent, false);
else
v = inflater.inflate(R.layout.video_list_card, parent, false);
holder = new ViewHolder();
holder.thumbnail = (ImageView) v.findViewById(R.id.ml_item_thumbnail);
holder.title = (TextView) v.findViewById(R.id.ml_item_title);
holder.time = (TextView) v.findViewById(R.id.ml_item_time);
holder.resolution = (TextView) v.findViewById(R.id.ml_item_resolution);
holder.progress = (ProgressBar) v.findViewById(R.id.ml_item_progress);
holder.more = (ImageView) v.findViewById(R.id.item_more);
holder.binding = DataBindingUtil.inflate(inflater, mListMode ? R.layout.video_list_card : R.layout.video_grid_card, parent, false);
v = holder.binding.getRoot();
holder.listmode = mListMode;
v.setTag(holder);
/* Set the layoutParams based on the values set in the video_grid_item.xml root element */
v.setLayoutParams(new GridView.LayoutParams(v.getLayoutParams().width, v.getLayoutParams().height));
v.setTag(R.layout.video_grid, holder);
} else {
holder = (ViewHolder) v.getTag();
holder = (ViewHolder) v.getTag(R.layout.video_grid);
}
if (position >= getCount() || position < 0)
return v;
holder.more.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mFragment != null)
mFragment.onContextPopupMenu(v, position);
}
});
holder.position = position;
MediaWrapper media = getItem(position);
/* Thumbnail */
Bitmap thumbnail = BitmapUtil.getPictureFromCache(media);
holder.thumbnail.setScaleType(ImageView.ScaleType.FIT_CENTER);
if (thumbnail == null) {
// missing thumbnail
holder.thumbnail.setScaleType(ImageView.ScaleType.CENTER);
holder.binding.setVariable(BR.scaleType, ImageView.ScaleType.CENTER);
thumbnail = BitmapCache.getFromResource(v, R.drawable.ic_cone_o);
}
else if (thumbnail.getWidth() == 1 && thumbnail.getHeight() == 1) {
} else if (thumbnail.getWidth() == 1 && thumbnail.getHeight() == 1) {
// dummy thumbnail
holder.thumbnail.setScaleType(ImageView.ScaleType.CENTER);
holder.binding.setVariable(BR.scaleType, ImageView.ScaleType.CENTER);
thumbnail = BitmapCache.getFromResource(v, R.drawable.ic_cone_o);
}
//FIXME Warning: the thumbnails are upscaled in the grid view!
holder.thumbnail.setImageBitmap(thumbnail);
} else
holder.binding.setVariable(BR.scaleType, ImageView.ScaleType.FIT_CENTER);
/* Color state */
ColorStateList titleColor = v.getResources().getColorStateList(
Util.getResourceFromAttribute(getContext(), R.attr.list_title));
holder.title.setTextColor(titleColor);
//FIXME Warning: the thumbnails are upscaled in the grid view!
holder.binding.setVariable(BR.cover, new BitmapDrawable(getContext().getResources(), thumbnail));
if (media instanceof MediaGroup)
fillGroupView(holder, media);
else
fillVideoView(holder, media);
holder.binding.setVariable(BR.media, media);
holder.binding.setVariable(BR.handler, mClickHandler);
holder.binding.executePendingBindings();
return v;
}
public ClickHandler mClickHandler = new ClickHandler();
public class ClickHandler {
public void onMoreClick(View v){
if (mFragment != null)
mFragment.onContextPopupMenu(v, ((ViewHolder) ((CardView)v.getParent().getParent()).getTag(R.layout.video_grid)).position);
}
}
private void fillGroupView(ViewHolder holder, MediaWrapper media) {
holder.binding.setVariable(BR.group, true);
MediaGroup mediaGroup = (MediaGroup) media;
int size = mediaGroup.size();
String text = getContext().getResources().getQuantityString(R.plurals.videos_quantity, size, size);
holder.time.setText("");
holder.resolution.setText(text);
holder.title.setText(media.getTitle() + "\u2026"); // ellipsis
holder.more.setVisibility(View.GONE);
holder.progress.setVisibility(View.INVISIBLE);
mediaGroup.setTitle(media.getTitle() + "\u2026");
holder.binding.setVariable(BR.resolution, text);
}
private void fillVideoView(ViewHolder holder, MediaWrapper media) {
......@@ -248,33 +231,22 @@ public class VideoListAdapter extends ArrayAdapter<MediaWrapper>
text = String.format("%s / %s",
Strings.millisToText(lastTime),
Strings.millisToText(media.getLength()));
holder.progress.setVisibility(View.VISIBLE);
holder.progress.setMax((int) (media.getLength() / 1000));
holder.progress.setProgress((int) (lastTime / 1000));
holder.binding.setVariable(BR.max, (int) (media.getLength() / 1000));
holder.binding.setVariable(BR.progress, (int) (lastTime / 1000));
} else {
text = Strings.millisToText(media.getLength());
holder.progress.setVisibility(View.INVISIBLE);
}
holder.time.setText(text);
} else
holder.progress.setVisibility(View.INVISIBLE);
holder.binding.setVariable(BR.time, text);
}
if (media.getWidth() > 0 && media.getHeight() > 0)
holder.resolution.setText(String.format("%dx%d", media.getWidth(), media.getHeight()));
else
holder.resolution.setText("");
holder.title.setText(media.getTitle());
holder.more.setVisibility(View.VISIBLE);
holder.binding.setVariable(BR.resolution, String.format("%dx%d", media.getWidth(), media.getHeight()));
}
static class ViewHolder {
boolean listmode;
ImageView thumbnail;
TextView title;
TextView time;
TextView resolution;
ImageView more;
ProgressBar progress;
int position;