Loading res/layout/inspector_header.xml +11 −0 Original line number Diff line number Diff line Loading @@ -17,11 +17,22 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/inspector_mime" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:background="@android:color/black" /> <ImageView android:id="@+id/inspector_thumbnail" android:layout_width="match_parent" android:layout_height="match_parent" android:alpha="0.0" android:scaleType="centerCrop" android:background="@android:color/black" /> <TextView android:id="@+id/inspector_file_title" android:layout_width="wrap_content" Loading src/com/android/documentsui/ThumbnailLoader.java 0 → 100644 +134 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * 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 com.android.documentsui; import static com.android.documentsui.base.Shared.VERBOSE; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Point; import android.net.Uri; import android.os.AsyncTask; import android.os.CancellationSignal; import android.os.OperationCanceledException; import android.provider.DocumentsContract; import android.util.Log; import android.view.View; import android.widget.ImageView; import com.android.documentsui.ProviderExecutor.Preemptable; import java.util.function.BiConsumer; /** * Loads a Thumbnails asynchronously then animates from the mime icon to the thumbnail */ public final class ThumbnailLoader extends AsyncTask<Uri, Void, Bitmap> implements Preemptable { private static final String TAG = ThumbnailLoader.class.getCanonicalName(); /** * Two animations applied to image views. The first is used to switch mime icon and thumbnail. * The second is used when we need to update thumbnail. */ public static final BiConsumer<View, View> ANIM_FADE_IN = (mime, thumb) -> { float alpha = mime.getAlpha(); mime.animate().alpha(0f).start(); thumb.setAlpha(0f); thumb.animate().alpha(alpha).start(); }; public static final BiConsumer<View, View> ANIM_NO_OP = (mime, thumb) -> {}; private final ImageView mIconThumb; private final Point mThumbSize; // A callback to apply animation to image views after the thumbnail is loaded. private final BiConsumer<View, View> mImageAnimator; private final Uri mUri; private final ImageView mIconMime; private final long mLastModified; private final boolean mAddToCache; private final CancellationSignal mSignal; /** * @param uri - to a thumbnail. * @param iconMime - ImageView for displaying a mime type. * @param iconThumb - ImageView to display the thumbnail. * @param thumbSize - size of the thumbnail. * @param lastModified - used for updating thumbnail caches. * @param animator - used to animate from the mime icon to the thumbnail. * @param addToCache - flag that determines if the loader saves the thumbnail to the cache. */ public ThumbnailLoader(Uri uri, ImageView iconMime, ImageView iconThumb, Point thumbSize, long lastModified, BiConsumer<View, View> animator, boolean addToCache) { mUri = uri; mIconMime = iconMime; mIconThumb = iconThumb; mThumbSize = thumbSize; mImageAnimator = animator; mLastModified = lastModified; mAddToCache = addToCache; mSignal = new CancellationSignal(); mIconThumb.setTag(this); if (VERBOSE) Log.v(TAG, "Starting icon loader task for " + mUri); } @Override public void preempt() { if (VERBOSE) Log.v(TAG, "Icon loader task for " + mUri + " was cancelled."); cancel(false); mSignal.cancel(); } @Override protected Bitmap doInBackground(Uri... params) { if (isCancelled()) { return null; } final Context context = mIconThumb.getContext(); final ContentResolver resolver = context.getContentResolver(); ContentProviderClient client = null; Bitmap result = null; try { client = DocumentsApplication.acquireUnstableProviderOrThrow( resolver, mUri.getAuthority()); result = DocumentsContract.getDocumentThumbnail(client, mUri, mThumbSize, mSignal); if (result != null && mAddToCache) { final ThumbnailCache cache = DocumentsApplication.getThumbnailCache(context); cache.putThumbnail(mUri, mThumbSize, result, mLastModified); } } catch (Exception e) { if (!(e instanceof OperationCanceledException)) { Log.w(TAG, "Failed to load thumbnail for " + mUri + ": " + e); } } finally { ContentProviderClient.releaseQuietly(client); } return result; } @Override protected void onPostExecute(Bitmap result) { if (VERBOSE) Log.v(TAG, "Loader task for " + mUri + " completed"); if (mIconThumb.getTag() == this && result != null) { mIconThumb.setTag(null); mIconThumb.setImageBitmap(result); mImageAnimator.accept(mIconMime, mIconThumb); } } } src/com/android/documentsui/dirlist/IconHelper.java +6 −97 Original line number Diff line number Diff line Loading @@ -20,16 +20,11 @@ import static com.android.documentsui.base.Shared.VERBOSE; import static com.android.documentsui.base.State.MODE_GRID; import static com.android.documentsui.base.State.MODE_LIST; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; import android.os.CancellationSignal; import android.os.OperationCanceledException; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Document; import android.support.annotation.Nullable; Loading @@ -40,10 +35,10 @@ import android.widget.ImageView; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.IconUtils; import com.android.documentsui.ProviderExecutor; import com.android.documentsui.ProviderExecutor.Preemptable; import com.android.documentsui.R; import com.android.documentsui.ThumbnailCache; import com.android.documentsui.ThumbnailCache.Result; import com.android.documentsui.ThumbnailLoader; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.MimeTypes; import com.android.documentsui.base.State; Loading @@ -58,16 +53,6 @@ import java.util.function.BiConsumer; public class IconHelper { private static final String TAG = "IconHelper"; // Two animations applied to image views. The first is used to switch mime icon and thumbnail. // The second is used when we need to update thumbnail. private static final BiConsumer<View, View> ANIM_FADE_IN = (mime, thumb) -> { float alpha = mime.getAlpha(); mime.animate().alpha(0f).start(); thumb.setAlpha(0f); thumb.animate().alpha(alpha).start(); }; private static final BiConsumer<View, View> ANIM_NO_OP = (mime, thumb) -> {}; private final Context mContext; private final ThumbnailCache mThumbnailCache; Loading Loading @@ -129,89 +114,13 @@ public class IconHelper { * @param icon */ public void stopLoading(ImageView icon) { final LoaderTask oldTask = (LoaderTask) icon.getTag(); final ThumbnailLoader oldTask = (ThumbnailLoader) icon.getTag(); if (oldTask != null) { oldTask.preempt(); icon.setTag(null); } } /** Internal task for loading thumbnails asynchronously. */ private static class LoaderTask extends AsyncTask<Uri, Void, Bitmap> implements Preemptable { private final Uri mUri; private final ImageView mIconMime; private final ImageView mIconThumb; private final Point mThumbSize; private final long mLastModified; // A callback to apply animation to image views after the thumbnail is loaded. private final BiConsumer<View, View> mImageAnimator; private final CancellationSignal mSignal; public LoaderTask(Uri uri, ImageView iconMime, ImageView iconThumb, Point thumbSize, long lastModified, BiConsumer<View, View> animator) { mUri = uri; mIconMime = iconMime; mIconThumb = iconThumb; mThumbSize = thumbSize; mImageAnimator = animator; mLastModified = lastModified; mSignal = new CancellationSignal(); if (VERBOSE) Log.v(TAG, "Starting icon loader task for " + mUri); } @Override public void preempt() { if (VERBOSE) Log.v(TAG, "Icon loader task for " + mUri + " was cancelled."); cancel(false); mSignal.cancel(); } @Override protected Bitmap doInBackground(Uri... params) { if (isCancelled()) { return null; } final Context context = mIconThumb.getContext(); final ContentResolver resolver = context.getContentResolver(); ContentProviderClient client = null; Bitmap result = null; try { client = DocumentsApplication.acquireUnstableProviderOrThrow( resolver, mUri.getAuthority()); result = DocumentsContract.getDocumentThumbnail(client, mUri, mThumbSize, mSignal); if (result != null) { final ThumbnailCache cache = DocumentsApplication.getThumbnailCache(context); cache.putThumbnail(mUri, mThumbSize, result, mLastModified); } } catch (Exception e) { if (!(e instanceof OperationCanceledException)) { Log.w(TAG, "Failed to load thumbnail for " + mUri + ": " + e); } } finally { ContentProviderClient.releaseQuietly(client); } return result; } @Override protected void onPostExecute(Bitmap result) { if (VERBOSE) Log.v(TAG, "Loader task for " + mUri + " completed"); if (mIconThumb.getTag() == this && result != null) { mIconThumb.setTag(null); mIconThumb.setImageBitmap(result); mImageAnimator.accept(mIconMime, mIconThumb); } } } /** * Load thumbnails for a directory list item. * Loading Loading @@ -287,11 +196,11 @@ public class IconHelper { uri.toString(), result.getStatus(), stale)); if (!result.isExactHit() || stale) { final BiConsumer<View, View> animator = (cachedThumbnail == null ? ANIM_FADE_IN : ANIM_NO_OP); final LoaderTask task = new LoaderTask(uri, iconMime, iconThumb, mCurrentSize, docLastModified, animator); (cachedThumbnail == null ? ThumbnailLoader.ANIM_FADE_IN : ThumbnailLoader.ANIM_NO_OP); iconThumb.setTag(task); final ThumbnailLoader task = new ThumbnailLoader(uri, iconMime, iconThumb, mCurrentSize, docLastModified, animator, true); ProviderExecutor.forAuthority(docAuthority).execute(task); } Loading src/com/android/documentsui/inspector/HeaderView.java +42 −1 Original line number Diff line number Diff line Loading @@ -15,13 +15,20 @@ */ package com.android.documentsui.inspector; import android.app.Activity; import android.content.Context; import android.graphics.Point; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import com.android.documentsui.ProviderExecutor; import com.android.documentsui.ThumbnailLoader; import com.android.documentsui.base.Display; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.R; import java.util.function.Consumer; Loading @@ -31,8 +38,14 @@ import java.util.function.Consumer; */ public final class HeaderView extends RelativeLayout implements Consumer<DocumentInfo> { private static final String TAG = HeaderView.class.getCanonicalName(); private final Context mContext; private final View mHeader; private ImageView mMime; private ImageView mThumbnail; private final TextView mTitle; private Point mImageDimensions; public HeaderView(Context context) { this(context, null); Loading @@ -46,8 +59,15 @@ public final class HeaderView extends RelativeLayout implements Consumer<Documen super(context, attrs, defStyleAttr); LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE); mContext = context; mHeader = inflater.inflate(R.layout.inspector_header, null); mMime = (ImageView) mHeader.findViewById(R.id.inspector_mime); mThumbnail = (ImageView) mHeader.findViewById(R.id.inspector_thumbnail); mTitle = (TextView) mHeader.findViewById(R.id.inspector_file_title); int width = (int) Display.screenWidth((Activity)context); int height = mContext.getResources().getDimensionPixelSize(R.dimen.inspector_header_height); mImageDimensions = new Point(width, height); } @Override Loading @@ -55,6 +75,10 @@ public final class HeaderView extends RelativeLayout implements Consumer<Documen if (!hasHeader()) { addView(mHeader); } if(!hasHeaderImage()) { loadHeaderImage(info); } mTitle.setText(info.displayName); } Loading @@ -66,4 +90,21 @@ public final class HeaderView extends RelativeLayout implements Consumer<Documen } return false; } private void loadHeaderImage(DocumentInfo info) { // load the mime icon. Drawable d = mContext.getContentResolver().getTypeDrawable(info.mimeType); mMime.setImageDrawable(d); // load the thumbnail async. final ThumbnailLoader task = new ThumbnailLoader(info.derivedUri, mMime, mThumbnail, mImageDimensions, info.lastModified, ThumbnailLoader.ANIM_FADE_IN, false); task.executeOnExecutor(ProviderExecutor.forAuthority(info.derivedUri.getAuthority()), info.derivedUri); } private boolean hasHeaderImage() { return mThumbnail.getAlpha() == 1.0f; } } No newline at end of file Loading
res/layout/inspector_header.xml +11 −0 Original line number Diff line number Diff line Loading @@ -17,11 +17,22 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/inspector_mime" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:background="@android:color/black" /> <ImageView android:id="@+id/inspector_thumbnail" android:layout_width="match_parent" android:layout_height="match_parent" android:alpha="0.0" android:scaleType="centerCrop" android:background="@android:color/black" /> <TextView android:id="@+id/inspector_file_title" android:layout_width="wrap_content" Loading
src/com/android/documentsui/ThumbnailLoader.java 0 → 100644 +134 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * 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 com.android.documentsui; import static com.android.documentsui.base.Shared.VERBOSE; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Point; import android.net.Uri; import android.os.AsyncTask; import android.os.CancellationSignal; import android.os.OperationCanceledException; import android.provider.DocumentsContract; import android.util.Log; import android.view.View; import android.widget.ImageView; import com.android.documentsui.ProviderExecutor.Preemptable; import java.util.function.BiConsumer; /** * Loads a Thumbnails asynchronously then animates from the mime icon to the thumbnail */ public final class ThumbnailLoader extends AsyncTask<Uri, Void, Bitmap> implements Preemptable { private static final String TAG = ThumbnailLoader.class.getCanonicalName(); /** * Two animations applied to image views. The first is used to switch mime icon and thumbnail. * The second is used when we need to update thumbnail. */ public static final BiConsumer<View, View> ANIM_FADE_IN = (mime, thumb) -> { float alpha = mime.getAlpha(); mime.animate().alpha(0f).start(); thumb.setAlpha(0f); thumb.animate().alpha(alpha).start(); }; public static final BiConsumer<View, View> ANIM_NO_OP = (mime, thumb) -> {}; private final ImageView mIconThumb; private final Point mThumbSize; // A callback to apply animation to image views after the thumbnail is loaded. private final BiConsumer<View, View> mImageAnimator; private final Uri mUri; private final ImageView mIconMime; private final long mLastModified; private final boolean mAddToCache; private final CancellationSignal mSignal; /** * @param uri - to a thumbnail. * @param iconMime - ImageView for displaying a mime type. * @param iconThumb - ImageView to display the thumbnail. * @param thumbSize - size of the thumbnail. * @param lastModified - used for updating thumbnail caches. * @param animator - used to animate from the mime icon to the thumbnail. * @param addToCache - flag that determines if the loader saves the thumbnail to the cache. */ public ThumbnailLoader(Uri uri, ImageView iconMime, ImageView iconThumb, Point thumbSize, long lastModified, BiConsumer<View, View> animator, boolean addToCache) { mUri = uri; mIconMime = iconMime; mIconThumb = iconThumb; mThumbSize = thumbSize; mImageAnimator = animator; mLastModified = lastModified; mAddToCache = addToCache; mSignal = new CancellationSignal(); mIconThumb.setTag(this); if (VERBOSE) Log.v(TAG, "Starting icon loader task for " + mUri); } @Override public void preempt() { if (VERBOSE) Log.v(TAG, "Icon loader task for " + mUri + " was cancelled."); cancel(false); mSignal.cancel(); } @Override protected Bitmap doInBackground(Uri... params) { if (isCancelled()) { return null; } final Context context = mIconThumb.getContext(); final ContentResolver resolver = context.getContentResolver(); ContentProviderClient client = null; Bitmap result = null; try { client = DocumentsApplication.acquireUnstableProviderOrThrow( resolver, mUri.getAuthority()); result = DocumentsContract.getDocumentThumbnail(client, mUri, mThumbSize, mSignal); if (result != null && mAddToCache) { final ThumbnailCache cache = DocumentsApplication.getThumbnailCache(context); cache.putThumbnail(mUri, mThumbSize, result, mLastModified); } } catch (Exception e) { if (!(e instanceof OperationCanceledException)) { Log.w(TAG, "Failed to load thumbnail for " + mUri + ": " + e); } } finally { ContentProviderClient.releaseQuietly(client); } return result; } @Override protected void onPostExecute(Bitmap result) { if (VERBOSE) Log.v(TAG, "Loader task for " + mUri + " completed"); if (mIconThumb.getTag() == this && result != null) { mIconThumb.setTag(null); mIconThumb.setImageBitmap(result); mImageAnimator.accept(mIconMime, mIconThumb); } } }
src/com/android/documentsui/dirlist/IconHelper.java +6 −97 Original line number Diff line number Diff line Loading @@ -20,16 +20,11 @@ import static com.android.documentsui.base.Shared.VERBOSE; import static com.android.documentsui.base.State.MODE_GRID; import static com.android.documentsui.base.State.MODE_LIST; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; import android.os.CancellationSignal; import android.os.OperationCanceledException; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Document; import android.support.annotation.Nullable; Loading @@ -40,10 +35,10 @@ import android.widget.ImageView; import com.android.documentsui.DocumentsApplication; import com.android.documentsui.IconUtils; import com.android.documentsui.ProviderExecutor; import com.android.documentsui.ProviderExecutor.Preemptable; import com.android.documentsui.R; import com.android.documentsui.ThumbnailCache; import com.android.documentsui.ThumbnailCache.Result; import com.android.documentsui.ThumbnailLoader; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.MimeTypes; import com.android.documentsui.base.State; Loading @@ -58,16 +53,6 @@ import java.util.function.BiConsumer; public class IconHelper { private static final String TAG = "IconHelper"; // Two animations applied to image views. The first is used to switch mime icon and thumbnail. // The second is used when we need to update thumbnail. private static final BiConsumer<View, View> ANIM_FADE_IN = (mime, thumb) -> { float alpha = mime.getAlpha(); mime.animate().alpha(0f).start(); thumb.setAlpha(0f); thumb.animate().alpha(alpha).start(); }; private static final BiConsumer<View, View> ANIM_NO_OP = (mime, thumb) -> {}; private final Context mContext; private final ThumbnailCache mThumbnailCache; Loading Loading @@ -129,89 +114,13 @@ public class IconHelper { * @param icon */ public void stopLoading(ImageView icon) { final LoaderTask oldTask = (LoaderTask) icon.getTag(); final ThumbnailLoader oldTask = (ThumbnailLoader) icon.getTag(); if (oldTask != null) { oldTask.preempt(); icon.setTag(null); } } /** Internal task for loading thumbnails asynchronously. */ private static class LoaderTask extends AsyncTask<Uri, Void, Bitmap> implements Preemptable { private final Uri mUri; private final ImageView mIconMime; private final ImageView mIconThumb; private final Point mThumbSize; private final long mLastModified; // A callback to apply animation to image views after the thumbnail is loaded. private final BiConsumer<View, View> mImageAnimator; private final CancellationSignal mSignal; public LoaderTask(Uri uri, ImageView iconMime, ImageView iconThumb, Point thumbSize, long lastModified, BiConsumer<View, View> animator) { mUri = uri; mIconMime = iconMime; mIconThumb = iconThumb; mThumbSize = thumbSize; mImageAnimator = animator; mLastModified = lastModified; mSignal = new CancellationSignal(); if (VERBOSE) Log.v(TAG, "Starting icon loader task for " + mUri); } @Override public void preempt() { if (VERBOSE) Log.v(TAG, "Icon loader task for " + mUri + " was cancelled."); cancel(false); mSignal.cancel(); } @Override protected Bitmap doInBackground(Uri... params) { if (isCancelled()) { return null; } final Context context = mIconThumb.getContext(); final ContentResolver resolver = context.getContentResolver(); ContentProviderClient client = null; Bitmap result = null; try { client = DocumentsApplication.acquireUnstableProviderOrThrow( resolver, mUri.getAuthority()); result = DocumentsContract.getDocumentThumbnail(client, mUri, mThumbSize, mSignal); if (result != null) { final ThumbnailCache cache = DocumentsApplication.getThumbnailCache(context); cache.putThumbnail(mUri, mThumbSize, result, mLastModified); } } catch (Exception e) { if (!(e instanceof OperationCanceledException)) { Log.w(TAG, "Failed to load thumbnail for " + mUri + ": " + e); } } finally { ContentProviderClient.releaseQuietly(client); } return result; } @Override protected void onPostExecute(Bitmap result) { if (VERBOSE) Log.v(TAG, "Loader task for " + mUri + " completed"); if (mIconThumb.getTag() == this && result != null) { mIconThumb.setTag(null); mIconThumb.setImageBitmap(result); mImageAnimator.accept(mIconMime, mIconThumb); } } } /** * Load thumbnails for a directory list item. * Loading Loading @@ -287,11 +196,11 @@ public class IconHelper { uri.toString(), result.getStatus(), stale)); if (!result.isExactHit() || stale) { final BiConsumer<View, View> animator = (cachedThumbnail == null ? ANIM_FADE_IN : ANIM_NO_OP); final LoaderTask task = new LoaderTask(uri, iconMime, iconThumb, mCurrentSize, docLastModified, animator); (cachedThumbnail == null ? ThumbnailLoader.ANIM_FADE_IN : ThumbnailLoader.ANIM_NO_OP); iconThumb.setTag(task); final ThumbnailLoader task = new ThumbnailLoader(uri, iconMime, iconThumb, mCurrentSize, docLastModified, animator, true); ProviderExecutor.forAuthority(docAuthority).execute(task); } Loading
src/com/android/documentsui/inspector/HeaderView.java +42 −1 Original line number Diff line number Diff line Loading @@ -15,13 +15,20 @@ */ package com.android.documentsui.inspector; import android.app.Activity; import android.content.Context; import android.graphics.Point; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import com.android.documentsui.ProviderExecutor; import com.android.documentsui.ThumbnailLoader; import com.android.documentsui.base.Display; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.R; import java.util.function.Consumer; Loading @@ -31,8 +38,14 @@ import java.util.function.Consumer; */ public final class HeaderView extends RelativeLayout implements Consumer<DocumentInfo> { private static final String TAG = HeaderView.class.getCanonicalName(); private final Context mContext; private final View mHeader; private ImageView mMime; private ImageView mThumbnail; private final TextView mTitle; private Point mImageDimensions; public HeaderView(Context context) { this(context, null); Loading @@ -46,8 +59,15 @@ public final class HeaderView extends RelativeLayout implements Consumer<Documen super(context, attrs, defStyleAttr); LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE); mContext = context; mHeader = inflater.inflate(R.layout.inspector_header, null); mMime = (ImageView) mHeader.findViewById(R.id.inspector_mime); mThumbnail = (ImageView) mHeader.findViewById(R.id.inspector_thumbnail); mTitle = (TextView) mHeader.findViewById(R.id.inspector_file_title); int width = (int) Display.screenWidth((Activity)context); int height = mContext.getResources().getDimensionPixelSize(R.dimen.inspector_header_height); mImageDimensions = new Point(width, height); } @Override Loading @@ -55,6 +75,10 @@ public final class HeaderView extends RelativeLayout implements Consumer<Documen if (!hasHeader()) { addView(mHeader); } if(!hasHeaderImage()) { loadHeaderImage(info); } mTitle.setText(info.displayName); } Loading @@ -66,4 +90,21 @@ public final class HeaderView extends RelativeLayout implements Consumer<Documen } return false; } private void loadHeaderImage(DocumentInfo info) { // load the mime icon. Drawable d = mContext.getContentResolver().getTypeDrawable(info.mimeType); mMime.setImageDrawable(d); // load the thumbnail async. final ThumbnailLoader task = new ThumbnailLoader(info.derivedUri, mMime, mThumbnail, mImageDimensions, info.lastModified, ThumbnailLoader.ANIM_FADE_IN, false); task.executeOnExecutor(ProviderExecutor.forAuthority(info.derivedUri.getAuthority()), info.derivedUri); } private boolean hasHeaderImage() { return mThumbnail.getAlpha() == 1.0f; } } No newline at end of file