从自定义列表视图中获取过滤项时出现IndexOutOfBound错误

3
我已经创建了一个自定义的ListView,可以生成正确的数据,但是当我尝试通过名称搜索特定项时,它返回正确的项,但1秒后由于IndexOutOfBoundException而崩溃,我不太确定为什么,因为我已经将所有数组初始化为正确的大小。 BossAdapter.java Boss.java
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计时器

<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)

请展示给我们这个: 在baegmon.com.bosstimer.BossAdapter.java文件的第38行的getItem方法。 - Roberto Anić Banić
@RobertoNicbaAnićBanić 抱歉,在适配器文件中进行了编辑。 - Simon Baeg
我们能看到 R.array.boss_array 吗? - Roberto Anić Banić
请问为什么您要使用handler来更新适配器数据?您试图在1000毫秒后更新值,而此时适配器计数可能会发生变化,请进行检查。 - bGorle
@bGorie 因为我正在进行时间倒计时,所以它需要不断更新。 - Simon Baeg
主要活动在第158行,我认为问题就出在那里的处理程序。注释掉处理程序代码,然后尝试搜索它,让我们看看会发生什么。 - bGorle
3个回答

0

这是问题!

bossList = new ArrayList<Boss>();
adapter = new BossAdapter(getApplicationContext(), bossList);

将bossList传递给适配器后,您可以填充它!

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

}

看起来我错了,问题可能出在 R.array.boss_array 资源上!

看到这个资源后,编码是否有问题呢? 其中一项为:<item>MARK52 ALPHA</item>,而其他所有内容都是韩文。这可能会引发问题吗?

尝试将其中一个值更改为 'example',然后再次运行。如果错误说数组大小为 2,则问题出在这里。

在列表中添加或删除项目后,您还应该调用 adapter.notifyDataSetChanged();


@Baegmon 如果这个答案解决了你的问题,请在15分钟后考虑将其标记为正确的答案!谢谢,祝你愉快! - Roberto Anić Banić
抱歉,我有些困惑,在for循环之前我向bossList中添加了什么? - Simon Baeg
将列表传递给适配器后填充列表是可以的。这是Android中的自然模式。您可以更新列表并在适配器上调用notifyDataSetChanged()。 - Hindol
我也尝试了你建议的方法,不管用什么语言,还是会出现错误。我还尝试在其他地方使用notifydataset changes,但仍然会出现错误 :/ - Simon Baeg
@Beagmon 但是错误信息现在是否显示为“索引2无效,大小为2”?如果再改变一个,它是否会显示为“索引3无效,大小为3”? - Roberto Anić Banić
显示剩余5条评论

0

您忘记通知适配器数据集的更改了。

// Moved our object creation here, so that it should only be done once.
for (String boss : boss_title) {
    ...
}
adapter.notifyDataSetChanged(); // This is required

为了避免任何混淆,上面的for循环是代码中显示的第一个


这是在第一个for循环之后吗?我已经在数据集更改后完成了这个。 - Simon Baeg
修改了我的回答。是的,这是第一个for循环。 - Hindol
尝试过了,仍然返回java.lang.IndexOutOfBoundsException:无效索引2,大小为2。 - Simon Baeg
请展示一下 MainActivity.java 文件中的第 158 行代码。 - Hindol
((Boss) adapter.getItem(bossID)).setBoss_appearance(bossAppearance[bossID]); - Simon Baeg

0

这里有个问题,boss_title有18个项目。你试图从0到18迭代循环,然后获取不在列表中的第n个项目。

((Boss) adapter.getItem(bossID)).setBoss_time(bossTime[bossID]);

bossID可能是另外一个大于列表大小的值

....

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

@bGorie 但是在 getID 方法中,我只返回分配给每个项目的数字 ID,那还会有问题吗? - Simon Baeg
是的,bossId可以从0到17,但是bossList的大小可能小于这个范围,因为您正在过滤数据。 - bGorle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接