1

我有两个问题:

  1. 在gridview中显示图像之前的延迟很长:15s!!!我不知道如何解决这个问题。

  2. 当在 gridview 中加载图像并且我尝试向下(或向上)滚动以查看其余图像时,手机需要很长时间才能显示它们。此外,如果我滚动得非常快,应用程序就会停止。

备注:e var 用于为每次跳转 +1 的背景赋予不同的颜色(绿色/蓝色/绿色....)

在此先感谢,这里是代码:

代码:res/layout/main_activity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >



     <GridView
    android:id="@+id/PhoneImageGrid"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:columnWidth="90dp"
    android:gravity="center"
    android:horizontalSpacing="10dp"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="5dp" />



</RelativeLayout>

代码:MainActivity.java

public class MainActivity extends Activity {

    private int count;
    private Bitmap[] thumbnails;
    private boolean[] thumbnailsselection;
    private String[] arrPath;
    private ImageAdapter imageAdapter;
    ArrayList<String> f = new ArrayList<String>();// list of file paths
     int e=0; // To change the background color 
    String[] Files;
    ImageView selection;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // get images paths and store them in f
            getFromSdcard();

           GridView imagegrid = (GridView) findViewById(R.id.PhoneImageGrid);

            imagegrid.setAdapter(new ImageAdapter(this));

    }

    /*GET images paths */
    public void getFromSdcard()
    {

        File file=  new File("mnt/sdcard/DCIM/100ANDRO");

            if (file.exists())
            {
                Files = file.list();

                for (int i = 0; i < Files.length; i++)
                {
                    f.add(file.getAbsolutePath() + File.separator + Files[i]);
              }

            }

    }


    public class ImageAdapter extends BaseAdapter {

        Context ctxt;

        public ImageAdapter(Context c) {

                this.ctxt=c;
                }

        public int getCount() {
            return f.size();
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }


        public void setColorType(){
            if(e==0)
                e= 1;
            else{e= 0;}

        }
        public View getView(int position, View convertView, ViewGroup parent) {


            ImageView c;

            if (convertView == null) {
                c= new ImageView(ctxt);

                //Bitmap myBitmap = BitmapFactory.decodeFile(f.get(position));// Files[position]
                c.setLayoutParams(new GridView.LayoutParams(80,80));
                c.setScaleType(ScaleType.CENTER_CROP);
                c.setPadding(8,8,8,8);

                if(e==0){
                     c.setBackgroundColor( -65536);
                     setColorType();
                    }
                else{
                    setColorType();
                    c.setBackgroundColor( -16711936);
                }

            }
            else {
                c= (ImageView) convertView;

                if(e==0){
                     c.setBackgroundColor( 00000);
                     setColorType();
                    }

            }

            Bitmap myBitmap = decodeFile(new File(f.get(position)));
            c.setImageBitmap(myBitmap);

            return c;
        }


    }



// To solve the issue of uploading image and avoid error ** Out of memory   

    private Bitmap decodeFile(File f){
        try {
            //Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);

            //The new size we want to scale to
            final int REQUIRED_SIZE=70;

            //Find the correct scale value. It should be the power of 2.
            int scale=1;
            while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
                scale*=2;

            //Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;


            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {}
        return null;
    }


}
4

3 回答 3

4

替换这些行

Bitmap myBitmap = decodeFile(new File(f.get(position)));
c.setImageBitmap(myBitmap);

if(c.getTag() != null) {
    ((ImageGetter) c.getTag()).cancel(true);
}
ImageGetter task = new ImageGetter(c) ;
task.execute(new File(f.get(position)));
c.setTag(task);

并创建在后台获取图像的此类ImageGetter

public class ImageGetter extends AsyncTask<File, Void, Bitmap> {
    private ImageView iv;
    public ImageGetter(ImageView v) {
        iv = v;
    }
    @Override
    protected Bitmap doInBackground(File... params) {
        return decodeFile(params[0]);
    }
    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        iv.setImageBitmap(result);
    }
}
于 2013-10-10T10:43:38.050 回答
1

我可能是错的,但我认为如果你在线程中完成所有加载部分,它会更快、更可扩展。在适配器中,每个图像都将在线程中加载(例如,在加载时,您可以在 gridview 单元格中显示进度条)。线程完成后,您只需将网格视图单元格与图像内容交换。当然,用户可以比线程加载图像更快地滑动网格视图,因此您必须将线程附加到单元格并确保只有一个线程适用于一个单元格,这样它们就不会相互交换工作结果。

于 2013-10-10T10:45:22.027 回答
0

用下面的代码替换你的代码

public class MainActivity extends Activity {

private int count;
private Bitmap[] thumbnails;
private boolean[] thumbnailsselection;
private String[] arrPath;
private ImageAdapter imageAdapter;
ArrayList<String> f = new ArrayList<String>();// list of file paths
 int e=0; // To change the background color 
String[] Files;
ImageView selection;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // get images paths and store them in f
        getFromSdcard();

       GridView imagegrid = (GridView) findViewById(R.id.PhoneImageGrid);

        imagegrid.setAdapter(new ImageAdapter(this));

}

/*GET images paths */
public void getFromSdcard()
{

    File file=  new File("mnt/sdcard/DCIM/100ANDRO");

        if (file.exists())
        {
            Files = file.list();

            for (int i = 0; i < Files.length; i++)
            {
                f.add(file.getAbsolutePath() + File.separator + Files[i]);
          }

        }

}


public class ImageAdapter extends BaseAdapter {

    Context ctxt;

    public ImageAdapter(Context c) {

            this.ctxt=c;
            }

    public int getCount() {
        return f.size();
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }


    public void setColorType(){
        if(e==0)
            e= 1;
        else{e= 0;}

    }
    public View getView(int position, View convertView, ViewGroup parent) {


        ImageView c;

        if (convertView == null) {
            c= new ImageView(ctxt);

            //Bitmap myBitmap = BitmapFactory.decodeFile(f.get(position));// Files[position]
            c.setLayoutParams(new GridView.LayoutParams(80,80));
            c.setScaleType(ScaleType.CENTER_CROP);
            c.setPadding(8,8,8,8);

            if(e==0){
                 c.setBackgroundColor( -65536);
                 setColorType();
                }
            else{
                setColorType();
                c.setBackgroundColor( -16711936);
            }

        }
        else {
            c= (ImageView) convertView;

            if(e==0){
                 c.setBackgroundColor( 00000);
                 setColorType();
                }

        }

        Bitmap myBitmap = decodeFile(new File(f.get(position)));
        c.setImageBitmap(myBitmap);

        return c;
    }


}

// 解决上传图片的问题,避免报错 ** Out of memory

private Bitmap decodeFile(File f){
    try {
        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inSampleSize = 4;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

        //The new size we want to scale to
        final int REQUIRED_SIZE=70;

        //Find the correct scale value. It should be the power of 2.
        int scale=1;
        while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
            scale*=2;

        //Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = 4;


        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}

}

Just changed  o2.inSampleSize = 4; and  o.inSampleSize = 4;

还要更改以下代码

    BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 4;
        Bitmap myBitmap=BitmapFactory.decodeFile(new File(f.get(position), options);
Bitmap myBitmap2=Bitmap.createScaledBitmap(myBitmap, 100, 100, true);
                                c.setImageBitmap(myBitmap2);

通过更换Bitmap myBitmap = decodeFile(new File(f.get(position))); c.setImageBitmap(myBitmap);

于 2013-10-10T10:46:13.507 回答