26

Vì vậy, tôi có MainDisplayActivity thực hiện cả hai ActivityLoaderManager.LoaderCallbacks<Cursor>. Ở đây tôi có A ListView, tôi điền thông tin về Chương trình làm việc mà tôi nhận được từ cơ sở dữ liệu của mình bằng cách sử dụng Trình cung cấp nội dung. Tôi cũng có một GridView là một lịch. Tôi đã thiết lập nó khi nhấp vào một ô, chương trình làm việc được cập nhật với ngày được nhấp. Vấn đề của tôi là khi tái sử dụng Loader tôi tạo ra trong onCreate() bên trong của setOnItemClickListener(), nó không làm mới thông tin với con trỏ mới mà tôi đang tạo ra. Tôi chỉ có thể tạo Trình tải mới với một ID khác và nó hoạt động một lần, nhưng khi tôi nhấp vào một ngày khác, nó sẽ ngừng làm mới. Vấn đề nằm ở con trỏ. Làm cách nào để làm mới con trỏ từ Trình tải để tôi không phải tiếp tục tạo Trình tải mới? Cảm ơn trước!Làm cách nào để làm mới con trỏ từ Trình tải trang CursorLoader?

gọi ban đầu để tạo ra các Loader trong onCreate() trong lớp MainDisplayActivity của tôi:

makeProviderBundle(new String[] {"_id, event_name, start_date, start_time, end_date, end_time, location"}, 
      "date(?) >= start_date and date(?) <= end_date", new String[]{getChosenDate(), getChosenDate()}, null); 
    getLoaderManager().initLoader(0, myBundle, MainDisplayActivity.this); 

    list.setAdapter(agendaAdapter); 

Đây là những phương pháp ghi đè từ LoaderCallbacks<Cursor>

@Override 
public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    Uri baseUri = SmartCalProvider.CONTENT_URI; 
    return new CursorLoader(this, baseUri, args.getStringArray("projection"), 
      args.getString("selection"), args.getStringArray("selectionArgs"), args.getBoolean("sortOrder") ? args.getString("sortOrder") : null); 
} 



@Override 
public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) { 
    agendaAdapter.swapCursor(arg1); 
} 



@Override 
public void onLoaderReset(Loader<Cursor> arg0) { 
    //Not really sure how this works. Maybe I need to fix this here? 
    agendaAdapter.swapCursor(null); 

} 

public void makeProviderBundle(String[] projection, String selection, String[] selectionArgs, String sortOrder){ 
    /*this is a convenience method to pass it arguments 
    * to pass into myBundle which in turn is passed 
    * into the Cursor loader to query the smartcal.db*/ 
    myBundle = new Bundle(); 
    myBundle.putStringArray("projection", projection); 
    myBundle.putString("selection", selection); 
    myBundle.putStringArray("selectionArgs", selectionArgs); 
    if(sortOrder != null) myBundle.putString("sortOrder", sortOrder); 
} 

Bất kỳ mã bổ sung cần thiết xin vui lòng đừng ngần ngại hỏi . Cám ơn lần nữa cho bất kì sự giúp đỡ nào!

+0

Đó là kinh nghiệm của tôi khi bạn sử dụng 'ContentResolver' để cập nhật nội dung trong' ContentProvider' mà 'con trỏ' được thông báo và danh sách được cập nhật tự động. Bạn có thể đăng mã onClick của mình không? – stuckless

+0

Tôi biết đúng. Tôi cho rằng điều này là tốt vì mọi người đều nói điều đó thuận tiện đến mức nào. Nhưng nó không làm điều đó. Vấn đề là tôi cũng hiểu làm thế nào mà không thể làm việc. Khi 'Loader' được tạo đầu tiên, nó gọi' onCreateLoader() '. Khi gọi 'getLoaderManager(). InitLoader()', nếu arg đầu tiên, ID giống với 'Loader' được khởi tạo trước đó,' onCreateLoader() 'có thể sẽ không được gọi. Tất nhiên đây là suy đoán thuần túy về phía tôi khi tôi vẫn đang học, nhưng tôi đã nghĩ rằng phải có một phương pháp để tải một Con trỏ mới nếu đó là trường hợp. Alex đã đủ tốt để cung cấp nó! – Andy

Trả lời

40

Bạn chỉ cần di chuyển mã của mình xung quanh một chút và gọi restartLoader. Đó là,

  1. Khi người dùng nhấp vào một mục trong danh sách, bạn nào đó thay đổi biến dụ tin được trả về trong getChosenDate() (Tôi đang cố tình mập mờ ở đây bởi vì bạn không nói rõ những gì chính xác getChosenDate() lợi nhuận).

  2. Khi thay đổi được thực hiện, hãy gọi getLoaderManager().restartLoader() trên số Loader của bạn. Dữ liệu cũ của bạn sẽ bị hủy và restartLoader sẽ kích hoạt onCreateLoader để được gọi lại. Khoảng thời gian này, getChosenDate() sẽ trả lại một giá trị khác (tùy thuộc vào mục danh sách đã được nhấp) và điều đó sẽ thực hiện. thực hiện onCreateLoader bạn nên tìm một cái gì đó như thế này:

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
        Uri baseUri = SmartCalProvider.CONTENT_URI; 
    
        makeProviderBundle(
         new String[] { "_id, event_name, start_date, start_time, end_date, end_time, location" }, 
         "date(?) >= start_date and date(?) <= end_date", 
         new String[]{ getChosenDate(), getChosenDate() }, 
         null); 
    
        return new CursorLoader(
          this, 
          baseUri, 
          args.getStringArray("projection"), 
          args.getString("selection"), 
          args.getStringArray("selectionArgs"),  
          args.getBoolean("sortOrder") ? args.getString("sortOrder") : null); 
    } 
    

Hãy cho tôi biết nếu có ý nghĩa. :)

+0

Holy shiznit lol. Thats thiên tài haha. Tôi thấy những gì bạn đang nói. Vì vậy, phương thức mà tôi có thể gọi là 'restartLoader()'. Tại sao tôi không thấy phương pháp đó trong CursorLoader ?! Oh và xin lỗi, 'getChosenDate()' trả về một chuỗi ngày trong định dạng được sử dụng bởi cơ sở dữ liệu vì vậy tôi chỉ có thể làm tất cả các lọc với SQLite hơn là bằng mã java. – Andy

+0

Dude !!! Anh yêu em! Nó hoạt động rất đẹp. Và nhìn vào mã của tôi, tôi nhận ra trong 'myBundle.putString (" date ", getChosenDate());', nó không cần thiết. Vì vậy, tôi đã lấy nó đi. Tôi sẽ sử dụng nó khi gọi 'makeProviderBundle()'. Cảm ơn rất nhiều ... LẠI! – Andy

+11

Haha ... bạn dễ bị kích thích, phải không. Mừng vì tôi có thể giúp :). –

Các vấn đề liên quan