У меня проблемы с получением правильных элементов после удаления элемента в моем 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, но оно является окончательным, ноЯ не уверен? И если в этом проблема, как мне ее исправить?