adamwhiles adamwhiles - 12 days ago 6
Android Question

Access ArrayList from Custom Adapter

What I am trying to do is access an ArrayList that is in my main activity from a customer adapter for a listview.

I have a listview that I am making clickable, which I have done within the customer adapter(where the onclick resides). When the user clicks it they will enter a caption(text) which will update an arraylist(string) in the main activity.

I have read a few other questions about this topic but I'm lost on how to make this work.

I didn't see the need to post a code snippet because it's just a basic arraylist(string) and a custom adapter for a listview. If code is needed I can post though. Thanks!

Here part of the adapter code:

public class PhotoAdapter extends ArrayAdapter<Photo> {

private final ArrayList<Photo> objects;

public PhotoAdapter(Context context, int textViewResourceId,
ArrayList<Photo> objects) {
super(context, textViewResourceId, objects);
this.objects = objects;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Photo i = objects.get(position);
View v = convertView;

if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.listview_row, null);
v.setClickable(true);
v.setFocusable(true);
}


Here is come code from the main activity

public ArrayList<Photo> m_photos = new ArrayList<Photo>();
public ArrayList<String> m_photo_captions = new ArrayList<String>();
private PhotoAdapter m_adapter;

this.list1 = (ListView) findViewById(R.id.lstPhotos);
m_adapter = new PhotoAdapter(this, R.layout.listview_row, m_photos);
LayoutInflater infalter = getLayoutInflater();
list1.setAdapter(m_adapter);

if (Intent.ACTION_SEND_MULTIPLE.equals(action)
&& intentGallery.hasExtra(Intent.EXTRA_STREAM)) {
ArrayList<Parcelable> list = intentGallery
.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
for (Parcelable p : list) {
Uri uri = (Uri) p;
imagePath = getPath(uri);
m_photos.add(new Photo(imagePath, ""));
m_photo_locations.add(imagePath);
m_photo_captions.add("");
m_adapter.notifyDataSetChanged();
}
}


onclick listener

list1.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// Do whatever you want with m_photo_captions here
Log.v("listview", "listview item clicked");
appErrorAlert("test", "test");
}
});

Sam Sam
Answer

Now that you have posted your code, I would suggest a different approach than Mohamed A. Karim's.


You are trying to set a simple OnClickListener on the entire row in your Adapter but access members of your Activity. Why not just set an OnItemClickListener in your ListView which already has access to the List that you want?

list1.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
        // Do whatever you want with m_photo_captions here
    }
});

Next remove everything that will intercept the touch event before it reaches your ListView. You can also make your getView() a little smaller and faster, like this:

public class PhotoAdapter extends ArrayAdapter<Photo> {
    LayoutInflater mInflater;

    public PhotoAdapter(Context context, int textViewResourceId,
            ArrayList<Photo> objects) {
        super(context, textViewResourceId, objects);
        mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final Photo i = get(position);
        View v = convertView;

        if (v == null) {
            v = mInflater.inflate(R.layout.listview_row, null);
            // Initialize your ViewHolder here!
        }

        // Update your TextViews, ImageViews, etc here
        ...
    }
}

Hope that helps!