我正在專門研究CardScrollAdapter
中的操作,但在將卡發佈到時間線時,在LiveCard情況下也很好。有沒有辦法使用凌空或任何其他網絡庫來加載使用通用Card
類的圖像?延遲加載卡上的圖像
回答
「有額外的複雜性,目前的XE12 GDK只支持card.addImage(URI)與當地的資源和文件的URI所以除了上述警告,你必須將圖像下載到文件,然後才能將其添加爲卡片圖像。「
看起來像XE16 +現在支持card.addImage(位圖),因此使用文件作爲臨時緩存可能不再需要。
雖然你不能用Card
(因爲Card
管理自己的佈局),你應該能夠使用其他的功能的凌空處理延遲加載的圖像直接使用排的NetworkImageView
類。當您創建Card
- ,有它最初使用一個佔位符圖像,如果需要的圖像已經不可用(緩存的地方):
在一個高層次的,你可以使用這樣的方法。跟蹤某個地方的
Card
的實例(例如,在適配器中)。 - 排隊加載圖像的請求。
- 檢索完圖像後,將圖像寫入應用程序的緩存目錄,並使用
file:
URL將其添加到卡中。 - 再次致電
Card.toView()
重新生成卡的視圖並根據需要更新您的用戶界面。
好的有辦法做到這一點,但它有點複雜。訣竅是,您無法在適配器的getView()
中調度異步映像加載任務,這是您通常在android中執行的方式。如果您嘗試,您會發現在準備加載圖像時,由card.toView()
返回的ImageView
將會GC'd。似乎是GDK中的一個錯誤,或者可能是它設計的方式,我不確定。
當前的XE12 GDK僅支持帶本地資源和文件URI的card.addImage(Uri)
,這就增加了複雜性。因此,除了上述警告之外,您必須先將圖像下載到文件,然後才能將其添加爲卡片圖像。
我將使用Android Universal Image Loader來協助完成圖像下載任務。下面是這樣做的課程:
public class CardImageLoader {
private static final String TAG = CardImageLoader.class.getSimpleName();
private static final boolean DEBUG = false;
private static final int MAX_IMAGE_LOAD_RETRIES = 3;
private static Map<String, Integer> mLoadFailures = new ConcurrentHashMap<String, Integer>();
public static void init(Context context) {
File cacheDir = StorageUtils.getCacheDirectory(context);
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheOnDisc(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.discCache(new UnlimitedDiscCache(cacheDir))
.defaultDisplayImageOptions(options)
.build();
ImageLoader.getInstance().init(config);
}
public static void loadCardImage(final Card card, final String imageUri, final CardScrollView cardScrollView) {
card.setImageLayout(Card.ImageLayout.FULL);
int failures = mLoadFailures.containsKey(imageUri) ? mLoadFailures.get(imageUri) : 0;
if (failures > MAX_IMAGE_LOAD_RETRIES) {
if (DEBUG) Log.i(TAG, "Exceeded max retries on imageUri=" + imageUri);
return;
}
File file = ImageLoader.getInstance().getDiscCache().get(imageUri);
if (file != null && file.exists() && file.length() > 0) {
Uri uri = Uri.fromFile(file);
card.addImage(uri);
}
else {
ImageLoader.getInstance().loadImage(imageUri, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
if (DEBUG) Log.i(TAG, "onLoadingStarted");
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
if (DEBUG) Log.i(TAG, "onLoadingFailed");
int failures = mLoadFailures.containsKey(imageUri) ? mLoadFailures.get(imageUri) : 0;
mLoadFailures.put(imageUri, ++failures);
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
File file = ImageLoader.getInstance().getDiscCache().get(imageUri);
if (DEBUG) Log.i(TAG, "onLoadingComplete uri=" + imageUri + " file=" + file
+ " len=" + (file == null ? 0 : file.length()));
if (file != null && file.exists() && file.length() > 0) {
if (DEBUG) Log.i(TAG, "onLoadingComplete scheduling update of scroll views");
if (cardScrollView != null)
cardScrollView.updateViews(true);
}
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
if (DEBUG) Log.i(TAG, "onLoadingCancelled");
}
});
}
}
}
以下是它的工作原理。在適配器的getView()
中,我們找到了要加載的URL。我們問圖像加載器是否已經獲取了圖像緩存。如果有,我們會找到本地文件Uri並撥打card.addImage(Uri)
,我們就完成了。如果我們沒有緩存圖像,我們不能使用正常的圖像加載程序調用以前描述的原因。相反,我們使用loadImage()' and if successful, ask the
CardScrollView下載文件重新顯示自己(不要嘗試在此處設置卡,即使使用變量final
,也不會發生任何事情)。這將最終導致getView()
再次被調用,只有這一次文件將被緩存。因此圖像將被添加到卡上,並且您的卡片將正確顯示。
還有一些失敗的下載跟蹤,以防止在下載失敗時重新顯示循環的CardScrollView
。
你如何使用它?挺容易。首先在你的onCreate()
你需要初始化這條線的圖像加載器:
CardImageLoader.init(this);
其次,在適配器getView()
方法,當你要加載在卡中的圖像調用此方法:
CardImageLoader.loadCardImage(card, url, mCardScrollView);
然後您將顯示帶有圖像的卡片。目前我發現的唯一警告是,不要一次加載超過20張圖像,否則您可能會出現性能問題。裝載150個墜毀的玻璃,所以要小心。除此之外,它一直很好。
更新:我減慢加載列表與10 +圖像。我不確定這是因爲在每個圖像加載或什麼後調用updateViews()
。
此代碼適用於我,謝謝!我需要將類方法修改爲不是靜態的,以便爲最新版本的Glass進行編譯。 – MikeN
「更新:我得到的影片加載速度超過10張圖片,我不確定這是因爲在每次加載圖片或調用後調用updateViews()。
確保您的CardScrollAdapter getView()方法不會嘗試在每次調用時加載圖像。
例如:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (getCards() == null) return null;
MyCard card = getCards().get(position);
if (! card.isImageLoaded()) {
CardImageLoader.loadCardImage(...);
}
return card.toView();
}
看起來像最新版本的卡片不再定義addImage(uri) – user1679130
- 1. 延遲加載UICollectionView圖像
- 2. Javascript延遲圖像加載
- 3. ajax加載圖像延遲?
- 4. 延遲加載PhotoLibrary圖像
- 5. HttpWebRequest圖像加載延遲
- 6. 延遲加載的gif圖像
- 7. 延遲加載UIImageView中的圖像
- 8. 延遲加載的圖像問題UICollectionView
- 9. 推遲或延遲在單個頁面上加載大圖像
- 10. 圖像不延遲加載和緩存
- 11. 動態圖像加載延遲在ios
- 12. 在Vue/Laravel中延遲加載圖像
- 13. 在UIScrollView中延遲加載圖像
- 14. 停止延遲加載圖像?
- 15. 在ImageSpan中延遲加載圖像
- 16. uwp延遲加載圖像源
- 17. 使用jQuery加載延遲圖像
- 18. 延遲加載動態畫面圖像
- 19. UISearchDisplayController和圖像延遲加載
- 20. 在jQuery Mobile中延遲加載圖像
- 21. 在tableview中延遲加載圖像
- 22. 在ListView中延遲加載圖像
- 23. UITableView - 延遲加載聯繫人圖像
- 24. 延遲加載延遲
- 25. 延遲加載我的網頁上的圖像
- 26. 延遲加載Highcharts'圖表
- 27. AngularJS延遲視圖加載
- 28. Hibernate延遲加載視圖
- 29. 延遲加載iPhone圖片
- 30. android圖庫視圖「延遲」與延遲圖像加載適配器
這就是我目前正在實施的。這有點令人失望,因爲它需要爲這些圖像管理文件緩存,而不是在檢索時從內存中加載它們。 – yincrash
@tony - 'Card.toViews()'似乎不存在。你的意思是別的嗎? –
錯字 - 有一個額外的「s」。編輯它到'toView'。 –