我有ListView,如下图所示
每个白框是一个单独的ListView行.每个ListView行在右上角都有一个Button.
each white box is a separate ListView row. Each ListView row has a Button at top right corner.
我正在尝试在每一行的Button上设置一个OnClickListener.每当单击此Button时,我都想删除该行.
I am trying to set a OnClickListener on Button of each row. Whenever this Button is clicked, i want to delete that row.
每个ListView行中的数据都来自Firebase数据库.因此,每当在ListView的任何行中单击十字Button时,我都会得到Timestamp的值,然后将此Timestamp作为参数传递给在数据库中搜索此Timestamp的单独方法中. Firebase数据库中具有此Timestamp作为其子级的所有键都将被删除.
The data in each ListView row is coming from Firebase database. So whenever the cross Button is clicked on in any row of ListView, i get the value of Timestamp and then pass this Timestamp as an argument in a separate method that searches in the database for this Timestamp. Any key in the Firebase database that has this Timestamp as its child is deleted.
用于删除ListView行数据的方法可以正常工作,因为它删除与此方法中作为参数传递的Timestamp关联的数据.
Method that is used to delete the ListView row data is working fine as it deletes the data associated with the Timestamp passed in this method as an argument.
问题是单击任何ListView上的按钮时得到的Timestamp值是错误的.例如,在上图中,如果我单击带有27-01-2018 05-31-22AM的Timestamp的第二个ListView行,而不是获取此Timestamp,而是获取了ListView最后一行的Timestamp,因此错误的数据将被删除.
Problem is that the Timestamp value that i am getting when a button is clicked on any ListView is wrong. For example, in the image above, if i click on 2nd ListView row with Timestamp of 27-01-2018 05-31-22AM, instead of getting this Timestamp, i get the Timestamp of the last row of ListView and consequently wrong data is deleted.
这是相关代码:
onClick()方法
@Override public void onClick(View view) { //get the parent view i.e. listview row on which delete button is clicked ConstraintLayout listviewRow = (ConstraintLayout) btnDeleteMsg.getParent(); //get the textview containing receiver username from the view on which delete button is clicked TextView textviewReceiver = listviewRow.findViewById(R.id.outbox_msgReceiverUsername); //get the textview containing timestamp value from the view on which delete button is clicked TextView textTimestamp = listviewRow.findViewById(R.id.outbox_msgSentTime); //get the values of message receiver username and timestamp //timestamp value will be used to determine which message to delete //from database String receiverUsername = textviewReceiver.getText().toString(); String timestamp = textTimestamp.getText().toString(); //call delSentMsg() method in SentMessages Fragment using SentMessages Fragment //instance passed in the constructor of this class sentMsgsFragment.deleteSentMsg(receiverUsername, timestamp); }ListView行布局
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="schemas.android/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="schemas.android/apk/res-auto" android:padding="15dp" android:background="#fff"> <Button android:id="@+id/btn_deleteMsg_SMF" android:layout_width="17dp" android:layout_height="17dp" android:background="@drawable/cross_image" app:layout_constraintRight_toRightOf="parent" /> <TextView android:id="@+id/outbox_msgText" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#000" android:textSize="22sp" android:paddingTop="10dp" app:layout_constraintTop_toBottomOf="@id/btn_deleteMsg_SMF"/> <TextView android:id="@+id/outbox_msgReceiverLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/to_text_label" android:textColor="#000" android:textSize="18sp" app:layout_constraintTop_toBottomOf="@id/outbox_msgText" app:layout_constraintLeft_toLeftOf="parent" android:paddingTop="10dp"/> <TextView android:id="@+id/outbox_msgReceiverUsername" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" app:layout_constraintLeft_toRightOf="@id/outbox_msgReceiverLabel" android:layout_marginLeft="10dp" app:layout_constraintTop_toBottomOf="@id/outbox_msgText" android:paddingTop="10dp"/> <TextView android:id="@+id/outbox_msgDateLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/sent_on_label" android:textColor="#000" android:textSize="18sp" app:layout_constraintTop_toBottomOf="@id/outbox_msgReceiverLabel" app:layout_constraintLeft_toLeftOf="parent" android:paddingTop="10dp"/> <TextView android:id="@+id/outbox_msgSentTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" app:layout_constraintLeft_toRightOf="@id/outbox_msgDateLabel" app:layout_constraintTop_toBottomOf="@id/outbox_msgReceiverLabel" android:layout_marginLeft="10dp" app:layout_constraintBaseline_toBaselineOf="@id/outbox_msgDateLabel" android:paddingTop="10dp"/> </android.support.constraint.ConstraintLayout>ListView适配器类
public class CustomOutboxListAdapter extends BaseAdapter implements View.OnClickListener{ private ArrayList<SentMessageTemplate> sentMsgsList; private Context context; private Button btnDeleteMsg; private SentMessages sentMsgsFragment; public CustomOutboxListAdapter(ArrayList<SentMessageTemplate> list, Context cont, SentMessages sm){ this.sentMsgsList = list; this.context = cont; this.sentMsgsFragment = sm; } @Override public int getCount() { return this.sentMsgsList.size(); } @Override public Object getItem(int position) { return this.sentMsgsList.get(position); } @Override public long getItemId(int i) { return i; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if(convertView == null){ LayoutInflater inf = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inf.inflate(R.layout.listview_outbox_messages_row, null); //private inner class used to minimize the calls to "findViewById" method holder = new ViewHolder(); holder.datetimeText = convertView.findViewById(R.id.outbox_msgSentTime); holder.messageText = convertView.findViewById(R.id.outbox_msgText); holder.receiverUsernameText = convertView.findViewById(R.id.outbox_msgReceiverUsername); convertView.setTag(holder); //click listener for delete button btnDeleteMsg = convertView.findViewById(R.id.btn_deleteMsg_SMF); btnDeleteMsg.setOnClickListener(this); } else { holder = (ViewHolder)convertView.getTag(); } SentMessageTemplate stu = sentMsgsList.get(position); holder.datetimeText.setText(stu.getTimestamp()); holder.messageText.setText(stu.getMessageContent()); holder.receiverUsernameText.setText(stu.getMsgReceiver()); return convertView; } @Override public void onClick(View view) { //get the parent view i.e. listview row on which delete button is clicked ConstraintLayout listviewRow = (ConstraintLayout) btnDeleteMsg.getParent(); //get the textview containing receiver username from the view on which delete button is clicked TextView textviewReceiver = listviewRow.findViewById(R.id.outbox_msgReceiverUsername); //get the textview containing timestamp value from the view on which delete button is clicked TextView textTimestamp = listviewRow.findViewById(R.id.outbox_msgSentTime); //get the values of message receiver username and timestamp //timestamp value will be used to determine which message to delete //from database String receiverUsername = textviewReceiver.getText().toString(); String timestamp = textTimestamp.getText().toString(); //call delSentMsg() method in SentMessages Fragment using SentMessages Fragment //instance passed in the constructor of this class sentMsgsFragment.deleteSentMsg(receiverUsername, timestamp); } private static class ViewHolder{ public TextView datetimeText; public TextView messageText; public TextView receiverUsernameText; } }问题
我认为问题是我无法正确获得单击交叉按钮的ListView行.单击按钮时如何确定ListView的行?
Question
I think the problem is that i am not able to correctly get the ListView row on which cross button is clicked on. How can i determine the row of ListView when a button is clicked on?
推荐答案尝试对CustomOutboxListAdapter类进行这些更改.
Try making these changes to CustomOutboxListAdapter class.
在CustomOutboxListAdapter中不要实现View.OnClickListener.将其类声明从以下位置更改:
In CustomOutboxListAdapter don't implement View.OnClickListener. Change it's class declaration from:
public class CustomOutboxListAdapter extends BaseAdapter implements View.OnClickListener{收件人:
public class CustomOutboxListAdapter extends BaseAdapter {并删除其中的onClick方法:
@Override public void onClick(View view) {将public View getView(int position, View convertView, ViewGroup parent)替换为:
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if(convertView == null){ LayoutInflater inf = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inf.inflate(R.layout.listview_outbox_messages_row, null); //private inner class used to minimize the calls to "findViewById" method holder = new ViewHolder(); holder.datetimeText = convertView.findViewById(R.id.outbox_msgSentTime); holder.messageText = convertView.findViewById(R.id.outbox_msgText); holder.receiverUsernameText = convertView.findViewById(R.id.outbox_msgReceiverUsername); convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } SentMessageTemplate stu = sentMsgsList.get(position); holder.datetimeText.setText(stu.getTimestamp()); holder.messageText.setText(stu.getMessageContent()); holder.receiverUsernameText.setText(stu.getMsgReceiver()); // use local variable so it is always referenced correctly Button deleteBtn = convertView.findViewById(R.id.btn_deleteMsg_SMF); // Cache row position inside the button using `setTag` deleteBtn.setTag(position); // Attach the click event handler deleteBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int position = (Integer) view.getTag(); // Access the row position here to get the correct data item SentMessageTemplate sentMessageTemplate = getItem(position); String receiverUsername = sentMessageTemplate.getTimestamp(); String timestamp = sentMessageTemplate.getMsgReceiver(); sentMsgsFragment.deleteSentMsg(receiverUsername, timestamp); } }); return convertView; }只需删除不再使用的成员变量private Button btnDeleteMsg;.
Just delete the member variable private Button btnDeleteMsg; as not used anymore.
同样对于getItemId(int i)实施,我认为应该是这样的:
Also for getItemId(int i) implementation, I think it should be something like:
@Override public long getItemId( int position ) { return this.sentMsgsList.get(position).getId(); }然后在SentMessageTemplate类中,它应该实现:
Then in SentMessageTemplate class, it should implement:
public int getId() { // return unique ID for object .... }更多推荐
在Listview行布局中的按钮上设置单击侦听器
发布评论