适配器视图内的OnClickListener

时间:2018-01-09 13:05:36

标签: android listview android-arrayadapter

在我的活动中,我显示的是数据列表,每行都有一个编辑和删除按钮。这些按钮的侦听器在listviews适配器中定义。

我已经实现了一个自定义数组适配器:

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的最后一个项目。

我已经尝试了很多东西并且做了很多改变但到目前为止没有任何工作,这是我的最终代码。

4 个答案:

答案 0 :(得分:1)

您可以在按钮中添加标签。每次调用getView方法时,将当前位置标记为按钮。单击按钮获取按钮的标签,它将返回按钮的更新值/位置。并且在回拨该按钮单击时执行您想要处理的当前位置。希望有所帮助 添加更多信息 你有这行代码

 viewHolder.btnEdit 

这是编辑按钮。现在,您应该使用下面的代码为此按钮添加标签。您需要在Viewholder对象初始化的else子句之后使用下面的代码。

viewHolder.btnEdit.setTag(位置);

在onclick的回调中使用下面的代码

button.getTag()

答案 1 :(得分:1)

将每个ViewHolder对象的位置设置为按钮,并在单击时使用getTag()检索它。 这样的事情需要做: viewHolder.btnEdit.setTag(position)

onClick()内,将位置检索为viewHolder.btnEdit.getTag()

要在viewHolder中使用onClick()对象,必须将其声明为final,这样您就可以将对象复制为final ViewHolder finalHolder = viewHolder并使用finalHolder对象执行上述操作

答案 2 :(得分:1)

尝试按以下方式设置每个位置按钮的标记,这样当点击按钮时,您可以使用标记返回位置。

@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);
            }

    });

希望,我很乐于助人。

答案 3 :(得分:0)

  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);
                }
            }