Arrayadapter给出错误的位置

时间:2014-08-28 08:51:03

标签: android listview android-fragments android-arrayadapter

我使用了一个包含ViewPager的活动,该活动使用一个动态添加的单个片段,具体取决于传入的Json响应。

现在我的问题是,只有当它们在列表中的项目太多时,比在滚动有时适配器在列表行中单击视图时给出错误的位置。

包含适配器代码的My Fragment如下:

    public class FragmentDealDisplay extends Fragment {
        private ListView mDealListView;
        private final String DEAL_ARRAY_TAG = "deals";
        private final String DEAL_CATEGORY_TAG = "category";
        private final String DEAL_ID_TAG = "deal_id";
        private final String DEAL_DESC_TAG = "descripition";
        private final String DEAL_NAME_TAG = "deal_name";
        private final String DEAL_PRICE_TAG = "price";
        private final String DEALER_NAME_TAG = "dealer_name";
        private final String DEAL_IMAGE = "image";
        private ArrayList<DealDataObject> mList;
        private ArrayList<DealDataObject> listToPass;
        TextView mTotalTextView;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_deals, container, false);
            initViewsFragment(view);
            return view;
        }

        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            mTotalTextView = (TextView) getView().findViewById(
                    R.id.textView_totalPriceResult);
        }

        private void initViewsFragment(View v) {
            mDealListView = (ListView) v.findViewById(R.id.listView_deals);

            String jsonFromBundle = getArguments().getString(
                    Constants.DEAL_FRAGMENT_BUNDLE_TAG);
            String category = getArguments().getString(
                    Constants.DEAL_FRAGMENT_BUNDLE_CATEGORY_TAG);
            mList = new ArrayList<DealDataObject>();
            listToPass = new ArrayList<DealDataObject>();
            if (!CommonUtility.isStringEmtyOrNull(jsonFromBundle)) {
                try {
                    JSONObject jsonObject = new JSONObject(jsonFromBundle);
                    JSONArray jsonArray = jsonObject.getJSONArray(DEAL_ARRAY_TAG);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject jObj = jsonArray.getJSONObject(i);
                        if (category.equalsIgnoreCase(jObj
                                .optString(DEAL_CATEGORY_TAG))) {
                            DealDataObject dataObject = new DealDataObject();
                            dataObject.setDealDescription(jObj
                                    .optString(DEAL_DESC_TAG));
                            dataObject.setDealerId(jObj.optString(DEAL_ID_TAG));
                            dataObject
                                    .setDealerImageUrl(jObj.optString(DEAL_IMAGE));
                            dataObject.setDealerName(jObj
                                    .optString(DEALER_NAME_TAG));
                            dataObject.setDealName(jObj.optString(DEAL_NAME_TAG));
                            dataObject.setDealPrice(jObj.optString(DEAL_PRICE_TAG));
                            mList.add(dataObject);
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
            FragmentListAdapter fragmentListAdapter = new FragmentListAdapter(
                    getActivity(), R.layout.row_deal_list, mList);
            mDealListView.setAdapter(fragmentListAdapter);
            fragmentListAdapter.notifyDataSetChanged();
        }

        public static FragmentDealDisplay newInstance(Bundle b) {
            FragmentDealDisplay dealDisplay = new FragmentDealDisplay();
            Bundle bundle = b;
            dealDisplay.setArguments(bundle);
            return dealDisplay;
        }

        private class FragmentListAdapter extends ArrayAdapter<DealDataObject> {
            private ArrayList<DealDataObject> mAdapterList;

            public FragmentListAdapter(Context context, int resource,
                    ArrayList<DealDataObject> objects) {
                super(context, resource, objects);
                mAdapterList = objects;
            }

            @Override
            public int getCount() {
                return super.getCount();
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View rowView = convertView;
                ViewHolder holder = new ViewHolder();
                if (rowView == null) {
                    LayoutInflater inflater = getActivity().getLayoutInflater();
                    rowView = inflater.inflate(R.layout.row_deal_list, null);

                    holder.dealerName = (TextView) rowView
                            .findViewById(R.id.textView_dealerName);
                    holder.dealerName.setTag(position);
                    holder.dealDetail = (TextView) rowView
                            .findViewById(R.id.textView_deal_details);
                    holder.dealDetail.setTag(position);
                    holder.dealName = (TextView) rowView
                            .findViewById(R.id.textView_dealName);
                    holder.dealName.setTag(position);
                    holder.dealPrice = (TextView) rowView
                            .findViewById(R.id.textView_dealPrice);
                    holder.dealPrice.setTag(position);
                    holder.dealImage = (ImageView) rowView
                            .findViewById(R.id.imageView_dealer);
                    holder.dealImage.setTag(position);
                    rowView.setTag(holder);
                } else {
                    holder = (ViewHolder) rowView.getTag();
                }
                AQuery aQuery = new AQuery(getActivity());
                // ViewHolder viewHolder = (ViewHolder) rowView.getTag();
                DealDataObject dealDataObject = mAdapterList.get(position);
                holder.dealName.setText(dealDataObject.getDealName());
                holder.dealerName.setText(dealDataObject.getDealerName());
                holder.dealPrice.setText(dealDataObject.getDealPrice());
                if (CommonUtility.isStringEmtyOrNull(dealDataObject
                        .getDealDescription())) {
                } else {
                    holder.dealerName.append("  -->");
                }
                if (!dealDataObject.isSelected()) {
                    holder.dealPrice.setBackgroundColor(getResources().getColor(
                            R.color.castle_grey));
                    listToPass.remove(dealDataObject);
                } else {
                    holder.dealPrice.setBackgroundColor(getResources().getColor(
                            R.color.blue));
                    listToPass.add(dealDataObject);
                }
                holder.dealDetail.setText(Html.fromHtml(dealDataObject
                        .getDealDescription()));
                aQuery.id(holder.dealImage).image(
                        dealDataObject.getDealerImageUrl(), true, true, 200, 0);
                final ViewHolder holderTemp = holder;
                holder.dealerName.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (holderTemp.dealDetail.getVisibility() == View.GONE) {
                            holderTemp.dealDetail.setVisibility(View.VISIBLE);
                        } else {
                            holderTemp.dealDetail.setVisibility(View.GONE);
                        }
                    }
                });
                holder.dealPrice.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
//clicking on this textview is supposed to turn the background blue if selected and vice versa
                        int pos = Integer.parseInt(v.getTag().toString());
                        DealDataObject dataObject = mAdapterList.get(pos);
                        if (dataObject.isSelected()) {
                            dataObject.setSelected(false);
                            // v.setBackgroundColor(getResources().getColor(
                            // R.color.castle_grey));
                            listToPass.remove(dataObject);

                        } else {
                            dataObject.setSelected(true);
                            // v.setBackgroundColor(getResources().getColor(
                            // R.color.blue));
                            listToPass.add(dataObject);
                        }
                        updateTotal(dataObject);
                        FragmentListAdapter.this.notifyDataSetChanged();
                    }
                });
                return rowView;
            }
        }

        static class ViewHolder {
            public TextView dealName, dealDetail, dealerName, dealPrice;
            public ImageView dealImage;
        }

        private void updateTotal(DealDataObject object) {
            if (getActivity() instanceof DealsActivity) {
                int currentTotal = 0;
                String totalInActivity = ((DealsActivity) getActivity())
                        .getTextViewText();
                if (!CommonUtility.isStringEmtyOrNull(totalInActivity)) {
                    currentTotal = Integer.parseInt(totalInActivity);
                }

                if (object.isSelected()) {
                    currentTotal = currentTotal
                            + Integer.valueOf(object.getDealPrice());
                } else {
                    currentTotal = currentTotal
                            - Integer.valueOf(object.getDealPrice());
                }
                ((DealsActivity) getActivity()).setTextToTotal(String
                        .valueOf(currentTotal));
                // mTotalTextView.setText(String.valueOf(currentTotal));
            }
        }
    }

现在我的问题是当我点击textview

holder.dealPrice.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
    //clicking on this textview is supposed to turn the background blue if selected and vice versa
                            int pos = Integer.parseInt(v.getTag().toString());
                            DealDataObject dataObject = mAdapterList.get(pos);
                            if (dataObject.isSelected()) {
                                dataObject.setSelected(false);
                                // v.setBackgroundColor(getResources().getColor(
                                // R.color.castle_grey));
                                listToPass.remove(dataObject);

                            } else {
                                dataObject.setSelected(true);
                                // v.setBackgroundColor(getResources().getColor(
                                // R.color.blue));
                                listToPass.add(dataObject);
                            }
                            updateTotal(dataObject);
                            FragmentListAdapter.this.notifyDataSetChanged();
                        }
                    });

它突出显示不同行中的textview,例如如果我点击第二行,它会在第8行突出显示,并且在调试时,getView()方法中的“position”参数是错误的。

我已经经历了各种相关的问题和例子,如果你能指出我错过了什么,我们将非常感谢你们的帮助。

请注意,只有当列表包含大量数据时才会出现此问题。

2 个答案:

答案 0 :(得分:1)

移动

holder.dealerName.setTag(position);

适用于Viewif else之外的所有getView

目前你正在做的是检查rowView是否为null,如果它为null,那么你正在为其中的布局充气并在包含该位置的所有View中设置标签

但是当您滚动ListView Android时,我会回收View并且rowView一段时间后不会为空,并且position值不会在View秒。

因此,移动setTag(position)之外View以外的所有if else移动getView

答案 1 :(得分:0)

请尝试这种方式,希望这有助于您解决问题。

public View getView(final int position, View convertView, ViewGroup parent)

holder.dealPrice.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
         //clicking on this textview is supposed to turn the background blue if selected and vice versa

         DealDataObject dataObject = mAdapterList.get(position);
         if (dataObject.isSelected()) {
            dataObject.setSelected(false);
            // v.setBackgroundColor(getResources().getColor(
            // R.color.castle_grey));
            listToPass.remove(dataObject);
         } else {
            dataObject.setSelected(true);
           // v.setBackgroundColor(getResources().getColor(
           // R.color.blue));
           listToPass.add(dataObject);
        }
        updateTotal(dataObject);
        FragmentListAdapter.this.notifyDataSetChanged();
     }
 });