我的问题的简短版本:如果我有一个列表视图,其中每个项目都有一个按钮,并且该按钮导致该列表项上的文本视图被更新,我如何从 getView 中的 onClickListener 对列表行进行更改?
问题的详细描述:我有一个列表视图,该列表视图有一个“bump”按钮(相当于 Facebook 上的“like”按钮),当用户按下这个 like 按钮时,会发生 3 件事:
- 向我的 api 发出了一个异步请求,该请求通过向我的一个数据库表中添加一条记录来记录“碰撞”。如果请求成功,api 会发出一个包含 2 个字段的响应( is_bumped(boolean) & bump_count(int) )
- 如果 api 请求成功,那么我们从响应中获取 bumpCount 并使用它来更新 bumpTv 以反映该列表项被“碰撞”的新总次数......示例:“3 Bumps”
- 如果 API 请求成功并且 isBumped=true,那么我们将图像资源更新为我的凹凸图标的版本,该版本看起来被选中/按下。
所有这些乍一看都很好,但是如果您“碰撞”一个列表项,然后一直滚动到列表底部,然后又回到顶部,那么您刚刚碰撞的列表项将不再显示为除非你刷新整个活动。我知道这与我绑定到未更新的适配器的数据有关,但是如何在不刷新整个更新的情况下进行更新呢?
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();
}
}
});
}
}
}
编辑:在接受了评论中的建议后,我确信我的列表会按照我的预期开始运作,但它只会打开一个全新的地狱......现在由于某种原因,如果用户点击“前 6 个项目中的任何地方的“碰撞”按钮都可以正常工作,但除此之外,一些奇怪的事情开始发生。当用户点击前 6 个项目下方的列表项目之一上的碰撞按钮时,它会发送错误的位置,并且它的位置介于 0 和 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();
}
});
}
}
}