Reputation: 5887
In my fragment i want to display images selected from gallery and display them in a list view. Each list view item will consist of an ImageView for the image and an EditText for the caption. I am getting a nullpointerexception at caption.setText(mAllCaptions.get(position)) where I want to give a default caption such as Photo 1 from an ArrayList of captions named mAllCaptions. Any ideas
list_item_selected_image.xml
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/selected_imageImageView"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/selected_imageCaptionEditText"
android:background="@color/white"
android:hint="@string/add_caption"
android:textColorHint="@color/input_hint"
android:textColor="@color/dark_grey"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:padding="10dp"/>
</LinearLayout>
Inner class SelectedImagesAdapter
private class SelectedImagesAdapter extends ArrayAdapter<String>{
public SelectedImagesAdapter(ArrayList<String> imagesArray){
super(getActivity(),0,imagesArray);
for (int i = 0; i < imagesArray.size(); i++) {
int j = ++i;
String defaultCaption = "Photo " + j;
mAllCaptions.add(defaultCaption);
}
notifyDataSetChanged();
}//end constructor
@Override
public int getCount(){
return mAllCaptions.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
//if we arent given a view inflate one
//if there's no recycled view passed in inflate one
if(convertView == null)
convertView = getActivity()
.getLayoutInflater()
.inflate(R.layout.list_item_selected_image, null);
//configure the view for this image
String imagePath = getItem(position);
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
//get the screen width at run time
int screenWidth = DeviceDimensionsHelper.getDisplayWidth(getActivity());
//load resized bitmap into an ImageView
ImageView imageView = (ImageView)convertView.findViewById(R.id.selected_imageImageView);
imageView.setImageBitmap(BitmapScaler.scaleToFitWidth(bitmap, screenWidth));
EditText caption = (EditText)convertView.findViewById(R.id.selected_imageCaptionEditText);
caption.setText(mAllCaptions.get(position));
caption.setId(position);
//update adapter once we finish editing
caption.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus){
final int position = v.getId();
final EditText Caption = (EditText) v;
mAllCaptions.set(position, Caption.getText().toString());
}
}
});
return convertView;//return view object to the list view
}
}//end private class ImagesAdapter
Error Log
java.lang.NullPointerException
at com.photos.android.photos.PhotosFragment$SelectedImagesAdapter.getView(PhotosFragment.java: 278)
at android.widget.AbsListView.obtainView(AbsListView.java: 2259)
at android.widget.ListView.makeAndAddView(ListView.java: 1813)
at android.widget.ListView.fillDown(ListView.java: 688)
at android.widget.ListView.fillDown(ListView.java: 667)
at android.widget.ListView.fillFromTop(ListView.java: 759)
at android.widget.ListView.layoutChildren(ListView.java: 1666)
at android.widget.AbsListView.onLayout(AbsListView.java: 2110)
at android.view.View.layout(View.java: 13947)
at android.view.ViewGroup.layout(ViewGroup.java: 4472)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java: 1687)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java: 1545)
at android.widget.LinearLayout.onLayout(LinearLayout.java: 1450)
at android.view.View.layout(View.java: 13947)
at android.view.ViewGroup.layout(ViewGroup.java: 4472)
at android.support.v4.view.ViewPager.onLayout(ViewPager.java: 1627)
at android.view.View.layout(View.java: 13947)
at android.view.ViewGroup.layout(ViewGroup.java: 4472)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java: 1687)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java: 1545)
at android.widget.LinearLayout.onLayout(LinearLayout.java: 1450)
at android.view.View.layout(View.java: 13947)
at android.view.ViewGroup.layout(ViewGroup.java: 4472)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java: 1687)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java: 1545)
at android.widget.LinearLayout.onLayout(LinearLayout.java: 1450)
at android.view.View.layout(View.java: 13947)
at android.view.ViewGroup.layout(ViewGroup.java: 4472)
at android.widget.FrameLayout.onLayout(FrameLayout.java: 460)
at android.view.View.layout(View.java: 13947)
at android.view.ViewGroup.layout(ViewGroup.java: 4472)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java: 1687)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java: 1545)
at android.widget.LinearLayout.onLayout(LinearLayout.java: 1450)
at android.view.View.layout(View.java: 13947)
at android.view.ViewGroup.layout(ViewGroup.java: 4472)
at android.widget.FrameLayout.onLayout(FrameLayout.java: 460)
at android.view.View.layout(View.java: 13947)
at android.view.ViewGroup.layout(ViewGroup.java: 4472)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java: 1687)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java: 1545)
at android.widget.LinearLayout.onLayout(LinearLayout.java: 1450)
at android.view.View.layout(View.java: 13947)
at android.view.ViewGroup.layout(ViewGroup.java: 4472)
at android.widget.FrameLayout.onLayout(FrameLayout.java: 460)
at android.view.View.layout(View.java: 13947)
at android.view.ViewGroup.layout(ViewGroup.java: 4472)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java: 1883)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java: 1704)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java: 1011)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java: 4244)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java: 725)
at android.view.Choreographer.doCallbacks(Choreographer.java: 555)
at android.view.Choreographer.doFrame(Choreographer.java: 525)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java: 711)
at android.os.Handler.handleCallback(Handler.java: 615)
at android.os.Handler.dispatchMessage(Handler.java: 92)
at android.os.Looper.loop(Looper.java: 213)
at android.app.ActivityThread.main(ActivityThread.java: 4793)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java: 511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java: 789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 556)
at dalvik.system.NativeStart.main(Native Method)
Upvotes: 0
Views: 60
Reputation: 5887
The solution i had given earlier brought me some problems because edittext values were being interchanged on scrolling, i.e when the ListView redrwas itself, so here is the final solution with no bugs thanks to this link
//custom adapter as inner class
private class SelectedImagesAdapter extends BaseAdapter{
private LayoutInflater mInflater;
int size = 0;
public SelectedImagesAdapter() {
mInflater = (LayoutInflater)getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.size = mPhotosPathList.size();
int j = 1;
for (int i = 0; i < size; i++) {
String defaultCaption = "Photo " + j;
etStrings.add(defaultCaption);
j++;
}
}//end constructor
@Override
public int getCount() {
return size;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
//if we arent given a view inflate one
//if there's no recycled view passed in inflate one
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.list_item_selected_image, null);
holder.caption = (EditText)
convertView.findViewById(R.id.selected_imageCaptionEditText);
holder.photo = (ImageView)
convertView.findViewById(R.id.selected_imageImageView);
convertView.setTag(holder);
holder.mWatcher = new EditTextWatcher();
holder.caption.addTextChangedListener(holder.mWatcher);
}else {
holder = (ViewHolder)convertView.getTag();
}
holder.mWatcher.setActive(false);
holder.caption.setText(etStrings.get(position));
holder.mWatcher.setPosition(position);
holder.mWatcher.setActive(true);
Bitmap bitmap = BitmapFactory.decodeFile(mPhotosPathList.get(position));
//get the screen width at run time
int screenWidth = DeviceDimensionsHelper.getDisplayWidth(getActivity());
//load resized bitmap into an ImageView
holder.photo.setImageBitmap(BitmapScaler.scaleToFitWidth(bitmap, screenWidth));
return convertView;//return view object to the list view
}
}//end private class ImagesAdapter
class ViewHolder {
EditText caption;
ImageView photo;
public EditTextWatcher mWatcher;
}
class EditTextWatcher implements TextWatcher{
private int mPosition;
private boolean mActive;
void setPosition(int position){
mPosition = position;
}
void setActive(boolean active){
mActive = active;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if(mActive){
etStrings.set(mPosition, s.toString());
}
}
}
Upvotes: 1