Android, получение эскиза путем анализа URL-адреса в качестве аргумента с помощью SimpleCursorAdapter.ViewBinder

я знаю, что заголовок немного запутан, но вот проблема.... моя цель - получить заголовок и нарисовать эскизы видео моего канала YouTube, используя URL-адрес эскиза, в listView... до сих пор у меня есть textView для правильного отображения заголовка видео, но миниатюру все равно нельзя было нарисовать..... кстати, у меня есть классы материалов json / sqlite, сделанные правильно, и они могут правильно извлекать данные, поэтому мне не нужно беспокоиться об этом. .. единственное, что меня беспокоит, это то, что миниатюра не отображается, изображение отображается как пустое место в приложении....

вот мой код, пожалуйста, дайте мне руку. спасибо

это метод создания действия...

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    String[] uiBindFrom = { TutListDatabase.COL_TITLE, TutListDatabase.COL_THUMBNAIL };
    int[] uiBindTo = { R.id.title, R.id.thumbnail };

    getLoaderManager().initLoader(TUTORIAL_LIST_LOADER, null, this);

    adapter = new SimpleCursorAdapter(
            getActivity().getApplicationContext(), R.layout.list_item,
            null, uiBindFrom, uiBindTo,
            CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    adapter.setViewBinder(new MyViewBinder());
    setListAdapter(adapter);
}

и это частный класс для размещения вещей в listView...

private class MyViewBinder implements SimpleCursorAdapter.ViewBinder{

    @Override
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
        int viewId = view.getId();
        switch(viewId){
        case R.id.title:
            TextView titleTV = (TextView)view;
            titleTV.setText(cursor.getString(columnIndex));
            break;

                    // it is not displaying any thumbnail in app....
        case R.id.thumbnail:
            ImageView thumb = (ImageView) view;
            thumb.setImageURI(Uri.parse(cursor.getString(columnIndex)));

        break;
        }
        return false;
    }

}

а вот файл макета xml...

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal" >

<ImageView
    android:id="@+id/thumbnail"
    android:layout_width="101dp"
    android:layout_height="101dp"
    android:src="@drawable/icon" />

<TextView
    android:id="@+id/title"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="6dp"
    android:textSize="24dp" />


</LinearLayout>

person sefirosu    schedule 20.09.2012    source источник
comment
Является ли изображение uri внешним ресурсом? если это так, вы можете обнаружить, что это зависнет, если ему нужно сделать сетевой запрос   -  person Ian Warwick    schedule 20.09.2012
comment
да . URI является внешним ресурсом на YouTube. Как решить проблему? любой пример будет полезен...   -  person sefirosu    schedule 20.09.2012


Ответы (1)


Я могу показать вам способ, который я использовал, и он работал довольно хорошо, во-первых, нам нужен способ кэширования изображений, и лучший способ, который я видел на сегодняшний день, — это использовать LruCache, как описано в превосходной презентации Google IO, выполняющей больше с меньшими затратами: http://www.youtube.com/watch?v=gbQb1PVjfqM.

Вот моя реализация метода, описанного в этой презентации.

public class BitmapCache extends LruCache<String, Bitmap> { 

    public BitmapCache(int sizeInBytes) {
        super(sizeInBytes);
    }   

    public BitmapCache(Context context) {
        super(getOptimalCacheSizeInBytes(context));
    }   

    public static int getOptimalCacheSizeInBytes(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        int memoryClassBytes = am.getMemoryClass() * 1024 * 1024;

        return memoryClassBytes / 8;
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight();
    }
}

Затем нам нужно асинхронно загрузить изображения с помощью AsyncTask, следующая реализация позаботится о загрузке изображения в данный ImageView и работе с кешем:

public class LoadImageAsyncTask extends AsyncTask<Void, Void, Pair<Bitmap, Exception>> {
    private ImageView mImageView;
    private String mUrl;
    private BitmapCache mCache;

    public LoadImageAsyncTask(BitmapCache cache, ImageView imageView, String url) {
        mCache = cache;
        mImageView = imageView;
        mUrl = url;

        mImageView.setTag(mUrl);
    }

    @Override
    protected void onPreExecute() {
        Bitmap bm = mCache.get(mUrl);

        if(bm != null) {
            cancel(false);

            mImageView.setImageBitmap(bm);
        }
    }

    @Override
    protected Pair<Bitmap, Exception> doInBackground(Void... arg0) {
        if(isCancelled()) {
            return null;
        }

        URL url;
        InputStream inStream = null;
        try {
            url = new URL(mUrl);
            URLConnection conn = url.openConnection();

            inStream = conn.getInputStream();

            Bitmap bitmap = BitmapFactory.decodeStream(inStream);

            return new Pair<Bitmap, Exception>(bitmap, null);

        } catch (Exception e) {
            return new Pair<Bitmap, Exception>(null, e);
        }
        finally {
            closeSilenty(inStream);
        }
    }

    @Override
    protected void onPostExecute(Pair<Bitmap, Exception> result) {
        if(result == null) {
            return;
        }

        if(result.first != null && mUrl.equals(mImageView.getTag())) {
            mCache.put(mUrl, result.first);
            mImageView.setImageBitmap(result.first);
        }
    }

    public void closeSilenty(Closeable closeable) {
        if(closeable != null) {
        try {
            closeable.close();
        } catch (Exception e) {
            // TODO: Log this
        }
        }
    }
}

Затем вам нужно создать экземпляр вашего BitmapCache в действии или фрагменте, в котором размещается ListView, в onCreate(...) или onActivityCreated(...):

mBitmapCache = new BitmapCache(this); // or getActivity() if your using a Fragment

Теперь нам нужно обновить SimpleCursorAdapter, который показывает изображение, я опустил большую часть кода, поскольку он специфичен для моего проекта, но идея в том, что вы переопределяете setViewImage, где значение должно быть значением, привязанным к курсору, я удаляю imageview на null, чтобы убедиться, что у него нет нечетного изображения из кеша, связанного с элементом.

    @Override
    public void setViewImage(ImageView iv, String value) {
        final String url = value;
        iv.setImageBitmap(null);
        new LoadImageAsyncTask(mBitmapCache, iv, url).execute();

    }

Обновить

Чтобы было понятно, ваш адаптер должен выглядеть примерно так

    adapter = new SimpleCursorAdapter(
            context, R.layout.list_item,
            null, uiBindFrom, uiBindTo,
            CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER) {
        @Override
        public void setViewImage(ImageView iv, String value) {
                final String url = value;
                iv.setImageBitmap(null);
                new LoadImageAsyncTask(mBitmapCache, iv, url).execute();
        }
    };

Надеюсь, это поможет!

person Ian Warwick    schedule 20.09.2012
comment
извините, я немного запутался... как перезаписать setViewImage..? и что такое ..Closeables.closeSilenty(inStream); ? и вы создаете BitmapCache bm = new BitmapCache(getActivity().getApplicationContext()) для размещения списка? я запутался в логике... :( - person sefirosu; 20.09.2012
comment
Привет, извините, в примере кода, который я обновил, были некоторые ошибки, чтобы удалить Closeables. BitmapCache должен быть полем вашей активности или фрагмента. Затем вам нужно изменить SimpleCursorAdapter и переопределить setViewImage(...) - person Ian Warwick; 20.09.2012
comment
Я обновил код примера, чтобы сделать его более понятным, надеюсь, это поможет - person Ian Warwick; 20.09.2012