/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.goanna.tabs; import java.lang.ref.WeakReference; import org.mozilla.goanna.R; import org.mozilla.goanna.favicons.Favicons; import org.mozilla.goanna.favicons.OnFaviconLoadedListener; import org.mozilla.goanna.util.ThreadUtils; import org.mozilla.goanna.widget.FaviconView; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Typeface; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; public class TabHistoryItemRow extends RelativeLayout { private final FaviconView favicon; private final TextView title; private final ImageView timeLineTop; private final ImageView timeLineBottom; // Listener for handling Favicon loads. private final OnFaviconLoadedListener faviconListener; private int loadFaviconJobId = Favicons.NOT_LOADING; public TabHistoryItemRow(Context context, AttributeSet attrs) { super(context, attrs); LayoutInflater.from(context).inflate(R.layout.tab_history_item_row, this); favicon = (FaviconView) findViewById(R.id.tab_history_icon); title = (TextView) findViewById(R.id.tab_history_title); timeLineTop = (ImageView) findViewById(R.id.tab_history_timeline_top); timeLineBottom = (ImageView) findViewById(R.id.tab_history_timeline_bottom); faviconListener = new UpdateViewFaviconLoadedListener(favicon); } // Update the views with historic page detail. public void update(final TabHistoryPage historyPage, boolean isFirstElement, boolean isLastElement) { ThreadUtils.assertOnUiThread(); timeLineTop.setVisibility(isFirstElement ? View.INVISIBLE : View.VISIBLE); timeLineBottom.setVisibility(isLastElement ? View.INVISIBLE : View.VISIBLE); title.setText(historyPage.getTitle()); if (historyPage.isSelected()) { // Highlight title with bold font. title.setTypeface(null, Typeface.BOLD); } else { // Clear previously set bold font. title.setTypeface(null, Typeface.NORMAL); } favicon.setEnabled(historyPage.isSelected()); favicon.clearImage(); Favicons.cancelFaviconLoad(loadFaviconJobId); loadFaviconJobId = Favicons.getSizedFaviconForPageFromLocal(getContext(), historyPage.getUrl(), faviconListener); } // Only holds a reference to the FaviconView itself, so if the row gets // discarded while a task is outstanding, we'll leak less memory. private static class UpdateViewFaviconLoadedListener implements OnFaviconLoadedListener { private final WeakReference view; public UpdateViewFaviconLoadedListener(FaviconView view) { this.view = new WeakReference(view); } /** * Update this row's favicon. *

* This method is always invoked on the UI thread. */ @Override public void onFaviconLoaded(String url, String faviconURL, Bitmap favicon) { FaviconView v = view.get(); if (v == null) { return; } if (favicon == null) { v.showDefaultFavicon(); return; } v.updateImage(favicon, faviconURL); } } }