无法让自定义适配器中的 onClickButton 正确响应?
Cannot get onClickButton in custom adapter to respond correctly?
我试图在列表视图中单击按钮时更改按钮的文本,我尝试通过自定义适配器来完成。对于日志,调用 onclick 只是文本似乎没有改变:
这是我的适配器代码:
public class UserViewerAdapter extends BaseAdapter {
public List<DatabaseUser> _list;
public List<UserResponse> _listForSearch;
private final Activity mContext;
private ConfirmManager confirmManager;
private int query;
private Button isFriend;
// database helper
private DatabaseHelper db;
private static LayoutInflater inflater = null;
public UserViewerAdapter(Activity context, List<DatabaseUser> list) {
mContext = context;
_list = list;
//establishing db
db = new DatabaseHelper(mContext);
confirmManager = new ConfirmManager();
query = 0;
}
public UserViewerAdapter( List<UserResponse> list, Activity context) {
mContext = context;
_listForSearch = list;
query = 1;
//establishing db
db = new DatabaseHelper(mContext);
confirmManager = new ConfirmManager();
}
@Override
public int getCount() {
if(query == 0) {
return _list.size();
}
return _listForSearch.size();
}
@Override
public Object getItem(int position) {
if(query == 0) {
return _list.get(position);
}
return _listForSearch.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = mContext.getLayoutInflater();
v = inflater.inflate(R.layout.users_layout, null);
}
ImageView userImage = (ImageView) v.findViewById(R.id.userImage);
TextView text = (TextView) v.findViewById(R.id.label);
isFriend = (Button) v.findViewById(R.id.btnFriend);
String isFriendText;
//coming from search
if(query == 1) {
if (_listForSearch != null && _listForSearch.size() > 0) {
text.setText(_listForSearch.get(position).getName());
}
Picasso.with(mContext).setLoggingEnabled(true);
// String pictureToAdd = Constants.USER_IMAGES + _listForSearch.get(position).getPicId();
// String photo = _listForSearch.get(position).get_picture();
// Log.d(Constants.DEBUG, "THE photo IS " + photo);
// Log.d(Constants.DEBUG, "THE constant IS " + Constants.USER_IMAGES);
// if (photo.equals("default.jpg")) {
Picasso.with(mContext).load(R.drawable.default_profile_image).resize(50, 50).into(userImage);
isFriendText = "Add Friend";
if(_listForSearch.get(position).isFriend()) {
isFriendText = "Remove Friend";
}
isFriend.setText(isFriendText);
final String finalIsFriendText = isFriendText;
isFriend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Remove friend
callConfirmAddOrRemove(_listForSearch.get(position), finalIsFriendText);
Log.d(Constants.DEBUG, "clicked friend button " + finalIsFriendText);
}
});
}
return v;
}
private void changeText(String finalIsFriendText) {
String newTextToFill = "";
if(finalIsFriendText.equals("Remove Friend")) {
newTextToFill = "Add Friend";
}
if(finalIsFriendText.equals("Add Friend")) {
newTextToFill = "Remove Friend";
}
Log.d(Constants.DEBUG, "changing text of friend button " + newTextToFill);
isFriend.setText(newTextToFill);
notifyDataSetChanged();
}
private void callConfirmAddOrRemove(UserResponse userResponse, String finalIsFriendText) {
boolean dlg = confirmManager.Confirm(mContext, mContext.getString(R.string.remove_friend), mContext.getString(R.string.details_confirmation)
+ "\n" + mContext.getString(R.string.details_info),
mContext.getString(R.string.submit), mContext.getString(R.string.cancel), addOrRemove(userResponse, finalIsFriendText),
cancelPost());
}
private Runnable addOrRemove(final UserResponse userResponse, final String finalIsFriendText) {
return new Runnable() {
public void run() {
sendToDb(userResponse, finalIsFriendText);
}
};
}
private void sendToDb(UserResponse userResponse, String finalIsFriendText) {
Log.d(Constants.DEBUG, "sending to db friend change");
String uid, name, picid;
int points, totalshifts, totalhours, isguarding, isfriend;
uid = userResponse.getUserId();
name = userResponse.getName();
picid = userResponse.getPictureId();
points = userResponse.getTotalPoints();
totalshifts = userResponse.getTotalShifts();
totalhours = userResponse.getTotalHours();
isguarding = 0;
if(userResponse.isCheckedIn()) {
isguarding = 1;
}
//have to do the opposite since trying to add or remove 3 means newly added friend, 2 means newly removed friend
isfriend = 3;
if(userResponse.isFriend()) {
isfriend = 2;
}
DatabaseUser addOrRemoveUser = new DatabaseUser(uid, name, picid, points, totalshifts,totalhours, isguarding, isfriend);
db.updateFriend(addOrRemoveUser);
changeText(finalIsFriendText);
notifyDataSetChanged();
}
private Runnable cancelPost() {
return new Runnable() {
public void run() {
Log.d(Constants.DEBUG, "Canceled posting item");
}
};
}
}
这是 xml(我将 android focusable 设置为 false 以使 itemclick 上的列表视图正常工作):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<!-- ListRow Left side Thumbnail image -->
<LinearLayout android:id="@+id/thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dip"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dip">
<ImageView
android:id="@+id/userImage"
android:layout_width="50dip"
android:layout_height="50dip"
android:focusable="false"
android:focusableInTouchMode="false"/>
</LinearLayout>
<!-- Name-->
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/thumbnail"
android:layout_centerInParent="true"
android:layout_marginLeft="25dip"
android:textColor="#040404"
android:typeface="sans"
android:textSize="15dip"
android:textStyle="bold"
android:text="DEFAULT NAME"
android:focusable="false"
android:focusableInTouchMode="false"/>
<!-- Friend button -->
<Button android:id="@+id/btnFriend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/friends"
android:layout_marginRight="5dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:textSize="15dip"
android:focusable="false"
android:focusableInTouchMode="false"/>
</RelativeLayout>
您试图在单独的线程中更改文本,但是,只有 UI 主线程 可以更改 TextView 和按钮等视图。
要计算出来,您可以使用 runOnUiThread
runOnUiThread(new Runnable() {
public void run() {
// Update Button Text
}
});
因此,在 sendToDB
中,更改
changeText(finalIsFriendText);
为
runOnUiThread(new Runnable() {
public void run() {
changeText(finalIsFriendText);
}
});
runOnUIThread
是 java.lang.Runnable 中的一种方法,可以在 Docs
中看到
Runs the specified action on the UI thread. If the current thread is
the UI thread, then the action is executed immediately. If the current
thread is not the UI thread, the action is posted to the event queue
of the UI thread.
所以它是一个将您输入的 Runnable 作为参数的函数,并且 运行 它在 UI 线程中,从而可以在任何其他线程中更改 UI 元素.
我认为问题是 isFriend
用于更新文本,请使用另一个来执行此操作。
还要注意 UI 主线程 问题。
private Button btnToUpdate;
@Override
public void onClick(View v) {
btnToUpdate = v; //save which button to update
//Remove friend
callConfirmAddOrRemove(_listForSearch.get(position), finalIsFriendText);
Log.d(Constants.DEBUG, "clicked friend button " + finalIsFriendText);
}
private void changeText(String finalIsFriendText) {
String newTextToFill = "";
if(finalIsFriendText.equals("Remove Friend")) {
newTextToFill = "Add Friend";
}
if(finalIsFriendText.equals("Add Friend")) {
newTextToFill = "Remove Friend";
}
Log.d(Constants.DEBUG, "changing text of friend button " + newTextToFill);
btnToUpdate.setText(newTextToFill); //use btnToUpdate to update text
notifyDataSetChanged();
}
在getView
的点击监听中,方法:
callConfirmAddOrRemove(_listForSearch.get(position), finalIsFriendText);
你不能正确 position
,所以你必须定义一个最终的 position
,或者用按钮绑定一个 position
标签 isFriend
.
[更新]
isFriend.setTag(position); //this is inside getView
然后在您的听众中:
int position = (int)v.getTag(); //this position will be correct one
希望对您有所帮助!
我试图在列表视图中单击按钮时更改按钮的文本,我尝试通过自定义适配器来完成。对于日志,调用 onclick 只是文本似乎没有改变:
这是我的适配器代码:
public class UserViewerAdapter extends BaseAdapter {
public List<DatabaseUser> _list;
public List<UserResponse> _listForSearch;
private final Activity mContext;
private ConfirmManager confirmManager;
private int query;
private Button isFriend;
// database helper
private DatabaseHelper db;
private static LayoutInflater inflater = null;
public UserViewerAdapter(Activity context, List<DatabaseUser> list) {
mContext = context;
_list = list;
//establishing db
db = new DatabaseHelper(mContext);
confirmManager = new ConfirmManager();
query = 0;
}
public UserViewerAdapter( List<UserResponse> list, Activity context) {
mContext = context;
_listForSearch = list;
query = 1;
//establishing db
db = new DatabaseHelper(mContext);
confirmManager = new ConfirmManager();
}
@Override
public int getCount() {
if(query == 0) {
return _list.size();
}
return _listForSearch.size();
}
@Override
public Object getItem(int position) {
if(query == 0) {
return _list.get(position);
}
return _listForSearch.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = mContext.getLayoutInflater();
v = inflater.inflate(R.layout.users_layout, null);
}
ImageView userImage = (ImageView) v.findViewById(R.id.userImage);
TextView text = (TextView) v.findViewById(R.id.label);
isFriend = (Button) v.findViewById(R.id.btnFriend);
String isFriendText;
//coming from search
if(query == 1) {
if (_listForSearch != null && _listForSearch.size() > 0) {
text.setText(_listForSearch.get(position).getName());
}
Picasso.with(mContext).setLoggingEnabled(true);
// String pictureToAdd = Constants.USER_IMAGES + _listForSearch.get(position).getPicId();
// String photo = _listForSearch.get(position).get_picture();
// Log.d(Constants.DEBUG, "THE photo IS " + photo);
// Log.d(Constants.DEBUG, "THE constant IS " + Constants.USER_IMAGES);
// if (photo.equals("default.jpg")) {
Picasso.with(mContext).load(R.drawable.default_profile_image).resize(50, 50).into(userImage);
isFriendText = "Add Friend";
if(_listForSearch.get(position).isFriend()) {
isFriendText = "Remove Friend";
}
isFriend.setText(isFriendText);
final String finalIsFriendText = isFriendText;
isFriend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Remove friend
callConfirmAddOrRemove(_listForSearch.get(position), finalIsFriendText);
Log.d(Constants.DEBUG, "clicked friend button " + finalIsFriendText);
}
});
}
return v;
}
private void changeText(String finalIsFriendText) {
String newTextToFill = "";
if(finalIsFriendText.equals("Remove Friend")) {
newTextToFill = "Add Friend";
}
if(finalIsFriendText.equals("Add Friend")) {
newTextToFill = "Remove Friend";
}
Log.d(Constants.DEBUG, "changing text of friend button " + newTextToFill);
isFriend.setText(newTextToFill);
notifyDataSetChanged();
}
private void callConfirmAddOrRemove(UserResponse userResponse, String finalIsFriendText) {
boolean dlg = confirmManager.Confirm(mContext, mContext.getString(R.string.remove_friend), mContext.getString(R.string.details_confirmation)
+ "\n" + mContext.getString(R.string.details_info),
mContext.getString(R.string.submit), mContext.getString(R.string.cancel), addOrRemove(userResponse, finalIsFriendText),
cancelPost());
}
private Runnable addOrRemove(final UserResponse userResponse, final String finalIsFriendText) {
return new Runnable() {
public void run() {
sendToDb(userResponse, finalIsFriendText);
}
};
}
private void sendToDb(UserResponse userResponse, String finalIsFriendText) {
Log.d(Constants.DEBUG, "sending to db friend change");
String uid, name, picid;
int points, totalshifts, totalhours, isguarding, isfriend;
uid = userResponse.getUserId();
name = userResponse.getName();
picid = userResponse.getPictureId();
points = userResponse.getTotalPoints();
totalshifts = userResponse.getTotalShifts();
totalhours = userResponse.getTotalHours();
isguarding = 0;
if(userResponse.isCheckedIn()) {
isguarding = 1;
}
//have to do the opposite since trying to add or remove 3 means newly added friend, 2 means newly removed friend
isfriend = 3;
if(userResponse.isFriend()) {
isfriend = 2;
}
DatabaseUser addOrRemoveUser = new DatabaseUser(uid, name, picid, points, totalshifts,totalhours, isguarding, isfriend);
db.updateFriend(addOrRemoveUser);
changeText(finalIsFriendText);
notifyDataSetChanged();
}
private Runnable cancelPost() {
return new Runnable() {
public void run() {
Log.d(Constants.DEBUG, "Canceled posting item");
}
};
}
}
这是 xml(我将 android focusable 设置为 false 以使 itemclick 上的列表视图正常工作):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<!-- ListRow Left side Thumbnail image -->
<LinearLayout android:id="@+id/thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dip"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dip">
<ImageView
android:id="@+id/userImage"
android:layout_width="50dip"
android:layout_height="50dip"
android:focusable="false"
android:focusableInTouchMode="false"/>
</LinearLayout>
<!-- Name-->
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/thumbnail"
android:layout_centerInParent="true"
android:layout_marginLeft="25dip"
android:textColor="#040404"
android:typeface="sans"
android:textSize="15dip"
android:textStyle="bold"
android:text="DEFAULT NAME"
android:focusable="false"
android:focusableInTouchMode="false"/>
<!-- Friend button -->
<Button android:id="@+id/btnFriend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/friends"
android:layout_marginRight="5dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:textSize="15dip"
android:focusable="false"
android:focusableInTouchMode="false"/>
</RelativeLayout>
您试图在单独的线程中更改文本,但是,只有 UI 主线程 可以更改 TextView 和按钮等视图。
要计算出来,您可以使用 runOnUiThread
runOnUiThread(new Runnable() {
public void run() {
// Update Button Text
}
});
因此,在 sendToDB
中,更改
changeText(finalIsFriendText);
为
runOnUiThread(new Runnable() {
public void run() {
changeText(finalIsFriendText);
}
});
runOnUIThread
是 java.lang.Runnable 中的一种方法,可以在 Docs
Runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.
所以它是一个将您输入的 Runnable 作为参数的函数,并且 运行 它在 UI 线程中,从而可以在任何其他线程中更改 UI 元素.
我认为问题是 isFriend
用于更新文本,请使用另一个来执行此操作。
还要注意 UI 主线程 问题。
private Button btnToUpdate;
@Override
public void onClick(View v) {
btnToUpdate = v; //save which button to update
//Remove friend
callConfirmAddOrRemove(_listForSearch.get(position), finalIsFriendText);
Log.d(Constants.DEBUG, "clicked friend button " + finalIsFriendText);
}
private void changeText(String finalIsFriendText) {
String newTextToFill = "";
if(finalIsFriendText.equals("Remove Friend")) {
newTextToFill = "Add Friend";
}
if(finalIsFriendText.equals("Add Friend")) {
newTextToFill = "Remove Friend";
}
Log.d(Constants.DEBUG, "changing text of friend button " + newTextToFill);
btnToUpdate.setText(newTextToFill); //use btnToUpdate to update text
notifyDataSetChanged();
}
在getView
的点击监听中,方法:
callConfirmAddOrRemove(_listForSearch.get(position), finalIsFriendText);
你不能正确 position
,所以你必须定义一个最终的 position
,或者用按钮绑定一个 position
标签 isFriend
.
[更新]
isFriend.setTag(position); //this is inside getView
然后在您的听众中:
int position = (int)v.getTag(); //this position will be correct one
希望对您有所帮助!