2016-04-29 20 views
0

我正在使用自定义适配器以将选定图像添加到ListView。我得到这个错误:Android应用程序 - 从手机库中选择图像并将其添加到ListView中

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) 

当从画廊添加照片时,我创建一个新的照片对象,并将给定的位图存储在那里。我的getBitmap()方法调用它,但显然在这种情况下它是空的。不知道什么不对劲这里

这里是我的代码:

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(); 
    } 
} 

Album.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; 
    } 

} 

Photo.java

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 
    } 
} 

customimageview.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <ImageView 
     android:id="@+id/imageView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

</LinearLayout> 
基于您的堆栈跟踪

回答

1

你开始使用它看起来像这条线(硬有点不知道,这其实是线240)发生错误:

thumbnail.setImageBitmap(位);

由于你的错误是一个空指针意味着缩略图为空,并且告诉我们:

ImageView的缩略图=(ImageView的)vi.findViewById(R.id.imageView1);

无法找到ImageView。因此,要正本清源,我们需要看到的XML:

R.layout.customimageview

但它很可能是存在与imageView1在那里的ID没有ImageView的。如果没有添加,则应解决空指针。 如果不是这样,那里有一个ImageView,我们将继续调查。 :)(但发布您的XML,然后还有和请确认到底是哪行240)。

编辑:

也期待您的代码你的适配器没有完全实现,你可能会以后,如果获得其他错误这是不固定的。例如getItem和getItemId方法。

的getItem或许应该是这个样子:

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

和getItemId:

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

EDIT2:

此外,虽然序列化是方便和易于它带有一些消极的方面例如Android上的速度,查找Parceble并帮助您使用boilderplate代码: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,因此失败了。

+0

我已经添加了xml。我确实有这个图像视图:/ – Laugh7

+0

好的,你可以发布xml并确认哪一行是240? :) –

+0

我已经添加了它,我可以确认第240行是那一行 – Laugh7

相关问题