具有图像的Andr​​oid定制SimpleCursorAdapter从文件与数据库路径 [英] Android custom SimpleCursorAdapter with image from file with path in database

查看:202
本文介绍了具有图像的Andr​​oid定制SimpleCursorAdapter从文件与数据库路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要点:自定义适配器获取文件资源间接地通过文件路径数据库。李永忠/内存的担忧。您的意见要求。

Gist: custom adapter gets file resource indirectly via filepath in database. Inefficiency / memory concerns. Your opinion requested.

提及的所有搜索,相关链接和有用的东西重新话题是在后底部。

References to all searches, related links, and things useful re topic are at post bottom.

下面的作品,但多种因素的 code是关注。需要在此方面的经验更丰富的目光讨好建议改善或潜在的错误避免的。应用程序并不需要是一个内容提供商(源数据仅本地到应用程序)。有问题的ListView的将是重量很轻,只有大约5到最多10项。 (我离开了数据库的东西,因为它的工作原理。)

Code below works, but several factors are of concern. Need some more experienced eyes on this please to suggest improvement or potential errors to avoid. App doesn't need to be a content provider (data sourced local to app only). The ListView in question will be very light weight with only about 5 to max 10 entries. (I left out the database stuff because it works.)

概述:


  • 数据库中包含一些文本和图像文件的路径。 - 确定

  • 图像文件存储在设备(SD卡/外部存储,在以往任何时候)。 - 确定

这些文件不在数据库中,使比正常SimpleCursorAdapter此不同 - 要拉的图像文件。新增使它成为一个缩略图填充的ListView之前的开销。

That the files are not in the database makes this different than a normal SimpleCursorAdapter - have to pull the image file. Added overhead of making it into a thumbnail before populating the listview.

正如所述,它的光,但是,即使只有一个或两个条目,VM正在打嗝。我怀疑这是所有与位图内存joggling:

As said, it's light, however, even with only one or two entries, the VM is burping. I suspect it's all the memory joggling related to the Bitmaps:

08-27 19:53:14.273: I/dalvikvm-heap(11900): Grow heap (frag case) to 4.075MB for 1228816-byte allocation
08-27 19:53:14.393: D/dalvikvm(11900): GC_CONCURRENT freed <1K, 5% free 4032K/4244K, paused 13ms+3ms, total 116ms


/* myTextAndImageCursorAdapter.java */

import android.widget.SimpleCursorAdapter;

//import android.support.v4.widget.SimpleCursorAdapter;
import android.content.Context;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import android.database.Cursor;
import java.io.File;

import android.widget.ImageView;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import static android.media.ThumbnailUtils.extractThumbnail;


public class TextAndImageCursorAdapter extends SimpleCursorAdapter { 

    private Context context;
    private int layout;

    public TextAndImageCursorAdapter (Context ctx, int layout, Cursor c, String[] from, int[] to) {
        super(context, layout, c, from, to);
        this.context = ctx;
        this.layout = layout;
    }

    @Override
    public View newView(Context ctx, Cursor cursor, ViewGroup parent) {

        Cursor c = getCursor();

        final LayoutInflater inflater = LayoutInflater.from(ctx);
        View vView = inflater.inflate(layout, parent, false);

        int iCol_Text = c.getColumnIndex(DBCOL_TEXT);
        int iCol_Image = c.getColumnIndex(DBCOL_IMAGE);

        String sText = c.getString(iCol_Text);
        String sFileAndPath_Image = c.getString (iCol_Image);  //// sImage path & file

        TextView tvText = (TextView) v.findViewById(R.id.gui_text);
        if (tvText != null) {
            tvText.setText(sSomeText);
        }

        ImageView ivImage (ImageView) v.findViewById(R.id.gui_image);
        if (ivImage != null) {
            ivImage.setImage (mySetImage (sFileAndPath_Image) );
        }

        return vView;
    }

    @Override
    public void bindView(View v, Context ctx, Cursor c) {
        //// ( like newView(), without an inflater, view, or return ) 
        int iCol_Text = c.getColumnIndex(DBCOL_TEXT);
        int iCol_Image = c.getColumnIndex(DBCOL_IMAGE);

        String sText = c.getString(iCol_Text);
        String sFileAndPath_Image = c.getString (iCol_Image);  //// path & file

        TextView tvText = (TextView) v.findViewById(R.id.gui_text);
        if (tvText != null) {
            tvText.setText(sSomeText);
        }

        ImageView ivImage (ImageView) v.findViewById(R.id.gui_image);
        if (ivImage != null) {
            ivImage.setImageBitmap ( mySetImage ( sFileAndPath_Image ) ) ;
        }
    }
    /////
    /////
    protected Bitmap mySetImage ( String path ) {
        int width = 60; int height = 40 ;

        File imgFile = new File ( path );  //// usually like: \sdcard0\wherever\filename1234.bmp
        Bitmap myBitmap = null;

        if( imgFile.exists() )
        {
                myBitmap = BitmapFactory.decodeFile ( imgFile.getAbsolutePath () );                  
        }
            else                    
                Log.d ("oops", "no image file ... using default.");
                myBitmap = getTheDefaultImage ();  //// not shown - this is arbitrary
        }

        imgFile.close();
        return ( extractThumbnail ( myBitmap, width, height ) ) ;
    }      
}


搜索标准:

具有图像的Andr​​oid定制simplecursoradapter从文件与数据库路径

Search Criteria: " Android custom simplecursoradapter with image from file with path in database "

最近的打击,但将尝试从资源拉动的图像,而不是从外部/ SD存储(未):
<一href=\"http://stackoverflow.com/questions/13330654/simplecursoradapter-how-to-show-an-image\">SimpleCursorAdapter如何显示图像?

The nearest hit, but attempts to pull image from res, not from external / sd store (unanswered): SimpleCursorAdapter how to show an image?

还有近命中/缺失 - 类似的算法中(未)引用4):
<一href=\"http://stackoverflow.com/questions/17885047/customizing-list-shown-from-simplecursoradapter-using-viewbinder\">Customizing利用SimpleCursorAdapter显示列表ViewBinder

Also a near hit / miss - similar algo (unanswered) references 4): Customizing list shown from SimpleCursorAdapter using ViewBinder

差不多,但OP的code不工作,(无工作的答案):
<一href=\"http://stackoverflow.com/questions/15747380/load-image-in-a-custom-list-by-simplecursoradapter\">Load图片由SimpleCursorAdapter

Almost, but OP's code doesn't work, (no working answer): Load Image in a custom list by SimpleCursorAdapter

工作OP,但使用JSON进行远程检索,而不是本地(也许这可以调整,但它不是我清楚如何)。
<一href=\"http://stackoverflow.com/questions/12460463/how-to-show-images-in-imageview-in-simple-adapter\">How显示在ImageView的图像简单的适配器?

Working for OP, but uses JSON for remote retrieval, not local (maybe this could be tweaked, but it's not clear to me how). How to show images in imageview in simple adapter?

不完全是,但再度接近:
<一href=\"http://stackoverflow.com/questions/12085405/listview-scroll-slow-while-loading-image-from-internal-storage\">ListView从滚动慢加载图像内部存储

Not quite, but again close: ListView scroll slow while loading image from Internal Storage

图像装载机问题(参考文献2):
<一href=\"http://stackoverflow.com/questions/18416526/imageloader-not-loading-image-on-real-device\">Imageloader不加载真实设备图片

Image Loader problems (references 2): Imageloader not loading image on real device

相关链接:

的Andr​​oid定制光标适配器

<一个href=\"http://stackoverflow.com/questions/5183813/android-issue-with-newview-and-bindview-in-custom-simplecursoradapter\">Android:发行与NewView的和bindView定制SimpleCursorAdapter

同样名为命中,但无关我的具体问题 - 这通常是指在应用程序的资源:
<一href=\"http://stackoverflow.com/questions/8681878/show-image-from-database-where-you-saved-the-path-of-image\">show从数据库映像您保存图片的路径

Similarly named hits, but unrelated to my specific questions - these usually refer to in-app RESources: show image from database where you saved the path of image

定制SimpleCursorAdapter错误

<一个href=\"http://stackoverflow.com/questions/5716653/custom-simplecursoradapter-database-query-and-nullpointerexception\">Custom SimpleCursorAdapter,数据库查询和NullPointerException异常

<一个href=\"http://stackoverflow.com/questions/12069036/nullpointerexception-with-extended-simplecursoradapter\">nullPointerException与扩展SimpleCursorAdapter

<一个href=\"http://stackoverflow.com/questions/7439609/android-simplecursoradapter-adding-conditional-images\">Android SimpleCursorAdapter - 添加条件图片

外部参考:

0)的自定义光标适配器简单介绍啧啧
HTTP://thinkandroid.word$p$pss.com/ 2010/01/11 /自定义cursoradapters /

0) Simple intro tut on custom cursor adapters http://thinkandroid.wordpress.com/2010/01/11/custom-cursoradapters/

1)罗曼盖伊 - 基本布局... 2 txts,1图像
http://www.curious-creature.org/ 2009年/ 02/22 / Android的布局技巧-1 /

1) Romain Guy - basic layout ... 2 txts, 1 image http://www.curious-creature.org/2009/02/22/android-layout-tricks-1/

2)AQuery(Android的查询)
HTTP://$c$c.google.com/p/android -query /维基/ ImageLoading

2) AQuery (Android Query) http://code.google.com/p/android-query/wiki/ImageLoading

3)Android的缩略图
http://developer.android.com/reference/android/media/ThumbnailUtils.html

3) Android thumbnails http://developer.android.com/reference/android/media/ThumbnailUtils.html

4)卡斯特。列表视图与开/关明星形象:
http://enjoyandroid.word$p$pss.com/2012/03/12/customizing-simple-cursor-adapter/

4) Cust. listview with an "on/off" star image: http://enjoyandroid.wordpress.com/2012/03/12/customizing-simple-cursor-adapter/

推荐答案

有两件事情可以做:

1)使用ViewHolder模式,缓存LayoutInfalter也是最重要的:不要将数据绑定两次:

1) Use the ViewHolder pattern, cache the LayoutInfalter and most important: don't bind data twice:

/* ... imports */

import static android.media.ThumbnailUtils.extractThumbnail;

public class TextAndImageCursorAdapter extends SimpleCursorAdapter { 

    private LayoutInflater mLayoutInflater;
    private Context context;
    private int layout;


    private class ViewHolder {
        TextView textView;
        ImageView imageView;

        ViewHolder(View v) {
            textView = (TextView) v.findViewById(R.id.gui_text);
            imageView = (ImageView) v.findViewById(R.id.gui_image);
        }
    }

    public TextAndImageCursorAdapter (Context ctx, int layout, Cursor c, String[] from, int[] to) {
        super(ctx, layout, c, from, to);
        this.context = ctx;
        this.layout = layout;
        mLayoutInflater = LayoutInflater.from(ctx);
    }


    @Override
    public View newView(Context ctx, Cursor cursor, ViewGroup parent) {
        View vView = mLayoutInflater.inflate(layout, parent, false);
        vView.setTag( new ViewHolder(vView) );
        // no need to bind data here. you do in later
        return vView;// **EDITED:**need to return the view
    }

    @Override
    public void bindView(View v, Context ctx, Cursor c) {
        // you might want to cache these too
        int iCol_Text = c.getColumnIndex(DBCOL_TEXT);
        int iCol_Image = c.getColumnIndex(DBCOL_IMAGE);

        String sText = c.getString(iCol_Text);
        String sFileAndPath_Image = c.getString (iCol_Image);  //// path & file

        ViewHolder vh = (ViewHolder) v.getTag();

        vh.textView.setText(sSomeText);
        vh.imageView.setImageBitmap ( mySetImage ( sFileAndPath_Image ) );
    }
}

2)这是非常重要的:不要在每一个绑定创建缩略图。你需要缓存的结果:

2) This is really important: don't create a thumbnail on every bind. you need to cache the result:

private void setThumbnail(String path, Bitmap b) {
    // save thumbnail to some kind of cache
    // see comment below
}

private Bitmap getThumbnail(String path) {
    Bitmap thumbnail = null;
    // try to fetch the thumbnail from some kind of cache
    // see comment below
    return thumbnail;
}

protected Bitmap mySetImage ( String path ) {
    int width = 60; int height = 40 ;

    Bitmap thumbnail = getThumbnail(path); // try to fetch thumbnail
    if (thumbnail != null) return thumbnail;

    File imgFile = new File ( path );  //// usually like: /sdcard/wherever/filename1234.bmp
    Bitmap myBitmap = null;

    if( imgFile.exists() ) {
            myBitmap = BitmapFactory.decodeFile ( imgFile.getAbsolutePath () );                  
    } else {
            Log.d ("oops", "no image file ... using default.");
            myBitmap = getTheDefaultImage ();  //// not shown - this is arbitrary
    }

    imgFile.close();
    thumbnail = extractThumbnail ( myBitmap, width, height );
    myBitmap.recycle();
    setThumbnail(path, thumbnail); // save thumbnail for later reuse
    return thumbnail;
}     

根据使用的情况下,要填写 getThumbnail() setThumbnail()与某种LruCache:

Depending on you use case, you want to fill getThumbnail() and setThumbnail() with some kind of LruCache:

  • There is a in memory LruCache available in the android API and in support lib: https://developer.android.com/reference/android/util/LruCache.html
  • Jake made an persistent DiskLruCache: https://github.com/JakeWharton/DiskLruCache

编辑:

  @Override
public View newView(Context ctx, Cursor cursor, ViewGroup parent) {
    View vView = mLayoutInflater.inflate(layout, parent, false);
    vView.setTag( new ViewHolder(vView) );
    // no need to bind data here. you do in later
    return vView;// **EDITED:**need to return the view
}

这篇关于具有图像的Andr​​oid定制SimpleCursorAdapter从文件与数据库路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆