IndexOutOfBound when grabbing a filtered item from a custom list
I created a custom listview that generates the correct data, but when I try to search for a specific element by its name, it returns the correct element, but then crashes after 1 second due to an IndexOutOfBoundException, not really sure why I initialized all the arrays to what I want size.
ListView listView;
int[] boss_icon = {R.drawable.boss_1, R.drawable.boss_2, R.drawable.boss_3,
R.drawable.boss_4, R.drawable.boss_5, R.drawable.boss_6, R.drawable.boss_7,
R.drawable.boss_8, R.drawable.boss_9, R.drawable.boss_10, R.drawable.boss_11,
R.drawable.boss_12, R.drawable.boss_13, R.drawable.boss_14, R.drawable.boss_15,
R.drawable.boss_16, R.drawable.boss_17, R.drawable.boss_18};
String[] boss_title= new String[18];
BossAdapter adapter;
String[] bossTime= new String[18];
Handler handler;
String[] bossAppearance= new String[18];
EditText search_view;
ArrayList<Boss> bossList;
int bossID;
private int getID(String name){
int id = 0;
switch(name){
case "๋คํฌ ์ง๋ํธ":
id = 0;
return id;
case "๋จธ์ฌ๋ง":
id = 1;
return id;
case "MARK52 ALPHA":
id = 2;
return id;
case "๊นกํจ ๋ฐ๋ผํ":
id = 3;
return id;
case "๋ฐ๋ธ๋ฆฐ ์๋ฆฌ์ด":
id = 4;
return id;
case "๋์":
id = 5;
return id;
case "์ํผ":
id = 6;
return id;
case "์์ด์ธํธ ๋ผ๋ฐ์์ด":
id = 7;
return id;
case "๋๋":
id = 8;
return id;
case "๋ ๋ฒ๋ํธ ์ข๋น":
id = 9;
return id;
case "์ฐ๋ฅด์":
id = 10;
return id;
case "๋ถ๊ธฐ์ฝ๋ฆฌ":
id = 11;
return id;
case "๊ทธ๋ฆฌํฐ":
id = 12;
return id;
case "ํ๋์ผ๋ค๋จ":
id = 13;
return id;
case "๊ฒฝ๋น๋์ฅ ์ฐจ์ฐ":
id = 14;
return id;
case "๊ทธ๋ฆฌํผ๋":
id = 15;
return id;
case "๋งค๋์ค๋ค๋จ":
id = 16;
return id;
case "์์ด์ธํธ ํฐํ":
id = 17;
return id;
}
return id;
}
private void createListview(){
listView = (ListView) findViewById(R.id.list_view);
search_view = (EditText)findViewById(R.id.search_text);
boss_title = getResources().getStringArray(R.array.boss_array);
bossList = new ArrayList<Boss>();
adapter = new BossAdapter(getApplicationContext(), bossList);
listView.setAdapter(adapter);
listView.setTextFilterEnabled(true);
bossTime = getKoreanTime();
// Moved our object creation here, so that it should only be done once.
for (String boss : boss_title) {
bossID = getID(boss);
bossAppearance = bossAppearance(bossID);
Boss bossObject = new Boss(boss_icon[bossID], boss, bossTime[bossID], bossAppearance[bossID]);
bossList.add(bossObject);
}
handler = new Handler();
Runnable update = new Runnable() {
@Override
public void run() {
bossTime = getKoreanTime();
int count = adapter.getCount();
for(String boss: boss_title){
bossID = getID(boss);
bossAppearance = bossAppearance(bossID);
((Boss) adapter.getItem(bossID)).setBoss_time(bossTime[bossID]); // Re-set time
((Boss) adapter.getItem(bossID)).setBoss_appearance(bossAppearance[bossID]);
}
adapter.notifyDataSetChanged(); // Notify our update
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(update, 10);
EditText myFilter = (EditText) findViewById(R.id.search_text);
myFilter.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
}
});
}
strings.xml
Boss Timer
<string-array name="boss_array">
<item>๋คํฌ ์ง๋ํธ</item>
<item>๋จธ์ฌ๋ง</item>
<item>MARK52 ALPHA</item>
<item>๊นกํจ ๋ฐ๋ผํ</item>
<item>๋ฐ๋ธ๋ฆฐ ์๋ฆฌ์ด</item>
<item>๋์</item>
<item>์ํผ</item>
<item>์์ด์ธํธ ๋ผ๋ฐ์์ด</item>
<item>๋๋</item>
<item>๋ ๋ฒ๋ํธ ์ข๋น</item>
<item>์ฐ๋ฅด์</item>
<item>๋ถ๊ธฐ์ฝ๋ฆฌ</item>
<item>๊ทธ๋ฆฌํฐ</item>
<item>ํ๋์ผ๋ค๋จ</item>
<item>๊ฒฝ๋น๋์ฅ ์ฐจ์ฐ</item>
<item>๊ทธ๋ฆฌํผ๋</item>
<item>๋งค๋์ค๋ค๋จ</item>
<item>์์ด์ธํธ ํฐํ</item>
</string-array>
LogCat
07-24 17:11:18.628 11159-11159/baegmon.com.bosstimer E/AndroidRuntime๏น FATAL EXCEPTION: main
Process: baegmon.com.bosstimer, PID: 11159
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at baegmon.com.bosstimer.BossAdapter.getItem(BossAdapter.java:38)
at baegmon.com.bosstimer.MainActivity$1.run(MainActivity.java:158)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
source to share
This is problem!
bossList = new ArrayList<Boss>();
adapter = new BossAdapter(getApplicationContext(), bossList);
You fill in the bossList after passing it to the adapter!
for (String boss : boss_title) {
bossID = getID(boss);
bossAppearance = bossAppearance(bossID);
Boss bossObject = new Boss(boss_icon[bossID], boss, bossTime[bossID], bossAppearance[bossID]);
bossList.add(bossObject);
}
Strike> Looks like I was wrong, the problem might be in the resource R.array.boss_array!
After viewing a resource, might there be an encoding issue? One entry: <item>MARK52 ALPHA</item>
and all others are in Korean. Could this be causing the problem?
Try changing one of the values โโto something like "example" and run it again. If the error says the array size is 2, that's your problem.
You should also call adapter.notifyDataSetChanged();
after adding or removing items from the list!
source to share
You forgot to notify the adapter to change the dataset.
// Moved our object creation here, so that it should only be done once.
for (String boss : boss_title) {
...
}
adapter.notifyDataSetChanged(); // This is required
To avoid confusion, the above loop is the first shown in the code.
source to share
Here's the problem, boss_title has 18 items. You try to loop over from 0 to 18, after which you end up with the nth item that is not in the list.
((Boss) adapter.getItem(bossID)).setBoss_time(bossTime[bossID]);
bossID could be something else that is larger than the size of the list
....
for(String boss: boss_title){
bossID = getID(boss);
bossAppearance = bossAppearance(bossID);
((Boss) adapter.getItem(bossID)).setBoss_time(bossTime[bossID]); // Re-set time
((Boss) adapter.getItem(bossID)).setBoss_appearance(bossAppearance[bossID]);
}
source to share