自定义无尽ListView Android

时间:2012-08-27 03:40:31

标签: android listview android-listview baseadapter

我正在尝试做无尽的适配器但无法完成它,因此我的应用程序崩溃了。 我试图做的是,最初我想在listview中加载10items并在listview的末尾添加foorterview。如果用户点击了footerview,那么在listview中加载了10个以上的项目。

但是,当我开始该活动时,只会出现footerview,几秒钟后应用程序崩溃。 我已在下面发布了相关代码:

int questionsPerPage = 10;
boolean loadingMore = false;
ArrayList<DataHolder> myquestionsResults;
QuestionListViewAdapter adapter;

//in onCreate
lv = (ListView) findViewById(R.id.lv_questions);
    // add the footer before adding the adapter, else the footer will not
    // load!
    View footerView = ((LayoutInflater) this
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
            R.layout.listfooter, null, false);
    footerView.setOnClickListener(new OnClickListener() {

        public void onClick(View arg0) {
            Thread thread = new Thread(null, loadMoreListItems);
            thread.start();
        }
    });
    lv.addFooterView(footerView);
    myquestionsResults = new ArrayList<DataHolder>();
    adapter = new QuestionListViewAdapter(this, myquestionsResults);
    lv.setAdapter(adapter);
    lv.setOnItemClickListener(new OnItemClickListener() {

        public void onItemClick(AdapterView<?> a, View v, int position,
                long id) {
            Object o = lv.getItemAtPosition(position);
            DataHolder fullObject = (DataHolder) o;
            Intent intent = new Intent(getApplicationContext(),
                    ViewMyQuestion.class);
            intent.putExtra("id", fullObject.getId());
            startActivity(intent);

        }

    });

    // Load the first 10 items
    Thread thread = new Thread(null, loadMoreListItems);
    thread.start();
}// End of onCreate

private ArrayList<DataHolder> GetMyQuestionsResult() {
    ArrayList<DataHolder> myquestionInfo = new ArrayList<DataHolder>();
    HashMap<String, String> hm = new HashMap<String, String>();
    db = new DatabaseHandler(getApplicationContext());
    db.getReadableDatabase();
    hm = db.getUserDetails();
    db.close();
    String un = hm.get("username");

    uf = new UserFunctions();
    JSONArray json = uf.getQuestionsByUsername(un);
    int x = json.length();
    try {
        if (x > 0) {
            for (int i = 0; i < x; i++) {
                ja = json.getJSONArray(i);
                id = ja.getString(0);
                userName = ja.getString(1);
                question = ja.getString(2);
                tag1 = ja.getString(3);
                tag2 = ja.getString(4);
                tag3 = ja.getString(5);
                posted_on = ja.getString(6);
                DataHolder qih = new DataHolder();
                qih.setId(id);
                qih.setUserName(userName);
                qih.setQuestion(question);
                qih.setTag1(tag1);
                qih.setTag2(tag2);
                qih.setTag3(tag3);
                qih.setQuestionPostedOn(posted_on);
                myquestionInfo.add(qih);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();

    }
    return myquestionInfo;
}
// Runnable to load the items
private Runnable loadMoreListItems = new Runnable() {
    public void run() {
        // Set flag so we cant load new items 2 at the same time
        loadingMore = true;

        // Reset the array that holds the new items


        // Get 10 new listitems
        for (int i = 0; i < questionsPerPage; i++) {
            // Fill the item with some bogus information
            myquestionsResults.add(GetMyQuestionsResult().get(i));

        }

        // Done! now continue on the UI thread
        runOnUiThread(returnRes);

    }
};

// Since we cant update our UI from a thread this Runnable takes care of
// that!
private Runnable returnRes = new Runnable() {
    @SuppressWarnings("unchecked")
    public void run() {

        // Tell to the adapter that changes have been made, this will cause
        // the list to refresh
        ((BaseAdapter) lv.getAdapter()).notifyDataSetChanged();

        // Done loading more.
        loadingMore = false;
    }
};

以下是我的logcat消息:

08-27 06:00:03.799: E/AndroidRuntime(280): FATAL EXCEPTION: main
08-27 06:00:03.799: E/AndroidRuntime(280): java.lang.ClassCastException:    android.widget.HeaderViewListAdapter
08-27 06:00:03.799: E/AndroidRuntime(280):  at com.vervecoders.cuqu.MyQuestions$3.run(MyQuestions.java:275)
08-27 06:00:03.799: E/AndroidRuntime(280):  at android.os.Handler.handleCallback(Handler.java:587)
08-27 06:00:03.799: E/AndroidRuntime(280):  at android.os.Handler.dispatchMessage(Handler.java:92)
08-27 06:00:03.799: E/AndroidRuntime(280):  at android.os.Looper.loop(Looper.java:123)
08-27 06:00:03.799: E/AndroidRuntime(280):  at android.app.ActivityThread.main(ActivityThread.java:4627)
08-27 06:00:03.799: E/AndroidRuntime(280):  at java.lang.reflect.Method.invokeNative(Native Method)
08-27 06:00:03.799: E/AndroidRuntime(280):  at java.lang.reflect.Method.invoke(Method.java:521)
08-27 06:00:03.799: E/AndroidRuntime(280):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-27 06:00:03.799: E/AndroidRuntime(280):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-27 06:00:03.799: E/AndroidRuntime(280):  at dalvik.system.NativeStart.main(Native Method)

更新代码后,它再次崩溃。以下是新的logcat消息:

08-27 07:38:47.751: I/dalvikvm(349): "main" prio=5 tid=1 RUNNABLE
08-27 07:38:47.751: I/dalvikvm(349):   | group="main" sCount=0 dsCount=0 s=N obj=0x4001d8e0 self=0xccb0
08-27 07:38:47.751: I/dalvikvm(349):   | sysTid=349 nice=0 sched=0/0 cgrp=default handle=-1345026008
08-27 07:38:47.751: I/dalvikvm(349):   | schedstat=( 33038897911 15262681460 1352 )
08-27 07:38:47.751: I/dalvikvm(349):   at java.util.ArrayList.add(ArrayList.java:~123)
08-27 07:38:47.765: I/dalvikvm(349):   at com.vervecoders.cuqu.MyQuestions$3.run(MyQuestions.java:267)
08-27 07:38:47.765: I/dalvikvm(349):   at android.os.Handler.handleCallback(Handler.java:587)
08-27 07:38:47.771: I/dalvikvm(349):   at android.os.Handler.dispatchMessage(Handler.java:92)
08-27 07:38:47.771: I/dalvikvm(349):   at android.os.Looper.loop(Looper.java:123)
08-27 07:38:47.771: I/dalvikvm(349):   at android.app.ActivityThread.main(ActivityThread.java:4627)
08-27 07:38:47.785: I/dalvikvm(349):   at java.lang.reflect.Method.invokeNative(Native Method)
08-27 07:38:47.785: I/dalvikvm(349):   at java.lang.reflect.Method.invoke(Method.java:521)
08-27 07:38:47.785: I/dalvikvm(349):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-27 07:38:47.785: I/dalvikvm(349):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-27 07:38:47.785: I/dalvikvm(349):   at dalvik.system.NativeStart.main(Native Method)
08-27 07:38:47.811: D/AndroidRuntime(349): Shutting down VM
08-27 07:38:47.811: W/dalvikvm(349): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
08-27 07:38:47.845: E/AndroidRuntime(349): FATAL EXCEPTION: main
08-27 07:38:47.845: E/AndroidRuntime(349): java.lang.OutOfMemoryError
08-27 07:38:47.845: E/AndroidRuntime(349):  at java.util.ArrayList.add(ArrayList.java:123)
08-27 07:38:47.845: E/AndroidRuntime(349):  at com.vervecoders.cuqu.MyQuestions$3.run(MyQuestions.java:267)
08-27 07:38:47.845: E/AndroidRuntime(349):  at android.os.Handler.handleCallback(Handler.java:587)
08-27 07:38:47.845: E/AndroidRuntime(349):  at android.os.Handler.dispatchMessage(Handler.java:92)
08-27 07:38:47.845: E/AndroidRuntime(349):  at android.os.Looper.loop(Looper.java:123)
08-27 07:38:47.845: E/AndroidRuntime(349):  at android.app.ActivityThread.main(ActivityThread.java:4627)
08-27 07:38:47.845: E/AndroidRuntime(349):  at java.lang.reflect.Method.invokeNative(Native Method)
08-27 07:38:47.845: E/AndroidRuntime(349):  at java.lang.reflect.Method.invoke(Method.java:521)
08-27 07:38:47.845: E/AndroidRuntime(349):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-27 07:38:47.845: E/AndroidRuntime(349):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-27 07:38:47.845: E/AndroidRuntime(349):  at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:1)

((ArrayList<DataHolder>) lv.getAdapter()).add(myquestionsResults.get(i));

为什么要将适配器转换为ArrayList?这可能会导致ClassCastException

尝试将新项目添加到myquestionsResults,然后通知适配器。

更好的是,您可以在QuestionListViewAdapter的实现中添加方法add()(甚至addAll()),这会将项添加到列表中并调用notifyDataSetChanged()。在这种情况下,您可以使您的适配器成为成员变量并直接使用它,而不是从缓存的ListView中获取它。