0

我有一个ListView动态膨胀的自定义布局,它有不同的文本视图和一个按钮。单击按钮时,用户在对话框窗口中指定选项,并将数据返回到列表视图中的选定项目。

我希望数据能够插入到列表视图中相应项目的文本视图中。但是,当列表中不可滚动的项目较少时,关闭对话框时根本不会插入任何数据,并且当它有足够的可滚动项目时,数据会插入到列表中错误项目的文本视图中。我不知道我做错了什么,这是我的代码:

public double COST_EM = 0.00, COST = 0.00, NUM_CO = 0.00;
private Spinner mPSpinner, mMediSpinner;
private ArrayAdapter<String> pmedi, numCo;
private TextView mPTv, mCoTv, mSubMain, mSubTv;

@Override
        public View getView(final int position, View convertView,
                ViewGroup parent) {
            View view = null;
            LayoutInflater inflater = (LayoutInflater) mContext
                    .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.item_custom_layout, parent, false);

            // Display image in the ImageView widget
            TempP tphoto = tempPList.get(position);


            mPTv = (TextView) view.findViewById(R.id.p_tv_po);
            mCoTv = (TextView) view.findViewById(R.id.co_tv_po);
            mSubMain = (TextView) view.findViewById(R.id.sub_list);

            mModify = (Button) view.findViewById(R.id.modify_btn_po);
            mModify.setOnClickListener(new View.OnClickListener() {

                // calculate the order cost
                protected void calculateCost() {

                    mSub = ((COST_EM + COST) * NUM_CO);

                    mSubtv.setText("" + Double.toString(mSub));
                }

                @Override
                public void onClick(View v) {

                    mDialog = new Dialog(PCustom.this);
                    mDialog.setContentView(R.layout.item_custom_dialog);
                    mDialog.setTitle("Modify specifications");

                    mPSpinner = (Spinner) mDialog.findViewById(R.id.ces_sp_dialog);
                    mSubTv = (TextView) mDialog.findViewById(R.id.sub_der_dialog);

                    // set spinner adapters (code truncated for brevity)
                    pmedi = new ArrayAdapter<String>(MyApplication
                            .getContext(), R.layout.spinner_style, pmedi);
                    mPSpinner.setAdapter(pmedi);

                    mPSpinner
                            .setOnItemSelectedListener(new OnItemSelectedListener() {
                                public void onItemSelected(AdapterView<?> arg0,
                                        View arg1, int pos, long arg3) {

                                    if (mPSpinner.getSelectedItem() == "Glossy") {
                                        COST = 2000.00;
                                    } else if (mPSpinner
                                            .getSelectedItem() == "Standard") {
                                        COST = 1500.00;
                                    } else if (mPSpinner
                                            .getSelectedItem() == "Other") {
                                        COST = 1000.00;
                                    }

                                    // calculate the cost
                                    calculateCost();
                                }

                                public void onNothingSelected(
                                        AdapterView<?> arg0) {
                                }
                            });

                    Button save = (Button) mDialog
                            .findViewById(R.id.save_btn_po_dialog);
                    Button cancel = (Button) mDialog
                            .findViewById(R.id.cancel_btn_po_dialog);

                    save.setOnClickListener(new View.OnClickListener() {

                        public void onClick(View v) {
                            // String newnumber =
                            // mobileNumber.getText().toString();

                            mPTv.setText("" + mPSpinner
                                    .getSelectedItem());
                            mCoTv.setText((String) mNCoSpinner
                                    .getSelectedItem());
                            mSubMain.setText(Double.toString(mSub));

                            mDialog.dismiss();
                        }
                    });

                    cancel.setOnClickListener(new View.OnClickListener() {

                        @Override
                        public void onClick(View v) {
                            mDialog.dismiss();
                        }
                    });

                    mDialog.show();

                }
            });

            return view;
        }
4

1 回答 1

1

方法 getView() 每次 ListView 调用时返回一个项目 View 并带有特定的“位置”参数,因此它被调用的次数不小于它拥有的项目数。因此,您的成员变量 mPTv、mCoTv 和 mSubMain 将被多次重新分配,并最终在 getView() 的最终调用中获得它们的值。这就是您遇到该问题的原因。

要解决您的问题,您需要在单击“保存按钮”时拥有正确的 TextView。以下是如何找到正确的 TextView:

在mModify Button的OnClickListener中,方法onClick(View v)中的“v”参数就是mModify自身的同一个实例。因此,您可以使用它来找到那些正确的 TextView。也许您可以将项目根视图设置为其标记并在 onClick(View v) 中获取根视图,然后使用它来查找所有正确的 TextView。以下是更改代码的方法:

    mModify = (Button) view.findViewById(R.id.modify_btn_po);
    // set the root view as the tag of "modify button".
    mModify.setTag(view);
    mModify.setOnClickListener(new View.OnClickListener() {

        // calculate the order cost
        protected void calculateCost() {

            mSub = ((COST_EM + COST) * NUM_CO);

            mSubtv.setText("" + Double.toString(mSub));
        }

        @Override
        public void onClick(View v) {
            // retrieve the root view here, it's the root view of the item on which you    
            // clicked the "modify button".
            View view = (View)v.getTag();
            // find the correct TextViews here.
            mPTv = (TextView) view.findViewById(R.id.p_tv_po);
            mCoTv = (TextView) view.findViewById(R.id.co_tv_po);
            mSubMain = (TextView) view.findViewById(R.id.sub_list);

BTW,你没有优化你的ListView,所以可能滚动不流畅,但这不是你的问题。你可以参考这个: 如何优化Android ListView?

于 2014-11-04T11:23:22.547 回答