ArrayList丢失数据

时间:2014-11-27 18:02:31

标签: android android-listview arraylist baseadapter

在我的应用中,我有ListView Checkboxes并且有一个扩展BaseAdapter的适配器以填充ListView。列表的基本功能是显示债务,用户可以通过选中框来选择要支付的债务,当用户添加/删除项目时,列表底部的总数会更新。现在,一些债务与另一个债务相关,如果用户检查一个债务,任何其他相关债务也应该被标记,如果您取消债务则应该相同。我还有一个按钮,清除列表中所有选定的债务,以及我的问题所在。

我在ArrayList上记录所选择的债务,它似乎适用于所有程序但是清除按钮。按下按钮时,所选的债务清单似乎总是空的。对可能发生的事情有任何想法吗?

这是我的适配器:

public class ServicesFinancialStatusAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener{

    private Context context;
    private List<Debts> debtsList;
    private List<Debts> selectedDebts;
    private LayoutInflater inflater;
    private int tabPosition;
    private float total;
    private OnTotalChangedListener listener;

    public ServicesFinancialStatusAdapter(Context context, List<Debts> debtsList, int tabPosition) {
        this.context = context;
        this.debtsList = debtsList;
        this.tabPosition = tabPosition;
        this.total = 0;
        this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.selectedDebts = new ArrayList<Debts>();
    }

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

    @Override
    public Object getItem(int i) {
        return debtsList.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {

        ViewHolder holder;

        if (view == null) {

            holder = new ViewHolder();
            view = inflater.inflate(R.layout.item_services_financial_status, viewGroup, false);

            holder.concept = (TextView) view.findViewById(R.id.payment_concept);
            holder.descriptionOrDate = (TextView) view.findViewById(R.id.payment_description_date);
            holder.amount = (TextView) view.findViewById(R.id.payment_amount);
            holder.expirationDate = (TextView) view.findViewById(R.id.payment_expiration_date);

            if (tabPosition > 4) {
                holder.checkBox = (CheckBox) view.findViewById(R.id.check_box);
                holder.checkBox.setOnCheckedChangeListener(this);
            }

            view.setTag(holder);
        } else
            holder = (ViewHolder) view.getTag();

        Debts item = debtsList.get(i);

        holder.concept.setText(item.getConcept());
        holder.amount.setText(item.getAmountToString());

        if (item.isExpired())
            holder.expirationDate.setText(context.getString(R.string.expired_status_indicator));
        else
            holder.expirationDate.setText(context.getString(R.string.debts_expiration_date_indicator) + item.getExpirationDate());

        if (tabPosition < 3)
            holder.descriptionOrDate.setText(item.getDescription());
        else if (tabPosition < 5)
            holder.descriptionOrDate.setText(item.getDate());
        else {
            holder.descriptionOrDate.setVisibility(View.GONE);
            holder.checkBox.setVisibility(View.VISIBLE);
            holder.checkBox.setTag(i);
            holder.checkBox.setChecked(item.isSelected());
        }

        return view;
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

        //Get the position of the item clicked and the data object
        Integer position = (Integer) buttonView.getTag();
        Debts item = debtsList.get(position);

        //Change the status ob the object
        item.setSelected(isChecked);

        for (Debts debts : debtsList) {

            //Check on the list for related objects and marks them as well
            if (debts.getConceptId() == item.getRelatedDebt())
                debts.setSelected(isChecked);

            //Get the amount of the debt and add/remove it from
            //the selectedDebts list and update the total
            float amount = debts.getAmount();
            if (debts.isSelected()) {
                if (!selectedDebts.contains(debts)) {

                    selectedDebts.add(debts);
                    listener.onTotalChanged(addToTotal(amount), selectedDebts);
                }
            }
            else {
                if (selectedDebts.contains(debts)) {

                    selectedDebts.remove(debts);
                    listener.onTotalChanged(removeFromTotal(amount), selectedDebts);
                }
            }
        }
        //Finally update the UI
        notifyDataSetChanged();
    }

    //Anywhere else in the code selectedDebts has the right data but here
    //Here the size of the list is always 0
    public void unMarkDebts() {

        for (Debts debts : debtsList) {

            //Get the amount of the debt and remove it from
            //the selectedDebts list, set the data object as unselected
            //and update the total
            float amount = debts.getAmount();
            if (selectedDebts.contains(debts)) {

                debts.setSelected(false);
                selectedDebts.remove(debts);
                listener.onTotalChanged(removeFromTotal(amount), selectedDebts);
            }
        }
        //Update the UI
        notifyDataSetChanged();
    }

    private float addToTotal(float value) {
        return total += value;
    }

    private float removeFromTotal(float value) {
        return total -=value;
    }

    public interface OnTotalChangedListener{
        public void onTotalChanged(float total, List<Debts> selectedDebts);
    }

    public void setOnTotalChangedListener(OnTotalChangedListener listener) {
        this.listener = listener;
    }

    private class ViewHolder {

        TextView concept, descriptionOrDate, amount, expirationDate;
        CheckBox checkBox;
    }
}

这是我的片段代码:

public class CheckoutFragment extends BaseFragment implements View.OnClickListener, ServicesFinancialStatusAdapter.OnTotalChangedListener {

    public static final String TAG = CheckoutFragment.class.getSimpleName();

    private List<Debts> debtsList;
    private List<Debts> selectedDebts;
    private ServicesFinancialStatusAdapter adapter;
    private TextView totalView, positiveBalanceView;
    private View noDebtsView, header, footer;
    private LinearLayout mainLayout;

    private float total, positiveBalance;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);

        debtsList = new ArrayList<Debts>();
        adapter = new ServicesFinancialStatusAdapter(getActivity(), debtsList, 5);
        adapter.setOnTotalChangedListener(this);

        webServices = ((MainActivity) getActivity()).getNetworkInstance();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        //Initialize the views
        ...

        reloadData();
        onTotalChanged(0, null);

        return view;
    }

    @Override
    public void onClick(View view) {
        reloadData();
    }

    @Override
    public void onTotalChanged(float total, List<Debts> selectedDebts) {

        this.total = total == 0 ? total : total - positiveBalance;
        this.selectedDebts = selectedDebts;
        totalView.setText(getString(R.string.total_indicator) + Utilities.formatNumberAsMoney(this.total));
        getActivity().invalidateOptionsMenu();
    }

    private void reloadData() {
        debtsList.clear();
        adapter = new ServicesFinancialStatusAdapter(getActivity(), debtsList, 5);
        adapter.setOnTotalChangedListener(this);
        loadData();
    }

    private void loadData() {
        //Load debts from server
        ...
    }

    private void saveSelectedDebts() {

        for (Debts selectedDebt : selectedDebts) {
            long id = Debts.insert(getActivity(), selectedDebt);
            //Log.d(TAG, "Inserted " + selectedDebt.getConcept() + " with ID " + id);
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);

        if (!((MainActivity) getActivity()).drawerIsOpen) {
            inflater.inflate(R.menu.checkout, menu);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

            case R.id.clear:
                adapter.unMarkDebts();
                break;

            case R.id.checkout:
                selectPaymentMode();
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    private void selectPaymentMode() {

        ...
    }
}

1 个答案:

答案 0 :(得分:1)

聊天破了。我认为一项调查可能是:

每当你调用reload时,你都会使用一个新对象从scracth启动适配器,(call method new)。删除该行并使用以前的适配器(负责在onCreate上启动适配器)。请注意,可变的selectedDebts是适配器的本地,并且您没有在构造函数中传递它。