New app grid UI

This commit is contained in:
Cameron Gutman 2020-06-11 21:51:07 -07:00
parent 9fb7359a3e
commit 47b2ace7fd
7 changed files with 69 additions and 110 deletions

View File

@ -113,11 +113,7 @@ public class AppGridAdapter extends GenericGridAdapter<AppView.AppObject> {
@Override @Override
public void populateView(ImageView imgView, ProgressBar prgView, TextView txtView, ImageView overlayView, AppView.AppObject obj) { public void populateView(ImageView imgView, ProgressBar prgView, TextView txtView, ImageView overlayView, AppView.AppObject obj) {
// Let the cached asset loader handle it // Let the cached asset loader handle it
loader.populateImageView(obj.app, imgView, prgView); loader.populateImageView(obj.app, imgView, txtView);
// Select the text view so it starts marquee mode
txtView.setSelected(true);
txtView.setText(obj.app.getAppName());
if (obj.isRunning) { if (obj.isRunning) {
// Show the play button overlay // Show the play button overlay

View File

@ -10,7 +10,6 @@ import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import com.limelight.R; import com.limelight.R;
import com.limelight.preferences.PreferenceConfiguration;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -9,7 +9,7 @@ import android.view.View;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.TextView;
import com.limelight.R; import com.limelight.R;
import com.limelight.nvstream.http.ComputerDetails; import com.limelight.nvstream.http.ComputerDetails;
@ -137,14 +137,14 @@ public class CachedAppAssetLoader {
private class LoaderTask extends AsyncTask<LoaderTuple, Void, ScaledBitmap> { private class LoaderTask extends AsyncTask<LoaderTuple, Void, ScaledBitmap> {
private final WeakReference<ImageView> imageViewRef; private final WeakReference<ImageView> imageViewRef;
private final WeakReference<ProgressBar> progressViewRef; private final WeakReference<TextView> textViewRef;
private final boolean diskOnly; private final boolean diskOnly;
private LoaderTuple tuple; private LoaderTuple tuple;
public LoaderTask(ImageView imageView, ProgressBar prgView, boolean diskOnly) { public LoaderTask(ImageView imageView, TextView textView, boolean diskOnly) {
this.imageViewRef = new WeakReference<>(imageView); this.imageViewRef = new WeakReference<>(imageView);
this.progressViewRef = new WeakReference<>(prgView); this.textViewRef = new WeakReference<>(textView);
this.diskOnly = diskOnly; this.diskOnly = diskOnly;
} }
@ -153,7 +153,7 @@ public class CachedAppAssetLoader {
tuple = params[0]; tuple = params[0];
// Check whether it has been cancelled or the views are gone // Check whether it has been cancelled or the views are gone
if (isCancelled() || imageViewRef.get() == null || progressViewRef.get() == null) { if (isCancelled() || imageViewRef.get() == null || textViewRef.get() == null) {
return null; return null;
} }
@ -186,20 +186,16 @@ public class CachedAppAssetLoader {
// If the current loader task for this view isn't us, do nothing // If the current loader task for this view isn't us, do nothing
final ImageView imageView = imageViewRef.get(); final ImageView imageView = imageViewRef.get();
final ProgressBar prgView = progressViewRef.get(); final TextView textView = textViewRef.get();
if (getLoaderTask(imageView) == this) { if (getLoaderTask(imageView) == this) {
// Now display the progress bar since we have to hit the network
if (prgView != null) {
prgView.setVisibility(View.VISIBLE);
}
// Set off another loader task on the network executor. This time our AsyncDrawable // Set off another loader task on the network executor. This time our AsyncDrawable
// will use the app image placeholder bitmap, rather than an empty bitmap. // will use the app image placeholder bitmap, rather than an empty bitmap.
LoaderTask task = new LoaderTask(imageView, prgView, false); LoaderTask task = new LoaderTask(imageView, textView, false);
AsyncDrawable asyncDrawable = new AsyncDrawable(imageView.getResources(), noAppImageBitmap, task); AsyncDrawable asyncDrawable = new AsyncDrawable(imageView.getResources(), noAppImageBitmap, task);
imageView.setImageDrawable(asyncDrawable); imageView.setImageDrawable(asyncDrawable);
imageView.startAnimation(AnimationUtils.loadAnimation(imageView.getContext(), R.anim.boxart_fadein)); imageView.startAnimation(AnimationUtils.loadAnimation(imageView.getContext(), R.anim.boxart_fadein));
imageView.setVisibility(View.VISIBLE); imageView.setVisibility(View.VISIBLE);
textView.setVisibility(View.VISIBLE);
task.executeOnExecutor(networkExecutor, tuple); task.executeOnExecutor(networkExecutor, tuple);
} }
} }
@ -212,15 +208,13 @@ public class CachedAppAssetLoader {
} }
final ImageView imageView = imageViewRef.get(); final ImageView imageView = imageViewRef.get();
final ProgressBar prgView = progressViewRef.get(); final TextView textView = textViewRef.get();
if (getLoaderTask(imageView) == this) { if (getLoaderTask(imageView) == this) {
// Hide the progress bar
if (prgView != null) {
prgView.setVisibility(View.INVISIBLE);
}
// Fade in the box art // Fade in the box art
if (bitmap != null) { if (bitmap != null) {
// Show the text if it's a placeholder
textView.setVisibility(isBitmapPlaceholder(bitmap) ? View.VISIBLE : View.GONE);
if (imageView.getVisibility() == View.VISIBLE) { if (imageView.getVisibility() == View.VISIBLE) {
// Fade out the placeholder first // Fade out the placeholder first
Animation fadeOutAnimation = AnimationUtils.loadAnimation(imageView.getContext(), R.anim.boxart_fadeout); Animation fadeOutAnimation = AnimationUtils.loadAnimation(imageView.getContext(), R.anim.boxart_fadeout);
@ -324,7 +318,13 @@ public class CachedAppAssetLoader {
}); });
} }
public boolean populateImageView(NvApp app, ImageView imgView, ProgressBar prgView) { private boolean isBitmapPlaceholder(ScaledBitmap bitmap) {
return (bitmap == null) ||
(bitmap.originalWidth == 130 && bitmap.originalHeight == 180) || // GFE 2.0
(bitmap.originalWidth == 628 && bitmap.originalHeight == 888); // GFE 3.0
}
public boolean populateImageView(NvApp app, ImageView imgView, TextView textView) {
LoaderTuple tuple = new LoaderTuple(computer, app); LoaderTuple tuple = new LoaderTuple(computer, app);
// If there's already a task in progress for this view, // If there's already a task in progress for this view,
@ -334,8 +334,8 @@ public class CachedAppAssetLoader {
return true; return true;
} }
// Hide the progress bar always on initial load // Always set the name text so we have it if needed later
prgView.setVisibility(View.INVISIBLE); textView.setText(app.getAppName());
// First, try the memory cache in the current context // First, try the memory cache in the current context
ScaledBitmap bmp = memoryLoader.loadBitmapFromCache(tuple); ScaledBitmap bmp = memoryLoader.loadBitmapFromCache(tuple);
@ -343,13 +343,17 @@ public class CachedAppAssetLoader {
// Show the bitmap immediately // Show the bitmap immediately
imgView.setVisibility(View.VISIBLE); imgView.setVisibility(View.VISIBLE);
imgView.setImageBitmap(bmp.bitmap); imgView.setImageBitmap(bmp.bitmap);
// Show the text if it's a placeholder bitmap
textView.setVisibility(isBitmapPlaceholder(bmp) ? View.VISIBLE : View.GONE);
return true; return true;
} }
// If it's not in memory, create an async task to load it. This task will be attached // If it's not in memory, create an async task to load it. This task will be attached
// via AsyncDrawable to this view. // via AsyncDrawable to this view.
final LoaderTask task = new LoaderTask(imgView, prgView, true); final LoaderTask task = new LoaderTask(imgView, textView, true);
final AsyncDrawable asyncDrawable = new AsyncDrawable(imgView.getResources(), placeholderBitmap, task); final AsyncDrawable asyncDrawable = new AsyncDrawable(imgView.getResources(), placeholderBitmap, task);
textView.setVisibility(View.INVISIBLE);
imgView.setVisibility(View.INVISIBLE); imgView.setVisibility(View.INVISIBLE);
imgView.setImageDrawable(asyncDrawable); imgView.setImageDrawable(asyncDrawable);

View File

@ -1,49 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="150dp"
android:layout_height="wrap_content" android:layout_height="200dp"
android:padding="20dp"> android:padding="10dp">
<RelativeLayout
android:id="@+id/grid_image_layout"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView <ImageView
android:id="@+id/grid_image" android:id="@+id/grid_image"
android:cropToPadding="false" android:cropToPadding="false"
android:scaleType="fitXY" android:scaleType="fitXY"
android:layout_centerHorizontal="true" android:layout_width="match_parent"
android:layout_width="150dp" android:layout_height="match_parent">
android:layout_height="175dp">
</ImageView> </ImageView>
<ProgressBar
android:id="@+id/grid_spinner"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_width="75dp"
android:layout_height="75dp"
android:indeterminate="true">
</ProgressBar>
<ImageView <ImageView
android:id="@+id/grid_overlay" android:id="@+id/grid_overlay"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_centerVertical="true" android:layout_marginTop="10dp"
android:layout_width="50dp" android:layout_width="50dp"
android:layout_height="50dp"> android:layout_height="50dp">
</ImageView> </ImageView>
</RelativeLayout>
<TextView <TextView
android:id="@+id/grid_text" android:id="@+id/grid_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_below="@id/grid_image_layout" android:layout_below="@id/grid_overlay"
android:layout_marginTop="10dp" android:layout_margin="5dp"
android:layout_centerHorizontal="true"
android:gravity="center" android:gravity="center"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:textSize="18sp"> android:textSize="18sp">
</TextView> </TextView>
</RelativeLayout> </RelativeLayout>

View File

@ -1,49 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="100dp"
android:layout_height="wrap_content" android:layout_height="133dp"
android:padding="10dp"> android:padding="5dp">
<RelativeLayout
android:id="@+id/grid_image_layout"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView <ImageView
android:id="@+id/grid_image" android:id="@+id/grid_image"
android:cropToPadding="false" android:cropToPadding="false"
android:scaleType="fitXY" android:scaleType="fitXY"
android:layout_centerHorizontal="true" android:layout_width="match_parent"
android:layout_width="100dp" android:layout_height="match_parent">
android:layout_height="117dp">
</ImageView> </ImageView>
<ProgressBar
android:id="@+id/grid_spinner"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_width="50dp"
android:layout_height="50dp"
android:indeterminate="true">
</ProgressBar>
<ImageView <ImageView
android:id="@+id/grid_overlay" android:id="@+id/grid_overlay"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_centerVertical="true" android:layout_marginTop="10dp"
android:layout_width="33dp" android:layout_width="33dp"
android:layout_height="33dp"> android:layout_height="33dp">
</ImageView> </ImageView>
</RelativeLayout>
<TextView <TextView
android:id="@+id/grid_text" android:id="@+id/grid_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_below="@id/grid_image_layout" android:layout_below="@id/grid_overlay"
android:layout_marginTop="10dp" android:layout_margin="5dp"
android:layout_centerHorizontal="true"
android:gravity="center" android:gravity="center"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:textSize="14sp"> android:textSize="14sp">
</TextView> </TextView>
</RelativeLayout> </RelativeLayout>

View File

@ -4,7 +4,7 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:numColumns="auto_fit" android:numColumns="auto_fit"
android:columnWidth="160dp" android:columnWidth="150dp"
android:stretchMode="spacingWidthUniform" android:stretchMode="spacingWidthUniform"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"

View File

@ -4,7 +4,7 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:numColumns="auto_fit" android:numColumns="auto_fit"
android:columnWidth="105dp" android:columnWidth="100dp"
android:stretchMode="spacingWidthUniform" android:stretchMode="spacingWidthUniform"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"