【问题标题】:Arrayadapter giving the wrong positionArrayadapter 给出了错误的位置
【发布时间】:2014-08-28 08:51:02
【问题描述】:

我使用了一个包含 ViewPager 的活动,它使用单个片段,根据传入的 Json 响应动态添加多次。

现在我的问题是,只有在列表中的项目太多的情况下,当在列表行中单击视图时,适配器有时会给出错误的位置。

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

现在我的问题是当我点击文本视图时

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() 方法中的“位置”参数时是错误的。

我已经经历了关于相同的各种问题和示例,如果您能指出我错过了什么,任何帮助将不胜感激。

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

【问题讨论】:

  • 你也可以给定位参数 final 并在你的 onClick 上直接访问这个定位参数而不需要 setTag()。

标签: android listview android-fragments android-arrayadapter


【解决方案1】:

移动

holder.dealerName.setTag(position);

对于您的getViewif else 之外的所有Views。

目前您正在做的是检查rowView 是否为空,如果它为空,那么您将在其中膨胀一个布局并在所有包含该位置的View 中设置标签。

但是当您滚动ListView 时,Android 将回收Views 并且rowView 在一段时间后不会为空,position 的值不会在Views 中更新。

因此,将所有Views 的setTag(position) 移到if else 之外的getView

【讨论】:

  • 不客气。如果有帮助,您可以接受答案。
  • 是的,它说我需要等待 5 分钟才能接受。
【解决方案2】:

试试这个方法,希望能帮助你解决问题。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    • 2015-12-09
    相关资源
    最近更新 更多