Commit 39a8dfc3 authored by Geoffrey Métais's avatar Geoffrey Métais

Data binding for media browsers

parent b0e2d96f
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/separator_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="20dp"/>
</LinearLayout>
\ No newline at end of file
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="android.view.View"/>
<variable
name="title"
type="String"/>
</data>
<LinearLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/separator_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="20dp"
android:text="@{title}"/>
</LinearLayout>
</layout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:focusable="true"
android:clickable="true"
android:background="@drawable/background_item">
<CheckBox
android:id="@+id/browser_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:button="@drawable/custom_checkbox_button"
android:layout_marginLeft="15dp"
android:visibility="gone"/>
<ImageView
android:id="@+id/dvi_icon"
android:layout_width="@dimen/directory_browser_item_size"
android:layout_height="@dimen/directory_browser_item_size"
android:layout_gravity="center"
android:layout_marginLeft="15dp"
android:contentDescription="@string/cover_art"
android:src="@drawable/icon" />
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="android.view.View"/>
<variable
name="handler"
type="org.videolan.vlc.gui.browser.BaseBrowserAdapter.ClickHandler"/>
<variable
name="media"
type="org.videolan.vlc.MediaWrapper"/>
<variable
name="storage"
type="org.videolan.vlc.gui.browser.BaseBrowserAdapter.Storage"/>
<variable
name="type"
type="int"/>
<variable
name="hasContextMenu"
type="boolean"/>
<variable
name="chechEnabled"
type="boolean"/>
<variable
name="checked"
type="boolean"/>
</data>
<LinearLayout
android:layout_width="0dp"
android:id="@+id/layout_item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_marginTop="15dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="15dp" >
android:orientation="horizontal"
android:focusable="true"
android:clickable="true"
android:longClickable="@{hasContextMenu}"
android:onClick="@{handler.onClick}"
android:background="@drawable/background_item">
<TextView
android:id="@+id/title"
<CheckBox
android:id="@+id/browser_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="@string/title"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_title"
android:textSize="16sp" />
android:button="@drawable/custom_checkbox_button"
android:layout_marginLeft="15dp"
android:visibility="@{type == 2 ? View.VISIBLE : View.GONE}"
android:enabled="@{chechEnabled}"
android:checked="@{checked}"
android:onClick="@{handler.onCheckBoxClick}"/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
<ImageView
android:id="@+id/dvi_icon"
android:layout_width="@dimen/directory_browser_item_size"
android:layout_height="@dimen/directory_browser_item_size"
android:layout_gravity="center"
android:layout_marginLeft="15dp"
android:contentDescription="@string/cover_art"
android:visibility="@{type != 2 ? View.VISIBLE : View.GONE}"
android:src="@drawable/icon" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:maxLines="1"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_subtitle"/>
</LinearLayout>
android:layout_marginBottom="15dp"
android:layout_marginTop="15dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="15dp" >
<ImageView
android:id="@+id/item_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingRight="10dp"
android:paddingLeft="10dp"
android:background="@drawable/ic_more"
android:clickable="true" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="@{storage.name ?? media.title}"
android:fontFamily="sans-serif-light"
android:textColor="?attr/list_title"
android:textSize="16sp" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:maxLines="1"
android:text="@{media.description}"
android:fontFamily="sans-serif-light"
android:visibility="@{media.description != null ? View.VISIBLE : View.INVISIBLE}"
android:textColor="?attr/list_subtitle"/>
</LinearLayout>
<ImageView
android:id="@+id/item_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingRight="10dp"
android:paddingLeft="10dp"
android:background="@drawable/ic_more"
android:visibility="@{hasContextMenu ? View.VISIBLE : View.GONE}"
android:onClick="@{@{handler.onMoreClick}}"
android:clickable="@{hasContextMenu}" />
</LinearLayout>
\ No newline at end of file
</LinearLayout>
</layout>
......@@ -22,21 +22,22 @@
*/
package org.videolan.vlc.gui.browser;
import android.databinding.DataBindingUtil;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import org.videolan.libvlc.Media;
import org.videolan.vlc.MediaDatabase;
import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.R;
import org.videolan.vlc.VLCApplication;
import org.videolan.vlc.databinding.BrowserItemSeparatorBinding;
import org.videolan.vlc.databinding.DirectoryViewItemBinding;
import org.videolan.vlc.gui.audio.MediaComparators;
import org.videolan.vlc.util.CustomDirectories;
import org.videolan.vlc.util.Util;
......@@ -51,9 +52,9 @@ import java.util.List;
public class BaseBrowserAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
protected static final String TAG = "VLC/BaseBrowserAdapter";
private static final int TYPE_MEDIA = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_STORAGE = 2;
protected static final int TYPE_MEDIA = 0;
protected static final int TYPE_SEPARATOR = 1;
protected static final int TYPE_STORAGE = 2;
protected int FOLDER_RES_ID = R.drawable.ic_menu_folder;
......@@ -92,7 +93,7 @@ public class BaseBrowserAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
onBindMediaViewHolder(holder, position);
} else {
SeparatorViewHolder vh = (SeparatorViewHolder) holder;
vh.title.setText(getItem(position).toString());
vh.binding.setTitle(getItem(position).toString());
}
}
......@@ -102,58 +103,21 @@ public class BaseBrowserAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
boolean hasContextMenu = (media.getType() == MediaWrapper.TYPE_AUDIO ||
media.getType() == MediaWrapper.TYPE_VIDEO ||
media.getType() == MediaWrapper.TYPE_DIR );
vh.checkBox.setVisibility(View.GONE);
vh.title.setText(media.getTitle());
if (!TextUtils.isEmpty(media.getDescription())) {
vh.text.setVisibility(View.VISIBLE);
vh.text.setText(media.getDescription());
} else
vh.text.setVisibility(View.INVISIBLE);
vh.binding.setHandler(mClickHandler);
vh.binding.setMedia(media);
vh.binding.setHasContextMenu(hasContextMenu);
vh.binding.setType(TYPE_MEDIA);
vh.binding.executePendingBindings();
vh.icon.setImageResource(getIconResId(media));
vh.more.setVisibility(hasContextMenu ? View.VISIBLE : View.GONE);
vh.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MediaWrapper mw = (MediaWrapper) getItem(holder.getAdapterPosition());
mw.removeFlags(MediaWrapper.MEDIA_FORCE_AUDIO);
if (mw.getType() == MediaWrapper.TYPE_DIR)
fragment.browse(mw, holder.getAdapterPosition(), true);
else if (mw.getType() == MediaWrapper.TYPE_VIDEO)
Util.openMedia(v.getContext(), mw);
else if (mw.getType() == MediaWrapper.TYPE_AUDIO) {
int position = 0;
LinkedList<MediaWrapper> mediaLocations = new LinkedList<MediaWrapper>();
MediaWrapper mediaItem;
for (Object item : mMediaList)
if (item instanceof MediaWrapper) {
mediaItem = (MediaWrapper) item;
if (mediaItem.getType() == MediaWrapper.TYPE_VIDEO || mediaItem.getType() == MediaWrapper.TYPE_AUDIO) {
mediaLocations.add(mediaItem);
if (mediaItem.equals(mw))
position = mediaLocations.size() - 1;
}
}
Util.openList(v.getContext(), mediaLocations, position);
} else {
Util.openStream(v.getContext(), mw.getLocation());
}
}
});
if (hasContextMenu) {
vh.more.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fragment.onPopupMenu(vh.more, holder.getAdapterPosition());
}
});
vh.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
fragment.mRecyclerView.openContextMenu(holder.getAdapterPosition());
return true;
}
});
// vh.more.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// fragment.onPopupMenu(vh.more, holder.getAdapterPosition());
// }
// });
vh.itemView.setOnLongClickListener(mLongClickListener);
}
}
......@@ -163,28 +127,27 @@ public class BaseBrowserAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
public class MediaViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public CheckBox checkBox;
public TextView text;
public ImageView icon;
public ImageView more;
DirectoryViewItemBinding binding;
public MediaViewHolder(View v) {
super(v);
title = (TextView) v.findViewById(R.id.title);
binding = DataBindingUtil.bind(v);
checkBox = (CheckBox) v.findViewById(R.id.browser_checkbox);
text = (TextView) v.findViewById(R.id.text);
icon = (ImageView) v.findViewById(R.id.dvi_icon);
more = (ImageView) v.findViewById(R.id.item_more);
v.findViewById(R.id.layout_item).setTag(R.id.layout_item, this);
}
}
public static class SeparatorViewHolder extends RecyclerView.ViewHolder {
public TextView title;
BrowserItemSeparatorBinding binding;
public SeparatorViewHolder(View v) {
super(v);
title = (TextView) v.findViewById(R.id.separator_title);
binding = DataBindingUtil.bind(v);
}
}
......@@ -336,4 +299,59 @@ public class BaseBrowserAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
return R.drawable.ic_browser_unknown_normal;
}
}
public ClickHandler mClickHandler = new ClickHandler();
public class ClickHandler {
public void onClick(View v){
openMediaFromView(v);
}
public void onCheckBoxClick(View v){
checkBoxAction(v);
}
public void onMoreClick(View v){
final MediaViewHolder holder = (MediaViewHolder) v.getTag(R.id.layout_item);
fragment.onPopupMenu(holder.more, holder.getAdapterPosition());
}
}
protected void openMediaFromView(View v) {
final MediaViewHolder holder = (MediaViewHolder) v.getTag(R.id.layout_item);
final MediaWrapper mw = (MediaWrapper) getItem(holder.getAdapterPosition());
mw.removeFlags(MediaWrapper.MEDIA_FORCE_AUDIO);
if (mw.getType() == MediaWrapper.TYPE_DIR)
fragment.browse(mw, holder.getAdapterPosition(), true);
else if (mw.getType() == MediaWrapper.TYPE_VIDEO)
Util.openMedia(v.getContext(), mw);
else if (mw.getType() == MediaWrapper.TYPE_AUDIO) {
int position = 0;
LinkedList<MediaWrapper> mediaLocations = new LinkedList<MediaWrapper>();
MediaWrapper mediaItem;
for (Object item : mMediaList)
if (item instanceof MediaWrapper) {
mediaItem = (MediaWrapper) item;
if (mediaItem.getType() == MediaWrapper.TYPE_VIDEO || mediaItem.getType() == MediaWrapper.TYPE_AUDIO) {
mediaLocations.add(mediaItem);
if (mediaItem.equals(mw))
position = mediaLocations.size() - 1;
}
}
Util.openList(v.getContext(), mediaLocations, position);
} else {
Util.openStream(v.getContext(), mw.getLocation());
}
}
protected void checkBoxAction(View v){}
View.OnLongClickListener mLongClickListener = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
final MediaViewHolder holder = (MediaViewHolder) v.getTag(R.id.layout_item);
fragment.mRecyclerView.openContextMenu(holder.getAdapterPosition());
return true;
}
};
}
......@@ -29,6 +29,7 @@ import android.view.View;
import org.videolan.libvlc.Media;
import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.R;
public class FilePickerAdapter extends BaseBrowserAdapter {
......@@ -45,28 +46,24 @@ public class FilePickerAdapter extends BaseBrowserAdapter {
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
final MediaViewHolder vh = (MediaViewHolder) holder;
final MediaWrapper media = (MediaWrapper) getItem(position);
vh.checkBox.setVisibility(View.GONE);
vh.title.setText(media.getTitle());
if (!TextUtils.isEmpty(media.getDescription())) {
vh.text.setVisibility(View.VISIBLE);
vh.text.setText(media.getDescription());
} else
vh.text.setVisibility(View.INVISIBLE);
vh.binding.setHandler(mClickHandler);
vh.binding.setMedia(media);
vh.binding.setHasContextMenu(false);
vh.binding.setType(TYPE_MEDIA);
vh.icon.setImageResource(getIconResId(media));
vh.more.setVisibility(View.GONE);
vh.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (media.getType() == MediaWrapper.TYPE_DIR)
fragment.browse(media, holder.getAdapterPosition(), true);
else
((FilePickerFragment)fragment).pickFile(media);
}
});
}
//TODO update with different filter types in other cases than subtitles selection
private boolean filter(MediaWrapper mediaWrapper) {
return mediaWrapper.getType() == MediaWrapper.TYPE_DIR || mediaWrapper.getType() == MediaWrapper.TYPE_SUBTITLE;
}
protected void openMediaFromView(View v) {
final MediaViewHolder holder = (MediaViewHolder) v.getTag(R.id.layout_item);
final MediaWrapper media = (MediaWrapper) getItem(holder.getAdapterPosition());
if (media.getType() == MediaWrapper.TYPE_DIR)
fragment.browse(media, holder.getAdapterPosition(), true);
else
((FilePickerFragment)fragment).pickFile(media);
}
}
......@@ -29,6 +29,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import org.videolan.libvlc.Media;
import org.videolan.vlc.MediaWrapper;
......@@ -59,24 +60,14 @@ public class StorageBrowserAdapter extends BaseBrowserAdapter {
final Storage storage = (Storage) getItem(position);
String storagePath = storage.getUri().getPath();
boolean hasContextMenu = mCustomDirsLocation.contains(storagePath);
vh.title.setText(storage.getName());
vh.icon.setVisibility(View.GONE);
vh.checkBox.setVisibility(View.VISIBLE);
vh.more.setVisibility(hasContextMenu ? View.VISIBLE : View.GONE);
vh.text.setVisibility(View.GONE);
vh.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MediaWrapper mw = new MediaWrapper(((Storage) getItem(vh.getAdapterPosition())).getUri());
mw.setType(MediaWrapper.TYPE_DIR);
((StorageBrowserFragment) fragment).browse(mw, holder.getAdapterPosition(), vh.checkBox.isChecked());
}
});
vh.checkBox.setChecked(((StorageBrowserFragment) fragment).mScannedDirectory ||
vh.binding.setHandler(mClickHandler);
vh.binding.setStorage(storage);
vh.binding.setHasContextMenu(hasContextMenu);
vh.binding.setType(TYPE_STORAGE);
vh.binding.setChecked(((StorageBrowserFragment) fragment).mScannedDirectory ||
(isRoot && (mMediaDirsLocation == null || mMediaDirsLocation.isEmpty())) ||
mMediaDirsLocation.contains(storagePath));
vh.checkBox.setEnabled(!((StorageBrowserFragment) fragment).mScannedDirectory);
vh.binding.setChechEnabled(!((StorageBrowserFragment) fragment).mScannedDirectory);
vh.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
......@@ -88,21 +79,8 @@ public class StorageBrowserAdapter extends BaseBrowserAdapter {
removeDir(path);
}
});
if (hasContextMenu) {
vh.more.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fragment.onPopupMenu(vh.more, holder.getAdapterPosition());
}
});
vh.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
fragment.mRecyclerView.openContextMenu(holder.getAdapterPosition());
return true;
}
});
}
if (hasContextMenu)
vh.itemView.setOnLongClickListener(mLongClickListener);
}
public void addItem(Media media, boolean notify, boolean top){
......@@ -165,4 +143,21 @@ public class StorageBrowserAdapter extends BaseBrowserAdapter {
}
});
}
protected void openMediaFromView(View v) {
MediaViewHolder holder = (MediaViewHolder) v.getTag(R.id.layout_item);
MediaWrapper mw = new MediaWrapper(((Storage) getItem(holder.getAdapterPosition())).getUri());
mw.setType(MediaWrapper.TYPE_DIR);
fragment.browse(mw, holder.getAdapterPosition(), holder.checkBox.isChecked());
}
protected void checkBoxAction(View v){
MediaViewHolder holder = (MediaViewHolder) ((LinearLayout)v.getParent()).getTag(R.id.layout_item);
boolean isChecked = ((CheckBox) v).isChecked();
String path = ((Storage) getItem(holder.getAdapterPosition())).getUri().getPath();
if (isChecked)
addDir(path);
else
removeDir(path);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment