适配器视图内部的 OnClickListener
OnClickListener Inside Adapter View
在我的 activity 中,我显示了一个数据列表,每一行都有一个编辑和删除按钮。这些按钮的侦听器在列表视图适配器中定义。
我已经实现了自定义数组适配器:
public class SalesArrayAdapter extends ArrayAdapter<SaleModel> {
private Context context;
private int altColour;
private SaleModel sale;
private int position;
private ArrayList<SaleModel> sales;
private static class ViewHolder{
RelativeLayout container;
TextView tvId;
TextView tvDate;
TextView tvBusNo;
TextView tvDriver;
TextView tvNoOfTrips;
TextView tvTotalExpenditure;
TextView tvTotal;
TextView tvAmountReceived;
TextView tvStatus;
TextView tvReceiptCode;
ImageButton btnEdit;
ImageButton btnRemove;
}
public SalesArrayAdapter(@NonNull Context context, @NonNull ArrayList<SaleModel> sales) {
super(context, R.layout.row_sales, sales);
//this.getContext() = getContext();
//this.sales = sales;
}
@NonNull
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
// Get the data item for this position
sale = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
// If there's no view to re-use, inflate a brand new view for row
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row_sales, parent, false);
viewHolder.container = (RelativeLayout) convertView.findViewById(R.id.row_sales_ll_container);
viewHolder.tvId = (TextView) convertView.findViewById(R.id.row_sales_tv_id);
viewHolder.tvDate = (TextView) convertView.findViewById(R.id.row_sales_tv_date);
viewHolder.tvDriver = (TextView) convertView.findViewById(R.id.row_sales_tv_driver);
viewHolder.tvNoOfTrips = (TextView) convertView.findViewById(R.id.row_sales_tv_total_no_of_trips);
viewHolder.tvTotalExpenditure = (TextView) convertView.findViewById(R.id.row_sales_tv_total_expenditure);
viewHolder.tvTotal = (TextView) convertView.findViewById(R.id.row_sales_tv_total);
viewHolder.tvAmountReceived = (TextView) convertView.findViewById(R.id.row_sales_tv_amount_received);
viewHolder.tvStatus = (TextView) convertView.findViewById(R.id.row_sales_tv_status);
viewHolder.tvReceiptCode = (TextView) convertView.findViewById(R.id.row_sales_tv_receipt_code);
viewHolder.btnEdit = (ImageButton) convertView.findViewById(R.id.row_sales_btn_edit);
viewHolder.btnRemove = (ImageButton) convertView.findViewById(R.id.row_sales_btn_trash);
// Cache the viewHolder object inside the fresh view
convertView.setTag(viewHolder);
} else {
// View is being recycled, retrieve the viewHolder object from tag
viewHolder = (ViewHolder) convertView.getTag();
}
// Populate the data from the data object via the viewHolder object
// into the template view.
if (altColour == 0) {
viewHolder.container.setBackgroundColor(Color.parseColor("#FFFFFF"));
altColour = 1;
} else {
viewHolder.container.setBackgroundColor(Color.parseColor("#EFEFEF"));
altColour = 0;
}
viewHolder.tvId.setText(String.valueOf(sale.getId()));
viewHolder.tvDate.setText(sale.getDate());
viewHolder.tvDriver.setText(sale.getDriver());
double totalTripsAmount = 0;
for(int c = 0; c < sale.getTrips().length(); c++) {
try {
totalTripsAmount += sale.getTrips().getJSONObject(c).getDouble("trip_amount");
} catch (JSONException e) {
e.printStackTrace();
}
}
viewHolder.tvNoOfTrips.setText("GHS "+totalTripsAmount);
double totalExpenditureAmount = 0;
for(int c = 0; c < sale.getExpenditure().length(); c++) {
try {
totalExpenditureAmount += sale.getExpenditure().getJSONObject(c).getDouble("amount");
} catch (JSONException e) {
e.printStackTrace();
}
}
viewHolder.tvTotalExpenditure.setText("GHS "+totalExpenditureAmount);
viewHolder.tvTotal.setText("GHS "+sale.getTotal());
viewHolder.tvAmountReceived.setText("GHS "+sale.getAmountReceived());
viewHolder.tvStatus.setText(sale.getIsPending() == 1 ? "Pending" : "Complete");
viewHolder.tvReceiptCode.setText(sale.getReceiptCode());
viewHolder.btnEdit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent editSaleIntent = new Intent(getContext(), EditSaleActivity.class);
editSaleIntent.putExtra("sale", sale.toJson().toString());
((Activity) getContext()).startActivityForResult(editSaleIntent, 800);
}
});
viewHolder.btnRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = new Integer(getPosition(sale));
removeSale(pos);
}
});
// Return the completed view to render on screen
return convertView;
}
private void removeSale(final int position) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Confirm");
builder.setMessage("Are you sure you want to delete?");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//Log.i("btnYes", "works");
SalesRequest salesRequest = new SalesRequest(getContext());
remove(getItem(position));
notifyDataSetChanged();
salesRequest.remove(getItem(position).getId(), mTrashOnSuccessListener, mTrashOnErrorListener);
}
});
builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Do nothing
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private Response.Listener<JSONObject> mTrashOnSuccessListener = new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
//
}
};
Response.ErrorListener mTrashOnErrorListener = new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Utils.showNetworkResponse(getContext(), error);
}
};
}
现在我的问题是,当我点击任何正在显示的项目的删除或编辑按钮时,它总是选择列表视图中显示的最后一个项目的位置或 ID。
例如,如果我想删除列表视图中位置为 1 的第二个项目,它将选择显示的最后一个位置为 10 的项目。
我尝试了很多东西并做了很多更改,但到目前为止没有任何效果,这是我的最终代码。
您可以在按钮中添加标签。每次调用 getView 方法时,将当前位置标记到按钮上。单击按钮时获取按钮的标签,它将 return 更新后的 value/position 按钮。并在该按钮单击的回调中对当前位置执行您想执行的操作。希望有帮助
添加更多信息
你有这行代码
viewHolder.btnEdit
这是编辑按钮。现在你应该使用下面的代码向这个按钮添加一个标签。您需要在 Viewholder 对象初始化的 else 子句之后使用以下代码。
viewHolder.btnEdit.setTag(位置);
并在 onclick 的回调中使用下面的代码
button.getTag()
将每个 ViewHolder
对象的位置设置为按钮的标签,并在单击按钮时使用 getTag()
检索它。
需要做这样的事情:
viewHolder.btnEdit.setTag(position)
并在 onClick()
中检索位置 viewHolder.btnEdit.getTag()
要在 onClick()
中使用 viewHolder
对象,必须将其声明为最终对象,以便您可以将对象复制为 final ViewHolder finalHolder = viewHolder
并使用 finalHolder
对象执行上述操作
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (fileDataVo.isPdf()) {
Intent intent = new Intent(context, PdfActivity.class);
intent.putExtra("position", position);
context.startActivity(intent);
} else if (fileDataVo.isExcel()) {
Intent intent = new Intent(context, ExcelFileActivity.class);
intent.putExtra("position", position);
context.startActivity(intent);
}
else if (fileDataVo.isPpt()) {
Intent intent = new Intent(context, PptActivity.class);
intent.putExtra("position", position);
context.startActivity(intent);
}
}
尝试按以下方式为每个位置的按钮设置标签,以便在单击按钮时可以使用标签返回位置。
@NonNull
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
// Get the data item for this position
sale = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
// If there's no view to re-use, inflate a brand new view for row
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row_sales, parent, false);
//Fetch other views here .....
viewHolder.btnEdit = (ImageButton) convertView.findViewById(R.id.row_sales_btn_edit);
viewHolder.btnRemove = (ImageButton) convertView.findViewById(R.id.row_sales_btn_trash);
// Cache the viewHolder object inside the fresh view
convertView.setTag(viewHolder);
} else {
// View is being recycled, retrieve the viewHolder object from tag
viewHolder = (ViewHolder) convertView.getTag();
}
//Setting the position as the tag for both buttons
viewHolder.btnRemove.setTag(position);
viewHolder.btnEdit.setTag(position);
现在在点击监听器中..
viewHolder.btnRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Remove the below line
int pos = new Integer(getPosition(sale));
//Use this
int pos = (int)v.getTag();
removeSale(pos);
}
});
希望,对你有帮助。
在我的 activity 中,我显示了一个数据列表,每一行都有一个编辑和删除按钮。这些按钮的侦听器在列表视图适配器中定义。
我已经实现了自定义数组适配器:
public class SalesArrayAdapter extends ArrayAdapter<SaleModel> {
private Context context;
private int altColour;
private SaleModel sale;
private int position;
private ArrayList<SaleModel> sales;
private static class ViewHolder{
RelativeLayout container;
TextView tvId;
TextView tvDate;
TextView tvBusNo;
TextView tvDriver;
TextView tvNoOfTrips;
TextView tvTotalExpenditure;
TextView tvTotal;
TextView tvAmountReceived;
TextView tvStatus;
TextView tvReceiptCode;
ImageButton btnEdit;
ImageButton btnRemove;
}
public SalesArrayAdapter(@NonNull Context context, @NonNull ArrayList<SaleModel> sales) {
super(context, R.layout.row_sales, sales);
//this.getContext() = getContext();
//this.sales = sales;
}
@NonNull
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
// Get the data item for this position
sale = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
// If there's no view to re-use, inflate a brand new view for row
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row_sales, parent, false);
viewHolder.container = (RelativeLayout) convertView.findViewById(R.id.row_sales_ll_container);
viewHolder.tvId = (TextView) convertView.findViewById(R.id.row_sales_tv_id);
viewHolder.tvDate = (TextView) convertView.findViewById(R.id.row_sales_tv_date);
viewHolder.tvDriver = (TextView) convertView.findViewById(R.id.row_sales_tv_driver);
viewHolder.tvNoOfTrips = (TextView) convertView.findViewById(R.id.row_sales_tv_total_no_of_trips);
viewHolder.tvTotalExpenditure = (TextView) convertView.findViewById(R.id.row_sales_tv_total_expenditure);
viewHolder.tvTotal = (TextView) convertView.findViewById(R.id.row_sales_tv_total);
viewHolder.tvAmountReceived = (TextView) convertView.findViewById(R.id.row_sales_tv_amount_received);
viewHolder.tvStatus = (TextView) convertView.findViewById(R.id.row_sales_tv_status);
viewHolder.tvReceiptCode = (TextView) convertView.findViewById(R.id.row_sales_tv_receipt_code);
viewHolder.btnEdit = (ImageButton) convertView.findViewById(R.id.row_sales_btn_edit);
viewHolder.btnRemove = (ImageButton) convertView.findViewById(R.id.row_sales_btn_trash);
// Cache the viewHolder object inside the fresh view
convertView.setTag(viewHolder);
} else {
// View is being recycled, retrieve the viewHolder object from tag
viewHolder = (ViewHolder) convertView.getTag();
}
// Populate the data from the data object via the viewHolder object
// into the template view.
if (altColour == 0) {
viewHolder.container.setBackgroundColor(Color.parseColor("#FFFFFF"));
altColour = 1;
} else {
viewHolder.container.setBackgroundColor(Color.parseColor("#EFEFEF"));
altColour = 0;
}
viewHolder.tvId.setText(String.valueOf(sale.getId()));
viewHolder.tvDate.setText(sale.getDate());
viewHolder.tvDriver.setText(sale.getDriver());
double totalTripsAmount = 0;
for(int c = 0; c < sale.getTrips().length(); c++) {
try {
totalTripsAmount += sale.getTrips().getJSONObject(c).getDouble("trip_amount");
} catch (JSONException e) {
e.printStackTrace();
}
}
viewHolder.tvNoOfTrips.setText("GHS "+totalTripsAmount);
double totalExpenditureAmount = 0;
for(int c = 0; c < sale.getExpenditure().length(); c++) {
try {
totalExpenditureAmount += sale.getExpenditure().getJSONObject(c).getDouble("amount");
} catch (JSONException e) {
e.printStackTrace();
}
}
viewHolder.tvTotalExpenditure.setText("GHS "+totalExpenditureAmount);
viewHolder.tvTotal.setText("GHS "+sale.getTotal());
viewHolder.tvAmountReceived.setText("GHS "+sale.getAmountReceived());
viewHolder.tvStatus.setText(sale.getIsPending() == 1 ? "Pending" : "Complete");
viewHolder.tvReceiptCode.setText(sale.getReceiptCode());
viewHolder.btnEdit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent editSaleIntent = new Intent(getContext(), EditSaleActivity.class);
editSaleIntent.putExtra("sale", sale.toJson().toString());
((Activity) getContext()).startActivityForResult(editSaleIntent, 800);
}
});
viewHolder.btnRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = new Integer(getPosition(sale));
removeSale(pos);
}
});
// Return the completed view to render on screen
return convertView;
}
private void removeSale(final int position) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Confirm");
builder.setMessage("Are you sure you want to delete?");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//Log.i("btnYes", "works");
SalesRequest salesRequest = new SalesRequest(getContext());
remove(getItem(position));
notifyDataSetChanged();
salesRequest.remove(getItem(position).getId(), mTrashOnSuccessListener, mTrashOnErrorListener);
}
});
builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Do nothing
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private Response.Listener<JSONObject> mTrashOnSuccessListener = new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
//
}
};
Response.ErrorListener mTrashOnErrorListener = new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Utils.showNetworkResponse(getContext(), error);
}
};
}
现在我的问题是,当我点击任何正在显示的项目的删除或编辑按钮时,它总是选择列表视图中显示的最后一个项目的位置或 ID。
例如,如果我想删除列表视图中位置为 1 的第二个项目,它将选择显示的最后一个位置为 10 的项目。
我尝试了很多东西并做了很多更改,但到目前为止没有任何效果,这是我的最终代码。
您可以在按钮中添加标签。每次调用 getView 方法时,将当前位置标记到按钮上。单击按钮时获取按钮的标签,它将 return 更新后的 value/position 按钮。并在该按钮单击的回调中对当前位置执行您想执行的操作。希望有帮助 添加更多信息 你有这行代码
viewHolder.btnEdit
这是编辑按钮。现在你应该使用下面的代码向这个按钮添加一个标签。您需要在 Viewholder 对象初始化的 else 子句之后使用以下代码。
viewHolder.btnEdit.setTag(位置);
并在 onclick 的回调中使用下面的代码
button.getTag()
将每个 ViewHolder
对象的位置设置为按钮的标签,并在单击按钮时使用 getTag()
检索它。
需要做这样的事情:
viewHolder.btnEdit.setTag(position)
并在 onClick()
中检索位置 viewHolder.btnEdit.getTag()
要在 onClick()
中使用 viewHolder
对象,必须将其声明为最终对象,以便您可以将对象复制为 final ViewHolder finalHolder = viewHolder
并使用 finalHolder
对象执行上述操作
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (fileDataVo.isPdf()) {
Intent intent = new Intent(context, PdfActivity.class);
intent.putExtra("position", position);
context.startActivity(intent);
} else if (fileDataVo.isExcel()) {
Intent intent = new Intent(context, ExcelFileActivity.class);
intent.putExtra("position", position);
context.startActivity(intent);
}
else if (fileDataVo.isPpt()) {
Intent intent = new Intent(context, PptActivity.class);
intent.putExtra("position", position);
context.startActivity(intent);
}
}
尝试按以下方式为每个位置的按钮设置标签,以便在单击按钮时可以使用标签返回位置。
@NonNull
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
// Get the data item for this position
sale = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
// If there's no view to re-use, inflate a brand new view for row
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row_sales, parent, false);
//Fetch other views here .....
viewHolder.btnEdit = (ImageButton) convertView.findViewById(R.id.row_sales_btn_edit);
viewHolder.btnRemove = (ImageButton) convertView.findViewById(R.id.row_sales_btn_trash);
// Cache the viewHolder object inside the fresh view
convertView.setTag(viewHolder);
} else {
// View is being recycled, retrieve the viewHolder object from tag
viewHolder = (ViewHolder) convertView.getTag();
}
//Setting the position as the tag for both buttons
viewHolder.btnRemove.setTag(position);
viewHolder.btnEdit.setTag(position);
现在在点击监听器中..
viewHolder.btnRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Remove the below line
int pos = new Integer(getPosition(sale));
//Use this
int pos = (int)v.getTag();
removeSale(pos);
}
});
希望,对你有帮助。