Android应用程序 - 从手机图库中选择图像并将其添加到ListView

时间:2016-04-29 22:18:30

标签: android image listview android-imageview

我正在使用自定义适配器将所选图像添加到ListView。我收到这个错误:

$config['uri_protocol'] = 'REQUEST_URI';
config['enable_query_strings'] = FALSE;

当从图库中添加照片时,我创建了一个新的Photo对象并将给定的Bitmap存储在那里。我的getBitmap()方法调用了它,但显然在这种情况下它是null。不知道这里有什么问题

这是我的代码:

 04-29 18:15:33.582: E/AndroidRuntime(24214): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageBitmap(android.graphics.Bitmap)' on a null object reference
04-29 18:15:33.582: E/AndroidRuntime(24214):    at app.photoexpress.ViewAlbumActivity$ImageAdapter.getView(ViewAlbumActivity.java:240)

Album.java:

public class ViewAlbumActivity extends AppCompatActivity {
    ListView listview;
    ImageAdapter adapter;
    CharSequence[] images;
    int width = 250;
    boolean isSearch = false;
    // ArrayList<String> listItems = new ArrayList<String>();
    TextView title;
    Album album;
    ArrayList<Album> albumList;
    String albumName = "Album";
    Album currentlySelectedAlbum;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);
        // get bundle
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
            albumList = (ArrayList<Album>) bundle.getSerializable("albums");
            albumName = bundle.getString("albumName");
            album = Album.findAlbum(albumName, getBaseContext());
            Log.e(".", album.getName());
            setTitle(albumName);
        } else {
            album = new Album("placeholder");
        }

        currentlySelectedAlbum = Album.findAlbum(albumName, getBaseContext());
        ArrayList<Photo> photoList = currentlySelectedAlbum.getPhotos();

        // Displays the icon and album name in the action bar
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setLogo(R.drawable.ic_launcher);
        getSupportActionBar().setDisplayUseLogoEnabled(true);

        listview = (ListView) findViewById(R.id.listView1);
        adapter = new ImageAdapter(this, photoList);

        listview.setAdapter(adapter);
        // images = readPhotoList();

        // Display display = this.getWindowManager().getDefaultDisplay();
        // width = display.getWidth();
        // width=width/2-15;

        /*listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                Intent intent = new Intent(ViewAlbumActivity.this, ViewPhotoActivity.class);
                // intent.putExtra(name, value)
                intent.putExtra("index", position);
                intent.putExtra("albumname", albumName);
                intent.putExtra("album", album);
                intent.putExtra("isSearch", isSearch);
                startActivity(intent);
            }
        });*/
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        if (!isSearch) {
            getMenuInflater().inflate(R.menu.viewalbum, menu);

        }
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        if (!isSearch) {
            int id = item.getItemId();
            if (id == R.id.addPhoto) {
                Intent intent = new Intent(Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, 1);

                // addPhoto();
                return true;
            }
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            Uri targetUri = data.getData();
            // textTargetUri.setText(targetUri.toString());
            Bitmap bitmap;
            try {
                bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri));
                //image.setImageBitmap(bitmap);
                Photo photo = new Photo(bitmap);
                currentlySelectedAlbum.addPhoto(photo);
                Album.updateAlbumList(currentlySelectedAlbum, getBaseContext());
                adapter.notifyDataSetChanged();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /*
     * private String[] readPhotoList() { String path =
     * Environment.getExternalStorageDirectory().getAbsolutePath() + "/photos/";
     * 
     * File dir = new File(path);
     * 
     * File[] filelist = dir.listFiles();
     * 
     * if (filelist == null) { String[] z = new String[1]; z[0] = "no file in "
     * + path; return z; }
     * 
     * if (filelist.length == 0) { String[] s = new String[1]; s[0] =
     * "no image file under " + path; return s; } ArrayList<String> result = new
     * ArrayList<String>(); for (int i = 0; i < filelist.length; i++) { if
     * (BitmapFactory.decodeFile(path + filelist[i].getName()) != null) {
     * result.add(filelist[i].getName()); } } String[] convertList = new
     * String[result.size()]; for (int i = 0; i < result.size(); i++) {
     * convertList[i] = result.get(i); } return convertList;
     * 
     * }
     */

    /////////////

    class ImageAdapter extends BaseAdapter {
        private Context mContext;

        public ArrayList<Photo> photoList2;

        public ImageAdapter(Context c, ArrayList<Photo> photoList) {
            mContext = c;
            this.photoList2 = photoList;
        }

        public int getCount() {
            int returnInt = 0;
            try {
                returnInt = currentlySelectedAlbum.getPhotos().size();
            } catch (NullPointerException e) {
                Log.e("NullPointerError", ".");
            }
            return returnInt;
        }

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

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

        // create a new ImageView for each item referenced by the Adapter
        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView imageView = new ImageView(mContext);

            View vi = convertView;
            // String fileName="";
            if (convertView == null) {
                /*imageView = new ImageView(mContext);
                imageView.setLayoutParams(new ListView.LayoutParams(width, width));
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageView.setPadding(0, 0, 0, 0);*/
                LayoutInflater inflator = (LayoutInflater)ViewAlbumActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                vi  = inflator.inflate(R.layout.customimageview, parent, false);

            } /*else {
                imageView = (ImageView) convertView;
            }
            // if there is any photo
            if (album.getPhotos().size() != 0) {
                // final String fileName =
                // album.getPhotos().get(position).getName();
                // showImgFromSD("/photos/" + fileName, imageView);
                // showImgFromSD("/photos/002.jpg",imageView);
            }*/

            Bitmap bitmap = photoList2.get(position).getBitmap();
            ImageView thumbnail = (ImageView)vi.findViewById(R.id.imageView1);
            thumbnail.setImageBitmap(bitmap);
            return imageView;

        }

        /*
         * private void showImgFromSD(String fileName, ImageView iv) { File f =
         * new File(Environment.getExternalStorageDirectory(), fileName);
         * FileInputStream input = null;
         * 
         * try { input = new FileInputStream(f); } catch (FileNotFoundException
         * e) { // toastMsg("File: " + fileName + " not found"); return; }
         * Bitmap pic = BitmapFactory.decodeStream(input, null, null);
         * iv.setImageBitmap(pic);
         * 
         * }
         */
    }

    /*
     * private void addPhoto() { final CharSequence[] options = images;
     * AlertDialog.Builder build = new
     * AlertDialog.Builder(ViewAlbumActivity.this);
     * build.setTitle("../sdcard/photos/"); build.setItems(options, new
     * DialogInterface.OnClickListener() { public void onClick(DialogInterface
     * dialog, int item) { Album tempAlbum = findAlbum(albumName, albumList);
     * Album allPhotos = findAlbum("All Photos", albumList); List<Photo> Photos
     * = tempAlbum.getPhotos();
     * 
     * for (Photo p : Photos) { //if (p.getName().compareToIgnoreCase((String)
     * options[item]) == 0) { toastMsg(options[item] + " already in album");
     * return; } } //Photo tempPhoto = new Photo((String) options[item], "");
     * tempAlbum.addPhoto(tempPhoto); allPhotos.addPhoto(tempPhoto);
     * 
     * // SERIALIZE HERE
     * 
     * // listItems.add((String) options[item]); adapter.notifyDataSetChanged();
     * listview.invalidateViews(); toastMsg(options[item] + " added.");
     * 
     * } }); AlertDialog alert = build.create(); alert.show(); }
     */

    // handles pop up messages
    private void toastMsg(String msg) {
        Context context = getApplicationContext();
        CharSequence text = msg;
        int duration = Toast.LENGTH_LONG;
        Toast toast = Toast.makeText(context, text, duration);
        toast.show();
    }
}

Photo.java

public class Album implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -7593044560206879666L;
    String name;
    static ArrayList<Photo> photos;
    boolean previouslySelected = false;

    public Album() {
        photos = new ArrayList<Photo>();
    }

    public Album(String name) {
        this.name = name;
        photos = new ArrayList<Photo>();
    }

    public String toString() {
        return name;
    }

    public String getName() {
        return name;
    }

    public static ArrayList<Album> deleteAlbum(int position, Context context) {

        ArrayList<Album> albumList = new ArrayList<Album>();
        albumList = SerializableManager.readSerializable(context, "albumList.ser");

        albumList.remove(albumList.get(position));
        return albumList;

    }

    public static ArrayList<Album> addAlbum(Album a, Context context) {

        ArrayList<Album> albumList = new ArrayList<Album>();
        albumList = SerializableManager.readSerializable(context, "albumList.ser");

        for (Album i : albumList) {
            if (i.getName().equalsIgnoreCase(a.getName())) {
                Log.e("Not Added", "Album not added because it already exists.");
                CreateNewAlbumActivity.toastMsg("Not added. Album already exists.");
                return albumList;
            }
        }
        albumList.add(a);

        return albumList;

    }

    public static void updateAlbumList(Album a, Context context){

        ArrayList<Album> albumList = SerializableManager.readSerializable(context, "albumList.ser");

        for (int i = 0; i < albumList.size(); i++){
            if (albumList.get(i).getName().equals(a.getName())){
                albumList.remove(i);
                albumList.add(a);
            }
        }

        SerializableManager.saveSerializable(context, albumList, "albumList.ser");

    }

    public static boolean doesAlbumExist(String name, Context context) {

        ArrayList<Album> albumList = SerializableManager.readSerializable(context, "albumList.ser");
        for (Album i : albumList) {
            if (i.getName().equalsIgnoreCase(name)) {
                return true;
            }
        }

        return false;

    }

    public static Album findAlbum(String name, Context context) {

        ArrayList<Album> albumList = SerializableManager.readSerializable(context, "albumList.ser");
        for (Album i : albumList) {
            if (i.getName().equalsIgnoreCase(name)) {
                return i;
            }
        }

        return null;

    }

    public static ArrayList<Album> renameAlbum(String oldName, String newName, Context context) {

        ArrayList<Album> albumList = new ArrayList<Album>();
        albumList = SerializableManager.readSerializable(context, "albumList.ser");

        for (Album i : albumList) {
            if (i.getName().equalsIgnoreCase(oldName)) {
                Log.e(".", "match found");
                if (!doesAlbumExist(newName, context)) {
                    i.rename(newName);
                }
            }
        }

        return albumList;

    }

    public void rename(String newName) {
        this.name = newName;
    }

    public ArrayList<Photo> getPhotos() {
        return photos;
    }

    public void addPhoto(Photo p) {
        photos.add(p);
        return;
    }

}

customimageview.xml

public class Photo implements Serializable{

    // The Constant storeDir.
    public static final String storeDir = "data\\photo";
    int id;
    String Caption;
    Bitmap bitmap;
    List<Tag> Tags = new ArrayList <Tag>();

    public Photo(Bitmap bitmap) {
    id = 1 + (int)(Math.random() * 5000); 
    this.bitmap = bitmap;
    }

    public  Photo(String caption, Bitmap bitmap) {
        Caption = caption;
        id = 1 + (int)(Math.random() * 5000); 

        this.bitmap = bitmap;
    }


    public void setCaption(String input)
    {
        Caption = input;
    }

    public boolean hasTag( String type, String value)
    {
        for(Tag s: Tags )
        {
            if(s.Type.compareToIgnoreCase(type) == 0 && s.value.compareToIgnoreCase(value) == 0 )
            {
                return true;
            }
        }
        return false;
    }

    public boolean addTag( String type, String value)
    {

        //if tag already there error
        if(!hasTag(type,value))
        {
            Tags.add(new Tag(value,type));
            return true;
        }
        else
            return false;
    }

    public boolean deleteTag( String type, String value)
    {
        int count = 0;
        for(Tag s: Tags )
        {
            if(s.Type.compareToIgnoreCase(type) == 0 && s.value.compareToIgnoreCase(value) == 0 )
            {
                Tags.remove(count);
                return true;
            }
            count++;
        }
        return false;           
    }

    @Override
    public String toString()
    {
        return "no";
    }

    public List<Tag> getTags()
    {
        return Tags;
    }


    public String getCaption()
    {
        return Caption;
    }


    public Bitmap getBitmap(){
        return bitmap;
    }
    @Override
    public boolean equals(Object o)
    {
        if (o==null)
        {
            return false;
        }
        if(!(o instanceof Photo)) {return false;}
        Photo other = (Photo)o;
        return (true);

        //FIX THIS
    }
}

1 个答案:

答案 0 :(得分:1)

基于你的堆栈跟踪你开始看起来就像这行发生了错误(有点难以知道这实际上是240行):

thumbnail.setImageBitmap(位图);

由于您的错误是NullPointer,这意味着缩略图为空,并告诉我们:

ImageView thumbnail =(ImageView)vi.findViewById(R.id.imageView1);

无法找到ImageView。所以要到达root,我们需要看到xml:

R.layout.customimageview

但似乎没有带有imageView1 ID的imageView。如果没有添加,则应解决nullpointer。 如果不是这种情况,并且有一个ImageView,我们将继续调查。 :)(但是也要发布你的xml,请确认确切的240行。)

编辑:

同时查看代码,您的适配器未完全实现,如果不修复,您可能会在以后遇到其他错误。例如,方法getItem和getItemId。

getItem应该看起来像这样:

  public Object getItem(int position) {
      return photolist2.get(position);
  }

和getItemId:

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

EDIT2:

此外,虽然Serializable非常方便,但它确实带来了一些消极方面,例如Android上的速度,查找Parceble并帮助您使用borierplate代码可能会很好:https://github.com/johncarl81/parceler。但那是以后的事情;)

编辑3:

查看适配器代码,它包含一些错误,这应该更接近您想要的内容:

类ImageAdapter扩展BaseAdapter {         private Context mContext;

    public ArrayList<Photo> photoList2;

    public ImageAdapter(Context c, ArrayList<Photo> photoList) {
        mContext = c;
        this.photoList2 = photoList;
    }

    public int getCount() {
        int returnInt = 0;
        try {
            returnInt = currentlySelectedAlbum.getPhotos().size();
        } catch (NullPointerException e) {
            Log.e("NullPointerError", ".");
        }
        return returnInt;
    }

    public Object getItem(int position) {
        return photoList2.get(position);
    }

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

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        View vi;

        // String fileName="";
        if (convertView == null) {
            /*imageView = new ImageView(mContext);
            imageView.setLayoutParams(new ListView.LayoutParams(width, width));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(0, 0, 0, 0);*/
            LayoutInflater inflator = (LayoutInflater)ViewAlbumActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            vi  = inflator.inflate(R.layout.customimageview, parent, false);

        } else {
           vi = convertView;
        }

        Bitmap bitmap = photoList2.get(position).getBitmap();
        ImageView thumbnail = (ImageView)vi.findViewById(R.id.imageView1);
        thumbnail.setImageBitmap(bitmap);
        return vi;
    }

那么区别是什么?在适配器中,您在顶部创建和ImageView,并在最后返回该视图。因此,当Android使用convertView再次调用getView时,convertView现在保存ImageView对象,而不是您创建的customimageview视图。所以当调用vi.findViewByid时,它试图在ImageView中找到一个ImageView,因此失败了。