在 onCreate 中加载图像无法正确填充适配器

Loading image in onCreate doesn't fill adapter correctly

我的应用程序能够拍照、保存并在列表中显示它们。它们也可以被删除并且列表被正确更新。 但是,如果我关闭应用程序然后再次启动它,列表将不再正确。详细:

这些是我拍摄两张照片后适配器中的列表元素:

List[0] 20150603_042556 
List[1] 20150603_042601

这些图片保存正确。但是,如果我关闭并再次打开该应用程序,则会发生以下情况:

Loaded selfie:﹕ 20150603_042556
List[0] 20150603_042556           
Loaded selfie: 20150603_042601
List[0] 20150603_042601           
List[1] 20150603_042601

这是添加函数:

public void add(SelfieRecord listItem) {
    list.add(listItem);
    for(int k=0;k<list.size();k++)
        Log.i("List: ", String.valueOf(k) + " " + list.get(k).getPicName());
    notifyDataSetChanged();
}

这是我加载保存图片的方式:

for (int ii = 0; ii < dirFiles.length; ii++) {
    File file = dirFiles[ii];
    String path = file.getAbsolutePath();
    selfie.setPic(path);
    selfie.setPicName(path.substring(path.indexOf("_") + 1, path.lastIndexOf("_")));
    Log.i(TAG+" Loaded selfie: ",path);
    mAdapter.add(selfie);
}

想不通发生了什么。

编辑:更多代码如下。

主要activity:

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

        // setup notifications
        setNotifications();

        mListView = (ListView)findViewById(R.id.selfieList);
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent intent = new Intent(MainActivity.this, ViewActivity.class);
                SelfieRecord record = (SelfieRecord) mAdapter.getItem(position);
                intent.putExtra(SELFIE_KEY, record.getPic());
                startActivity(intent);
            }
        });

        mAdapter = new SelfieAdapter(getApplicationContext());
        mListView.setAdapter(mAdapter);

        // load selfies
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) && mAdapter.getCount()==0) {
            // gets the files in the directory
            File fileDirectory = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath());
            if (!fileDirectory.exists()) {
                fileDirectory.mkdirs();
            }
            // lists all the files into an array
            File[] dirFiles = fileDirectory.listFiles();

            if (dirFiles.length != 0) {
                SelfieRecord selfie = new SelfieRecord();
                // loops through the array of files, outputing the name to console
                for (int ii = 0; ii < dirFiles.length; ii++) {
                    File file = dirFiles[ii];
                    String path = file.getAbsolutePath();
                    selfie.setPic(path);
                    selfie.setPicName(path.substring(path.indexOf("_") + 1, path.lastIndexOf("_")));
                    Log.i(TAG+" Loaded selfie: ",path);
                    mAdapter.add(selfie);
                }
            }
        }

        registerForContextMenu(mListView);

    }

在适配器中:

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

        View newView = convertView;
        ViewHolder holder;

        SelfieRecord curr = list.get(position);
        Log.i("List: ", String.valueOf(position)+" "+list.get(position).getPicName());

        if (null == convertView) {
            holder = new ViewHolder();
            newView = inflater.inflate(R.layout.list_record, parent, false);
            holder.pic = (ImageView) newView.findViewById(R.id.pic);
            holder.name = (TextView) newView.findViewById(R.id.pic_name);
            newView.setTag(holder);

        } else {
            holder = (ViewHolder) newView.getTag();
        }

        //setPic(holder.pic, curr.getPic());
        holder.name.setText(curr.getPicName());
        mImageView = holder.pic;
        new BitmapLoader().execute(curr.getPic());

        Log.i("Loader: ", String.valueOf(position) + " " + curr.getPicName());

        return newView;
    }

    static class ViewHolder {

        ImageView pic;
        TextView name;

    }

    public void add(SelfieRecord listItem) {
        list.add(listItem);
        for(int k=0;k<list.size();k++)
            Log.i("List: ", String.valueOf(k) + " " + list.get(k).getPicName());
        notifyDataSetChanged();
    }

    public void remove(int position) {
        list.remove(position);
        notifyDataSetChanged();
    }

位图加载器:

public class BitmapLoader extends AsyncTask<String,Integer,Bitmap> {

        @Override
        protected Bitmap doInBackground(String... resId) {

            // Get the dimensions of the View
            int targetW = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 160, mContext.getResources().getDisplayMetrics()));
            int targetH = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 120, mContext.getResources().getDisplayMetrics()));

            // Get the dimensions of the bitmap
            BitmapFactory.Options bmOptions = new BitmapFactory.Options();
            bmOptions.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(resId[0], bmOptions);
            int photoW = bmOptions.outWidth;
            int photoH = bmOptions.outHeight;

            // Determine how much to scale down the image
            int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

            // Decode the image file into a Bitmap sized to fill the View
            bmOptions.inJustDecodeBounds = false;
            bmOptions.inSampleSize = scaleFactor;
            bmOptions.inPurgeable = true;

            Bitmap bitmap = BitmapFactory.decodeFile(resId[0], bmOptions);

            return bitmap;

        }

        @Override
        protected void onPostExecute(Bitmap result) {
            mImageView.setImageBitmap(result);
        }

    }

我认为问题出在我将元素从存储中恢复后放入适配器时:

Loaded selfie:﹕ 20150603_042556
List[0] 20150603_042556           
Loaded selfie: 20150603_042601
List[0] 20150603_042601           
List[1] 20150603_042601

第二次调用适配器的添加方法覆盖第一个元素。为什么?

通过更改创建时的 for 循环解决:

if (dirFiles.length != 0) {
                // loops through the array of files, outputing the name to console
                for (int ii = 0; ii < dirFiles.length; ii++) {
                    File file = dirFiles[ii];
                    String path = file.getAbsolutePath();
                    SelfieRecord selfie = new SelfieRecord();
                    selfie.setPic(path);
                    selfie.setPicName(path.substring(path.indexOf("_") + 1, path.lastIndexOf("_")));
                    Log.i(TAG+" Loaded selfie: ",path);
                    mAdapter.add(selfie);
                }
            }

必须将不同的 SelfieRecord 对象传递给添加方法。