iT邦幫忙

0

SQLite + material calendarview 的問題

我有一個問題想要詢問:
我是用Android studio 的Java
使用的資料庫是SQLite
我的想法是:讀取到SQLite資料庫裡面的其中一個欄位,這個欄位是日期的欄位,讀取到日期後,再將它轉成calendar的格式,例如:讀到了3/12,那它會在materialcalendarview的3/12的欄位裡面出現一個icon

但可能是我的觀念哪裡有不對,它可能只會抓取到最後一筆3/12的欄位,因我的資料庫裡面有一個是3/11,但在3/11的materialcalendarview 沒有出現icon

下方是我的程式碼,想要詢問是哪邊有漏掉了嗎?

 DH = new SQLdata(this);
        HashMap wordList = new HashMap();
        SQLiteDatabase db = DH.getReadableDatabase();
        String selectQuery = "SELECT * FROM TB2018";


        Cursor cursor = db.rawQuery(selectQuery, null);
        if(cursor.moveToFirst()){
            do{
                wordList.put("_date1", cursor.getString(1));
                wordList.put("_step1", cursor.getString(2));


                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
                String dateInString =cursor.getString(1);
                try {
                    date = sdf.parse(dateInString);
                    List<EventDay> events = new ArrayList<>();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(date);
                    events.add(new EventDay(calendar, R.drawable.ic_baseline_calendar_today_24));
                    CalendarView calendarView = (CalendarView) findViewById(R.id.calendarView);
                    calendarView.setEvents(events);
                    Log.i("sqlite", String.valueOf(date));
                } catch (ParseException e) {
                    e.printStackTrace();
                }

            }while(cursor.moveToNext());

謝謝

2 個回答

0
rogeryao
iT邦大師 1 級 ‧ 2021-03-17 15:28:58
最佳解答

請參閱 : android - SQLite查詢資料及使用Cursor物件@ Will的部落格
關鍵字 : c.moveToFirst(); // 移到第 1 筆資料

看更多先前的回應...收起先前的回應...

我有將我的程式碼改成:

        Cursor cursor = db.rawQuery(selectQuery, null);
        cursor.moveToFirst();

但結果還是一樣~~ 在日曆上,3/11 還是沒有辦法自動產生icon~~

rogeryao iT邦大師 1 級 ‧ 2021-03-17 16:24:47 檢舉

程式架構 :

        // 查詢tb_name資料表中的所有資料
        Cursor c=db.rawQuery("SELECT * FROM "+tb_name, null);   
        List<EventDay> events = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        // 若無資料, 則....  
        if (c.getCount()==0){   
            // 你想做的事
            // ......
        }
        // 若有資料
        if (c.getCount()>0){    
            // 移到第 1 筆資料 
            c.moveToFirst();     
            // 逐筆讀出資料              
            do{        
                // 你想做的事
                // ......
            } while(c.moveToNext());    // 有一下筆就繼續迴圈
        }        
        // 關閉資料庫
        db.close();  

抱歉!! 還是想要請問:程式碼大至上有改成像您貼的那樣子,結果還是一樣,欄位的值我有log, 都有抓到,但在material calendarview的icon一樣仍只有在3/12有set icon, 3/11則沒有出現~~~

       Cursor c=db.rawQuery("SELECT * FROM TB2018", null);
        List<EventDay> events = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
          if (c.getCount()>0){
              c.moveToFirst();
              do{
                  wordList.put("_date1", c.getString(1));
                  wordList.put("_step1", c.getString(2));

                  SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
                  String dateInString =c.getString(1);

                  try {
                      date = sdf.parse(dateInString);

                      calendar.setTime(date);
                      events.add(new EventDay(calendar, R.drawable.ic_baseline_calendar_today_24));
                      CalendarView calendarView = (CalendarView) findViewById(R.id.calendarView);
                      calendarView.setEvents(events);
                      Log.i("sqlite", c.getString(1));

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

              } while(c.moveToNext());

        }db.close();

謝謝

rogeryao iT邦大師 1 級 ‧ 2021-03-17 17:48:54 檢舉
        Cursor c=db.rawQuery("SELECT * FROM "+tb_name, null);   
        List<EventDay> events = new ArrayList<>();
        CalendarView calendarView = (CalendarView) findViewById(R.id.calendarView);

抱歉!! 它還是一樣仍只能set 最後一筆的icon. 但我有個問題想要詢問:在do 裡面執行撈資料庫裡面的資料時,它是一筆一筆的讀嗎?例如:先讀了第一筆的資料,執行完裡面要做的事才又再moveToNext()嗎? 還是說do 裡面就已經把資料庫裡面資料已全部撈出來了呢?

謝謝大家的幫忙,已OK了! 附上我程式碼。

 DH = new SQLdata(this);
        HashMap wordList = new HashMap();
        SQLiteDatabase db = DH.getReadableDatabase();
       
        Cursor c=db.rawQuery("SELECT * FROM TB2018", null);
        List<EventDay> events = new ArrayList<>();
        if (c.getCount()>0){
            c.moveToFirst();
            do{
                wordList.put("_date1", c.getString(1));
                wordList.put("_step1", c.getString(2));

                Calendar calendar = Calendar.getInstance();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
                String dateInString =c.getString(1);

                try {
                    date = sdf.parse(dateInString);

                    calendar.setTime(date);
                    events.add(new EventDay(calendar, R.drawable.ic_baseline_calendar_today_24));
                    CalendarView calendarView = (CalendarView) findViewById(R.id.calendarView);
                    calendarView.setEvents(events);
                    Log.i("sqlite", c.getString(1));

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

            } while(c.moveToNext());

        }db.close();
rogeryao iT邦大師 1 級 ‧ 2021-03-18 15:15:41 檢舉

calendarView.setEvents(events);
移到 while(c.moveToNext()); 下面

Cursor c=db.rawQuery("SELECT * FROM "+tb_name, null);   
List<EventDay> events = new ArrayList<>();
CalendarView calendarView = (CalendarView) findViewById(R.id.calendarView);
.................
.................
do{        
    // 你想做的事
    // ......
} while(c.moveToNext());    // 有一下筆就繼續迴圈
calendarView.setEvents(events); 

不行,它會出錯,錯誤原因:
2021-03-18 15:52:51.438 29467-29467/com.lab4416.htest5 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.lab4416.htest5, PID: 29467
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lab4416.htest5/com.lab4416.htest5.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.applandeo.materialcalendarview.CalendarView.setEvents(java.util.List)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3114)

早上我也有試過,calendarView要做的事情,一定要在while之前做,放到while之後才做的話,它都會出錯~~

1
海綿寶寶
iT邦大神 1 級 ‧ 2021-03-17 17:28:38

試試看搬幾列
原則是「只做一次的動件移到迴圈外面」
重點是「setEvents 只做一次」(才不會被最後一筆「蓋」掉)

DH = new SQLdata(this);
        HashMap wordList = new HashMap();
        SQLiteDatabase db = DH.getReadableDatabase();
        String selectQuery = "SELECT * FROM TB2018";


        Cursor cursor = db.rawQuery(selectQuery, null);
        if(cursor.moveToFirst()){

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
            List<EventDay> events = new ArrayList<>();
            Calendar calendar = Calendar.getInstance();
            CalendarView calendarView = (CalendarView) findViewById(R.id.calendarView);
            
            do{
                wordList.put("_date1", cursor.getString(1));
                wordList.put("_step1", cursor.getString(2));

                String dateInString =cursor.getString(1);
                try {
                    date = sdf.parse(dateInString);
                    calendar.setTime(date);
                    events.add(new EventDay(calendar, R.drawable.ic_baseline_calendar_today_24));                    
                    Log.i("sqlite", String.valueOf(date));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            } while(cursor.moveToNext());
            
       calendarView.setEvents(events);
}

今早我再重新的檢查過我的程式碼,並把這3行的程式碼調整到while 的下一行,它會直接出錯。或是再把它調整到while 的上一行,則一樣,它只讀取到最後一筆資料

 calendar.setTime(date);
                events.add(new EventDay(calendar, R.drawable.ic_baseline_calendar_today_24));
                calendarView.setEvents(events);

我只是覺得很想不懂,因我是看了這一篇的方式:https://thumbb13555.pixnet.net/blog/post/326337258-calendar-view

因這篇文章的作者有提到,沒設定執行緒時,它會出錯,原本我已為我可能可能我也是一樣的問題,但增加了執行緒,問題也仍是一樣~~

如果是用按日期的,例如我按了3/11,3/11會出現icon, 再按3/12,3/12也會出現icon,而且3/11的icon並不會被覆蓋過去。想不懂為什麼它沒有辦法完整的呈現。

我要發表回答

立即登入回答