Оставшиеся позиции элементов в ListView неверны после удаления элементов - PullRequest
0 голосов
/ 28 сентября 2011

У меня проблемы с получением правильных элементов после удаления элемента в моем ListView.Позиция должна соответствовать индексу элемента в ArrayList, но после удаления элемента в ListView позиции неверны (и могут даже дать исключение indexoutofbounds.

Могу поспорить, что это как-то связано спозиция Views, но я просто не могу найти ошибку.

У меня есть этот класс ListActivity с внутренним классом BaseAdapter:

    public class MSMobilMyStocksActivity extends ListActivity {
    static MyStocksCtr myStocksCtr;
    static ListView listview;



    static EfficientAdapter adap;
    boolean downloadSuccess;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mystockslist);
        mContext = this;
        listview = getListView();
        myStocksCtr = MyStocksCtr.getInstance(mContext);

        adap = new EfficientAdapter(this);

        setListAdapter(adap);
        if (isOnline())
            new InsertDataTask().execute();
        else {
            startTimer();
            Toast.makeText(mContext, "Du har ingen internetforbindelse", 1000)
                    .show();
        }

    }

    public static boolean updateData() {
        return myStocksCtr.downloadJson();
    }

    private class InsertDataTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            try {
                listview.setEnabled(false);
            } catch (Exception e) {
            }
        }

        // can use UI thread here
        @Override
        protected void onPostExecute(final Void unused) {
            if (isOnline()) {
                if (downloadSuccess) {
                    try {
                        if (myStocksCtr.getArray().size() == 0) {
                            Toast.makeText(mContext, "Ingen data hentet", 2000)
                                    .show();
                        } else if (myStocksCtr.getArray().size() == 1
                                && myStocksCtr.getArray().get(0)
                                        .getString("FH_FULLNAME").equals("-")) {
                            Toast.makeText(mContext, "Ingen data hentet", 2000)
                                    .show();
                        } else {
                            adap.notifyDataSetChanged();
                        }
                    } catch (JSONException e) {
                        Toast.makeText(mContext, "JSONException", 2000).show();
                    }
                }
            } else
                Toast.makeText(mContext, "Du har ingen internetforbindelse",
                        1000).show();
            startTimer();
            try {
                listview.setEnabled(true);
            } catch (Exception e) {
            }
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            downloadSuccess = false;
            if (isOnline()) {
                try {
                    if (updateData())
                        downloadSuccess = true;
                } catch (Exception e) {
                    Toast.makeText(mContext, "Fejl under download af data",
                            2000).show();
                    downloadSuccess = false;
                }
            } else
                Toast.makeText(mContext, "Du har ingen internetforbindelse",
                        1000).show();

            return null;

        }
    }

    }

    public static class EfficientAdapter extends BaseAdapter implements
            Filterable {
        private LayoutInflater mInflater;
        private Context context;

        public EfficientAdapter(Context context) {
            mInflater = LayoutInflater.from(context);
            this.context = context;
        }


        @Override
        public View getView(final int position, View convertView,
                ViewGroup parent) {
            final ViewHolder holder;

            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.mylistitem, null);

                holder = new ViewHolder();
                holder.stockName = (TextView) convertView
                        .findViewById(R.id.stockName1);
                holder.stockPrice = (TextView) convertView
                        .findViewById(R.id.stockValue1);
                holder.stockChange = (TextView) convertView
                        .findViewById(R.id.stockChange1);
                holder.stockPctChange = (TextView) convertView
                        .findViewById(R.id.stockPctChange1);

                convertView.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {

                        try {
                            Intent i = new Intent(mContext, MSStockDetailActivity.class);
                            Bundle b = new Bundle();
                            b.putInt("position", position); //Your id
                            b.putBoolean("isMyStocks", true);
                            i.putExtras(b); //Put your id to your next Intent
                            mContext.startActivity(i);
                        } catch (Exception e) {
                            Toast.makeText(mContext, "OnClick error ", 2000)
                                    .show();
                        }
                    }
                });

                convertView.setOnLongClickListener(new OnLongClickListener() {

                    @Override
                    public boolean onLongClick(View arg0) {

                        final CharSequence[] items = {
                                "See stock details",
                                "Delete the stock \"" + holder.stockName.getText()
                                        + "\" from the list", "Cancel" };

                        AlertDialog.Builder builder = new AlertDialog.Builder(
                                mContext);
                        builder.setTitle("Configure list");
                        builder.setItems(items,
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog,
                                            int item) {
                                        if (item == 1) {
                                            myStocksCtr.removeStock(holder.ric);
                                            adap.notifyDataSetChanged();
                                        } else if (item == 2) {
                                        }
                                        Toast.makeText(mContext, items[item],
                                                Toast.LENGTH_SHORT).show();
                                    }
                                });
                        AlertDialog alert = builder.create();
                        alert.show();
                        return true;
                    }
                });

                convertView.setTag(holder);
            } else {

                holder = (ViewHolder) convertView.getTag();
            }
            try {
                String result = myStocksCtr.getArray().get(position)
                        .getString("FH_FULLNAME");
                holder.stockName.setText(result);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            try {
                String result = myStocksCtr.getArray().get(position)
                        .getString("FH_RIC");
                holder.ric = result;
            } catch (JSONException e) {
                e.printStackTrace();
            }
            // + String.valueOf(position));
            try {
                String result = myStocksCtr.getArray().get(position)
                        .getString("FH_PRC");
                if (String.valueOf(result.charAt(result.length() - 2)).equals(
                        ".")) {
                    result += "0";
                }
                ;
                holder.stockPrice.setText(result);

            } catch (JSONException e) {
                e.printStackTrace();
            }

            holder.position = position;

            return convertView;
        }

        static class ViewHolder {
            String ric;
            TextView stockName;
            TextView stockPrice;
            TextView stockPctChange;
            TextView stockChange;
            int position;

        }

        @Override
        public Filter getFilter() {
            return null;
        }

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

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

        @Override
        public JSONObject getItem(int position) {
            return myStocksCtr.getArray().get(position);
        }

    }

Это некоторые вещи из моего контроллера акций(где массив):

public class MyStocksCtr {

private static MyStocksCtr INSTANCE = null;

ArrayList<String> myStocksArray;
JSONCtr jsonCtr;
static Context mContext;
boolean isRunning = false;
ArrayList<JSONObject> myArray;

MyStocksCtr(Context mContext) {
    this.mContext = mContext;
    jsonCtr = new JSONCtr(mContext);
    myStocksArray = new ArrayList<String>();
    myArray = new ArrayList<JSONObject>();
    }
}

public static MyStocksCtr getInstance(Context context){
    mContext = context;
    if(INSTANCE == null) {
          INSTANCE = new MyStocksCtr(mContext);
       }
       return INSTANCE;
}

public ArrayList<JSONObject> getArray() {
    return myArray;
}

public boolean downloadJson() {
    if (!myStocksArray.isEmpty()) {
        String myStocksString = "";
        for (String s : myStocksArray)
            myStocksString += (s + "%2C");
        myStocksString = myStocksString.substring(0,
                myStocksString.length() - 3);
        jsonCtr.getJSON(preStocksUrl + myStocksString + postStocksUrl);
        myArray.clear();
        myArray.addAll(jsonCtr.getArray());
        return true;
    } else {
        return false;
    }
}


public void removeStock(String newStock) {
    JSONObject toRemove = null;

    for (JSONObject obj : myArray) {
        try {
            if (obj.getString("FH_RIC").equals(newStock)) {
                toRemove = obj;
            }
        } catch (JSONException e) {
            Toast.makeText(mContext, "Kunne ikke fjerne objekt", 1000)
                    .show();
        }
    }
    if (toRemove != null){
        myStocksArray.remove(newStock);
    jsonCtr.removeRic(toRemove);
    myArray = jsonCtr.getArray();
    saveMyStocks();
}
    }

    }

В моем jsonCtr я удаляю и получаю массив:

public ArrayList<JSONObject> getArray() {
    return rics1;
}

public void removeRic(Object o){
    rics1.remove(o);
}

Когда я удалил объект из списка, список обновится,поэтому элемента больше нет. Но позиции представлений все перепутаны, и некоторые из них находятся вне границ.

Я предполагаю, что это как-то связано с положением в GetView, но оно является окончательным, ноЯ не уверен? И если в этом проблема, как мне ее исправить?

1 Ответ

1 голос
/ 28 сентября 2011

Хм, я не смотрел на каждую деталь вашего кода, но думаю, что вам не хватает для вызова myAdaper. notifyDataSetChanged () после изменения массива.

Редактировать

Это действительно сложно смотреть, потому что вы публикуете здесь много кода. Так вот что я получил. Я не вижу, что здесь происходит (на складе удалить), но должно быть что-то не так, я думаю:

jsonCtr.removeRic(toRemove);
myArray = jsonCtr.getArray();

Пожалуйста, не публикуйте весь код этого тоже, постарайтесь свести его к реальной проблеме. Я не буду проверять весь код снова ...

...