我正在使用自定义适配器将所选图像添加到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
}
}
答案 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,因此失败了。