私の質問の短いバージョン:各アイテムにボタンがあり、そのボタンによってそのリストアイテムのテキストビューが更新されるリストビューがある場合、getView パーマネントの onClickListener からリスト行に変更を加えるにはどうすればよいですか?
問題の詳細な説明:リストビューがあり、そのリストビューには「バンプ」ボタン (Facebook の「いいね」ボタンに相当) があり、ユーザーがこのようなボタンを押すと、3 つのことが起こります。
- 私のdbテーブルの1つにレコードを追加することにより、「バンプ」を記録するAPIに対して非同期リクエストが行われます。リクエストが成功すると、API は 2 つのフィールド ( is_bumped(boolean) と bump_count(int) ) を含むレスポンスを発行します。
- API リクエストが成功した場合は、レスポンスから BumpCount を取得し、それを使用して、リスト アイテムが「バンプ」された新しい合計回数を反映するために、bumpTv を更新します。例: 「3 バンプ」
- 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 項目の下にあるリスト項目の 1 つでバンプ ボタンを押すと、間違った位置が送信され、その位置は 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();
}
});
}
}
}