Reputation: 4204
In my ImageAdapter
(extends BaseAdapter
), each View
is a custom view I called ImageTapView
. It's a separate class that extends RelativeLayout
with its own layout file that starts with a <merge>
. This class contains all the click listeners, loaders for the images that each ImageTapView
downloads and displays from the internet, as well as animations that happen on click.
Here's my ImageAdapter
constructor:
public class ImageAdapter extends BaseAdapter {
private Context context;
private JSONArray posts;
private String baseUrl;
private HashMap views = new HashMap();
public ImageAdapter(Context _context, JSONArray _posts, String _baseUrl){
context = _context;
posts = _posts;
baseUrl = _baseUrl;
}
...etc
}
In my ImageAdapter.getView
everything works fine if I do something like:
public View getView(int position, View convertView, ViewGroup parent){
// create new imageTapView
JSONObject thisPost = posts.getJSONObject(position);
convertView = new ImageTapView(context, thisPost);
return convertView;
}
But this means Android is creating a new ImageTapView
every time it calls getView
instead of just replacing the data in the already inflated view. I think it'd be way harder to go in and replace each field and reset the animations on getView
, not to mention, I'd like the user to see where in their interaction with ImageTapView
they left off (e.g. zoomed in on an image or in the middle of an animation).
I tried saving each view to a HashMap
called views
:
public View getView(int position, View convertView, ViewGroup parent){
if(views.containsKey(position)) return (ImageTapView) views.get(position);
// create new imageTapView
JSONObject thisPost = posts.getJSONObject(position);
convertView = new ImageTapView(context, thisPost);
views.put(position, convertView);
return convertView;
}
But I get some very strange behavior. ImageTapViews
that are on, say, step 2 of 3 steps of interaction (start state, zoomed state, information overlay shown state), things get really strange. They don't seem to pick up where they left off and they don't respond to clicks the proper way a fresh ImageTapView
would.
So is there a standard way of caching objects or custom objects in a ListView
? Should I be extending ArrayAdapter
instead, or would my problem be the same in the getView
function?
Thanks in advance!
Upvotes: 1
Views: 956
Reputation: 1546
try this ,you need create extra method setPost() to set post
public View getView(int position, View convertView, ViewGroup parent){
// create new imageTapView
JSONObject thisPost = posts.getJSONObject(position);
if(convertView==null)
convertView = new ImageTapView(context, thisPost);
else{
((ImageTapView)convertView).setPost(thisPost);
}
return convertView;
}
Upvotes: 2
Reputation: 24848
Try this way,hope this will help you to solve your problem.
row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<packageName.ImageTapView>
android:id="@+id/imageTapView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
</packageName.ImageTapView>
</LinearLayout>
inflate custom row layout in adapter.
public class ImageAdapter extends BaseAdapter {
private Context context;
private JSONArray posts;
private String baseUrl;
private HashMap views = new HashMap();
public ImageAdapter(Context _context, JSONArray _posts, String _baseUrl){
context = _context;
posts = _posts;
baseUrl = _baseUrl;
}
static class ViewHolder
{
ImageTapView imageTapView;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(_context).inflate(R.layout.row, null);
viewHolder.imageTapView = (ImageTapView) convertView.findViewById(R.id.imageTapView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.imageTapView.setPost(posts.getJSONObject(position));
return convertView;
}
...etc
}
Upvotes: 0