The short version of my question: If I have a listview where each item has a button and that button causes a textview on that listitem to be updated, how do I make changes I make to the list row from a onClickListener in getView permanent?
Detailed description of problem: I have a listview and that listview has a "bump" button (equivalent to a "like" button on Facebook) and when a user presses this like button 3 things happen:
- A async request is made to my api which records the "bump" by adding a record to one of my db tables. If the request is successful the api issues a response with 2 fields ( is_bumped(boolean) & bump_count(int) )
- If the api request was successful then we grab bumpCount from the response and use it to update the bumpTv to reflect the new total number of times that list item has been "bumped".... example: "3 Bumps"
- If the API request was successful and isBumped=true then we update the image resource to a version of my bump icon that looks selected/pressed.
All of this works just fine at first glance, but if you "bump" a list item and then scroll all the way to the bottom of the list and then back to the top, the list item you just bumped will no longer appear to be bumped unless you refresh the entire activity. I know this has to have something to do with the data that I bind to the adapter not being updated, but how do I go about updating without refreshing the entire update?
package com.quothor.helpers;
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
public class NewLazyAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public FragmentManager frag_manager;
static class ViewHolder {
TextView name;
TextView div3;
TextView div2;
TextView bumpTv;
TextView message;
TextView commentsTv;
SmartImageView thumb_image;
ImageButton bumpBtn;
ImageButton requestBtn;
ImageButton settingsBtn;
TextView created ;
int position;
}
public NewLazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public NewLazyAdapter(Activity a, ArrayList<HashMap<String, String>> d, FragmentManager manager) {
activity = a;
frag_manager=manager;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
HashMap<String, String> update = new HashMap<String, String>();
update = data.get(position);
if(convertView==null){
convertView = inflater.inflate(R.layout.list_row, null);
holder = new ViewHolder();
holder.name = (TextView)convertView.findViewById(R.id.name); // title
holder.div3 = (TextView)convertView.findViewById(R.id.divider3); // title
holder.div2 = (TextView)convertView.findViewById(R.id.divider2); // title
holder.bumpTv = (TextView)convertView.findViewById(R.id.bump); // title
holder.message = (TextView)convertView.findViewById(R.id.message); // artist name
holder.commentsTv = (TextView)convertView.findViewById(R.id.comments); // artist name
holder.thumb_image = (SmartImageView) convertView.findViewById(R.id.list_image);
holder.bumpBtn= (ImageButton)convertView.findViewById(R.id.bump_btn);
holder.requestBtn = (ImageButton)convertView.findViewById(R.id.hidden_btn);
holder.settingsBtn = (ImageButton)convertView.findViewById(R.id.settings_btn);
holder.created = (TextView)convertView.findViewById(R.id.created); // duration
holder.bumpBtn.setTag(holder);
holder.bumpBtn.setOnClickListener(new Bump(position, update));
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Log.i("LazyAdapter data", String.valueOf(position)+" "+update.toString());
if(update.get("bump_count") != null){
holder.bumpBtn.setVisibility(holder.bumpBtn.VISIBLE);
//holder.bumpBtn.setOnClickListener(new Bump(position, update));
String bump_count=update.get("bump_count");
String is_bumped=update.get("is_bumped");
//sets bump textview
if(bump_count.equals("0")){
}else if(bump_count.equals("1")){
holder.div3.setVisibility(holder.div3.VISIBLE);
holder.bumpTv.setVisibility(holder.bumpTv.VISIBLE);
holder.bumpBtn.setVisibility(holder.bumpBtn.VISIBLE);
holder.bumpTv.setText(bump_count+" bump");
}else{
holder.div3.setVisibility(holder.div3.VISIBLE);
holder.bumpTv.setVisibility(holder.bumpTv.VISIBLE);
holder.bumpBtn.setVisibility(holder.bumpBtn.VISIBLE);
holder.bumpTv.setText(bump_count+" bumps");
}
if(is_bumped.equals("true")){
holder.bumpBtn.setImageResource(R.drawable.quothor_thumb_blue);
//bumpBtn.setBackgroundResource(R.drawable.quothor_bump_btn_bg_black);
}else{
holder.bumpBtn.setImageResource(R.drawable.quothor_bump_icon_black);
//bumpBtn.setBackgroundResource(android.R.drawable.btn_default);
}
}
if(update.get("relationship_view")!=null){
if(update.get("uid")!=TabHostFragmentActivity.loggedin_uid){
if(update.get("relation_to_user")!=null){
holder.requestBtn.setVisibility(holder.requestBtn.VISIBLE);
String relation= update.get("relation_to_user");
if(relation.equals("Friend")){
holder.settingsBtn.setVisibility(holder.settingsBtn.VISIBLE);
holder.requestBtn.setImageResource(R.drawable.friend_btn);
}else if(relation.equals("Familiar")){
holder.settingsBtn.setVisibility(holder.settingsBtn.VISIBLE);
holder.requestBtn.setImageResource(R.drawable.familiar_btn);
}
holder.requestBtn.setOnClickListener(new myOnClickListener(position));
holder.settingsBtn.setOnClickListener(new myOnClickListener(position));
}
}
}
if(update.get("created") != null){
TextView created = (TextView)convertView.findViewById(R.id.created); // duration
String str_created=update.get("created");
long created_l = Long.parseLong(str_created);
String time_ago=TimeAgo.fromPhpTime(created_l);
created.setVisibility(convertView.VISIBLE);
created.setText(time_ago);
}
if(update.get("comment_count")!=null){
holder.div2.setVisibility(holder.div2.VISIBLE);
holder.commentsTv.setVisibility(holder.commentsTv.VISIBLE);
String comments = update.get("comment_count");
if(comments.equals("0")){
holder.commentsTv.setText("no comments");
}else if(comments.equals("1")){
holder.commentsTv.setText("1 comment");
}else{
holder.commentsTv.setText(comments+ " comments");
}
}else{
holder.commentsTv.setVisibility(holder.commentsTv.INVISIBLE);
}
// Setting all values in listview
holder.name.setText(update.get("name"));
if(update.get("message") != null){
holder.message.setText(update.get("message"));
}else{
holder.message.setVisibility(holder.message.INVISIBLE);
}
holder.thumb_image.setImageUrl(update.get("thumb_img"));
/*
name.setOnClickListener(new myOnClickListener(position));
thumb_image.setOnClickListener(new myOnClickListener(position));
*/
return convertView;
}
public class myOnClickListener implements OnClickListener{
private int position;
private String clicked_uid;
public myOnClickListener(int position){
this.position=position;
}
@Override
public void onClick(View v) {
HashMap<String, String> update = new HashMap<String, String>();
update = data.get(position);
Log.i("Update Position:", update.toString());
clicked_uid=update.get("uid");
Log.d("Clicked UID:", clicked_uid+"");
String relation= update.get("relation_to_user");
String uid = update.get("uid");
String name = update.get("name");
String thumb_img = update.get("thumb_img");
FragmentManager fm = frag_manager;
EditRelationshipDialog editRelationshipDialog = new EditRelationshipDialog().newInstance(uid,relation,name,thumb_img);
editRelationshipDialog.show(fm, "relationshipsdialog");
}
}
public class Bump implements OnClickListener{
private int position;
private String clicked_uid;
public Bump(int position, HashMap<String, String> update){
this.position=position;
}
@Override
public void onClick(View v) {
HashMap<String, String> update = new HashMap<String, String>();
update = data.get(position);
final View theview=v;
Log.i("Update Position:", update.toString());
String msg_id=update.get("msg_id");
//ViewHolder mH = (ViewHolder) theview.getTag();
// mH.message.setText("clicked");
RequestParams params = new RequestParams();
params.put("msg_id", msg_id);
params.put("loggedin_uid", TabHostFragmentActivity.loggedin_uid);
RestClient.post(TabHostFragmentActivity.token,"http://api/bump", params, new JsonHttpResponseHandler() {
@Override
public void onFailure(Throwable arg0, JSONObject arg1) {
// TODO Auto-generated method stub
super.onFailure(arg0, arg1);
Log.i("bump request failed in lazy adapter", arg1.toString());
Toast.makeText(activity.getApplicationContext(), arg1.toString() , Toast.LENGTH_LONG).show();
}
@Override
public void onSuccess(JSONObject json) {
ViewHolder mH = (ViewHolder) theview.getTag();
try {
String is_bumped=json.getString("is_bumped");
String bump_count=json.getString("bump_count");
if(bump_count != null){
if(bump_count.equals("0")){
}else if(bump_count.equals("1")){
mH.div3.setVisibility(mH.div3.VISIBLE);
mH.bumpTv.setVisibility(mH.bumpTv.VISIBLE);
mH.bumpBtn.setVisibility(mH.bumpBtn.VISIBLE);
mH.bumpTv.setText(bump_count+" bump");
}else{
mH.div3.setVisibility(mH.div3.VISIBLE);
mH.bumpTv.setVisibility(mH.bumpTv.VISIBLE);
mH.bumpBtn.setVisibility(mH.bumpBtn.VISIBLE);
mH.bumpTv.setText(bump_count+" bumps");
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
String is_bumped=json.getString("is_bumped");
if(is_bumped.equals("true")){
mH.bumpBtn.setImageResource(R.drawable.quothor_thumb_blue);
//bumpBtn.setBackgroundResource(R.drawable.quothor_bump_btn_bg_black);
}else{
mH.bumpBtn.setImageResource(R.drawable.quothor_bump_icon_black);
//bumpBtn.setBackgroundResource(android.R.drawable.btn_default);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
}
EDIT: After taking the advice in the comments i was sure my list would begin functioning the way I had intended it to , but it only opened up a whole new can of hell....now for some reason if a user clicks the "bump" button anywhere in the first 6 items it works just fine, but beyond that something weird starts happening. when a user hits the bump button on one of the list items below the first 6 items it sends the wrong position and its a position somewhere between 0 and 6 ?!?!?
package com.quothor.helpers;
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
public class NewLazyAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public FragmentManager frag_manager;
static class ViewHolder {
TextView name;
TextView div3;
TextView div2;
TextView bumpTv;
TextView message;
TextView commentsTv;
SmartImageView thumb_image;
ImageButton bumpBtn;
ImageButton requestBtn;
ImageButton settingsBtn;
TextView created ;
int position;
}
public NewLazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public NewLazyAdapter(Activity a, ArrayList<HashMap<String, String>> d, FragmentManager manager) {
activity = a;
frag_manager=manager;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
HashMap<String, String> update = new HashMap<String, String>();
update = data.get(position);
Log.i("position being scrolled over", String.valueOf(position));
if(convertView==null){
convertView = inflater.inflate(R.layout.list_row, null);
holder = new ViewHolder();
holder.name = (TextView)convertView.findViewById(R.id.name); // title
holder.div3 = (TextView)convertView.findViewById(R.id.divider3); // title
holder.div2 = (TextView)convertView.findViewById(R.id.divider2); // title
holder.bumpTv = (TextView)convertView.findViewById(R.id.bump); // title
holder.message = (TextView)convertView.findViewById(R.id.message); // artist name
holder.commentsTv = (TextView)convertView.findViewById(R.id.comments); // artist name
holder.thumb_image = (SmartImageView) convertView.findViewById(R.id.list_image);
holder.bumpBtn= (ImageButton)convertView.findViewById(R.id.bump_btn);
holder.requestBtn = (ImageButton)convertView.findViewById(R.id.hidden_btn);
holder.settingsBtn = (ImageButton)convertView.findViewById(R.id.settings_btn);
holder.created = (TextView)convertView.findViewById(R.id.created); // duration
holder.bumpBtn.setTag(holder);
holder.bumpBtn.setOnClickListener(new Bump(position, update));
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Log.i("LazyAdapter data", String.valueOf(position)+" "+update.toString());
if(update.get("bump_count") != null){
holder.bumpBtn.setVisibility(holder.bumpBtn.VISIBLE);
//holder.bumpBtn.setOnClickListener(new Bump(position, update));
String bump_count=update.get("bump_count");
String is_bumped=update.get("is_bumped");
//sets bump textview
if(bump_count.equals("0")){
}else if(bump_count.equals("1")){
holder.div3.setVisibility(holder.div3.VISIBLE);
holder.bumpTv.setVisibility(holder.bumpTv.VISIBLE);
holder.bumpBtn.setVisibility(holder.bumpBtn.VISIBLE);
holder.bumpTv.setText(bump_count+" bump");
}else{
holder.div3.setVisibility(holder.div3.VISIBLE);
holder.bumpTv.setVisibility(holder.bumpTv.VISIBLE);
holder.bumpBtn.setVisibility(holder.bumpBtn.VISIBLE);
holder.bumpTv.setText(bump_count+" bumps");
}
if(is_bumped.equals("true")){
holder.bumpBtn.setImageResource(R.drawable.quothor_thumb_blue);
//bumpBtn.setBackgroundResource(R.drawable.quothor_bump_btn_bg_black);
}else{
holder.bumpBtn.setImageResource(R.drawable.quothor_bump_icon_black);
//bumpBtn.setBackgroundResource(android.R.drawable.btn_default);
}
}
if(update.get("relationship_view")!=null){
if(update.get("uid")!=TabHostFragmentActivity.loggedin_uid){
if(update.get("relation_to_user")!=null){
holder.requestBtn.setVisibility(holder.requestBtn.VISIBLE);
String relation= update.get("relation_to_user");
if(relation.equals("Friend")){
holder.settingsBtn.setVisibility(holder.settingsBtn.VISIBLE);
holder.requestBtn.setImageResource(R.drawable.friend_btn);
}else if(relation.equals("Familiar")){
holder.settingsBtn.setVisibility(holder.settingsBtn.VISIBLE);
holder.requestBtn.setImageResource(R.drawable.familiar_btn);
}
holder.requestBtn.setOnClickListener(new myOnClickListener(position));
holder.settingsBtn.setOnClickListener(new myOnClickListener(position));
}
}
}
if(update.get("created") != null){
TextView created = (TextView)convertView.findViewById(R.id.created); // duration
String str_created=update.get("created");
long created_l = Long.parseLong(str_created);
String time_ago=TimeAgo.fromPhpTime(created_l);
created.setVisibility(convertView.VISIBLE);
created.setText(time_ago);
}
if(update.get("comment_count")!=null){
holder.div2.setVisibility(holder.div2.VISIBLE);
holder.commentsTv.setVisibility(holder.commentsTv.VISIBLE);
String comments = update.get("comment_count");
if(comments.equals("0")){
holder.commentsTv.setText("no comments");
}else if(comments.equals("1")){
holder.commentsTv.setText("1 comment");
}else{
holder.commentsTv.setText(comments+ " comments");
}
}else{
holder.commentsTv.setVisibility(holder.commentsTv.INVISIBLE);
}
// Setting all values in listview
holder.name.setText(update.get("msg_id"));
if(update.get("message") != null){
holder.message.setText(update.get("message"));
}else{
holder.message.setVisibility(holder.message.INVISIBLE);
}
holder.thumb_image.setImageUrl(update.get("thumb_img"));
/*
name.setOnClickListener(new myOnClickListener(position));
thumb_image.setOnClickListener(new myOnClickListener(position));
*/
return convertView;
}
public class myOnClickListener implements OnClickListener{
private int position;
private String clicked_uid;
public myOnClickListener(int position){
this.position=position;
}
@Override
public void onClick(View v) {
HashMap<String, String> update = new HashMap<String, String>();
update = data.get(position);
Log.i("Update Position:", update.toString());
clicked_uid=update.get("uid");
Log.d("Clicked UID:", clicked_uid+"");
String relation= update.get("relation_to_user");
String uid = update.get("uid");
String name = update.get("name");
String thumb_img = update.get("thumb_img");
FragmentManager fm = frag_manager;
EditRelationshipDialog editRelationshipDialog = new EditRelationshipDialog().newInstance(uid,relation,name,thumb_img);
editRelationshipDialog.show(fm, "relationshipsdialog");
}
}
public class Bump implements OnClickListener{
private int position;
private String clicked_uid;
public Bump(int position, HashMap<String, String> update){
this.position=position;
}
@Override
public void onClick(View v) {
HashMap<String, String> update = new HashMap<String, String>();
update = data.get(position);
final View theview=v;
Log.i("POSITION BEING CLICKED",String.valueOf(position));
Log.i("Update Position:", update.toString());
String msg_id=update.get("msg_id");
Log.i("msg_id",msg_id);
//ViewHolder mH = (ViewHolder) theview.getTag();
// mH.message.setText("clicked");
RequestParams params = new RequestParams();
params.put("msg_id", msg_id);
params.put("loggedin_uid", TabHostFragmentActivity.loggedin_uid);
RestClient.post(TabHostFragmentActivity.token,"http://api/content/bump", params, new JsonHttpResponseHandler() {
@Override
public void onFailure(Throwable arg0, JSONObject arg1) {
// TODO Auto-generated method stub
super.onFailure(arg0, arg1);
Log.i("bump request failed in lazy adapter", arg1.toString());
Toast.makeText(activity.getApplicationContext(), arg1.toString() , Toast.LENGTH_LONG).show();
}
@Override
public void onSuccess(JSONObject json) {
ViewHolder mH = (ViewHolder) theview.getTag();
HashMap<String, String> latestUpdate = new HashMap<String, String>();
latestUpdate = data.get(position);
Log.i("list item being edited", latestUpdate.toString());
try {
String bump_count=json.getString("bump_count");
if(bump_count != null){
latestUpdate.put("bump_count", bump_count);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
String is_bumped=json.getString("is_bumped");
latestUpdate.put("is_bumped", is_bumped);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
data.remove(position);
data.add(position, latestUpdate);
notifyDataSetChanged();
}
});
}
}
}