2

aufgerufen Ich habe folgende Links für die Aktualisierung von Daten gelesen, wenn Datenbank geändert wird.Android: Update Recyclerview ITEM, wenn ContentObserver

So ist es erfolgreich mit ContentObserver getan und mein Fragment bekommen mit, dass die notifizierten und ich habe RecyclerView durch folgenden Weg aktualisiert.

/** 
* A simple {@link Fragment} subclass. 
*/ 
public class OrderListFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { 

    /** 
    * Cursor Loader ID 
    */ 
    private int LOADER_ID = 2; 

    /** 
    * Observer... 
    */ 
    OrderObserver orderObserver = null; 

    @Override 
    public void onResume() { 
     super.onResume(); 
     /** 
     * Observer Declaration... 
     */ 
     orderObserver = new OrderObserver(new Handler()); 
     LOGD("Registered......"); 
     getActivity().getContentResolver().registerContentObserver(KOOPSContentProvider.CONTENT_URI_ORDER, true, orderObserver); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     if (orderObserver != null) { 
      LOGD("Unregistered..."); 
      getActivity().getContentResolver().unregisterContentObserver(orderObserver); 
     } 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 

     View view = inflater.inflate(R.layout.fragment_order_list, container, false); 

     orderListBinding = DataBindingUtil.bind(view); 

     /** 
     * Getting Context 
     */ 
     mContext = getActivity().getApplicationContext(); 

     /** 
     * Setup with RecyclerView 
     */ 
     layoutManager = new HPLinearLayoutManager(mContext); 

     /** 
     * Adapter... 
     */ 
     orderListAdapter = new OrderRecyclerAdapter(mContext, orderCursor); 

     /** 
     * RecyclerView Binding 
     */ 
     orderListBinding.orderListRecyclerView.setLayoutManager(layoutManager); 
     orderListBinding.orderListRecyclerView.setHasFixedSize(true); 
     orderListBinding.orderListRecyclerView.setAdapter(orderListAdapter); 

     /** 
     * First Time init Loader 
     */ 
     orderQueryData = new Bundle(); 
     orderQueryData.putString("searchString", ""); 

     /** 
     * Adding Bundle in Loader and then Call 
     */ 
     getActivity().getSupportLoaderManager().initLoader(LOADER_ID, orderQueryData, this); 

     /*********************************/ 
     // Inflate the layout for this fragment 
     return view; 
    } 



    /** 
    * Get Data From Local 
    */ 
    private void getDataFromLocal() { 
     /** 
     * Adding Bundle in Loader and then Call 
     */ 
     getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, orderQueryData, this); 
    } 

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     final Uri CONTENT_URI = KOOPSContentProvider.CONTENT_URI_ORDER.buildUpon() 
       .appendQueryParameter(KOOPSContentProvider.QUERY_PARAMETER_OFFSET, String.valueOf(offset)) 
       .build(); 

     return new CursorLoader(mContext, CONTENT_URI, null, null, null, null); 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 

     int length = data.getCount(); 

     LOGD("Length of Orders in Local : " + length); 

      /*** 
      * Binding Data to Adapter 
      * OFFSET is 0 whenever search for orders of sync 
      */ 
      if (offset == 0) { 
       ((OrderRecyclerAdapter) orderListBinding.orderListRecyclerView.getAdapter()).swapCursor(data); 
      } else { 
       Cursor cursor = ((OrderRecyclerAdapter) orderListBinding.orderListRecyclerView.getAdapter()).getCursor(); 

       //fill all existing in adapter 
       ArrayList<String> first = new ArrayList<>(Arrays.asList(Order.ORDER_COLUMNS)); 
       first.add("amount"); 

       MatrixCursor mx = new MatrixCursor(first.toArray(new String[first.size()])); 
       fillMx(cursor, mx); 

       //fill with additional result 
       fillMx(data, mx); 
       ((OrderRecyclerAdapter) orderListBinding.orderListRecyclerView.getAdapter()).swapCursor(mx); 
      } 

      /** 
      * Check Length of Data from Local 
      */ 

    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 

    } 

    /** 
    * Merging New Cursor with Old Cursor... 
    * 
    * @param data data 
    * @param mx matrix cursor 
    */ 
    private void fillMx(Cursor data, MatrixCursor mx) { 
     if (data == null) 
      return; 

     data.moveToPosition(-1); 

     while (data.moveToNext()) { 
      mx.addRow(new Object[]{ 

        data.getString(data.getColumnIndex(MOBILE_ID)), 
        data.getString(data.getColumnIndex(SERVER_ID)), 
        data.getString(data.getColumnIndex(ORDER_ORDER_DATE)), 
        data.getString(data.getColumnIndex(ORDER_ACCOUNT_ID)), 
        data.getString(data.getColumnIndex(ORDER_CREATED_BY)), 
        data.getString(data.getColumnIndex(ORDER_ORDER_STATUS)), 
        data.getString(data.getColumnIndex(ORDER_SEEN)), 
        data.getString(data.getColumnIndex(ORDER_ITP)), 
        data.getString(data.getColumnIndex(ORDER_UTP)), 
        data.getString(data.getColumnIndex(ORDER_MITP)), 
        data.getString(data.getColumnIndex("amount")), 
      }); 
     } 
    } 

    /** 
    * My Observer.... 
    */ 
    class OrderObserver extends ContentObserver { 

     /** 
     * Creates a content observer. 
     * 
     * @param handler The handler to run {@link #onChange} on, or null if none. 
     */ 
     OrderObserver(Handler handler) { 
      super(handler); 
     } 

     @Override 
     public void onChange(boolean selfChange) { 
      this.onChange(selfChange, null); 
      LOGD("Changed....."); 
      // Override this method to listen to any changes 
     } 

     @Override 
     public void onChange(boolean selfChange, Uri uri) { 
      // depending on the handler you might be on the UI 
      // thread, so be cautious! 
      LOGD("Changed....." + uri); 
      offset = 0; 
      hasLocal = true; 
      getDataFromLocal(); 

      // HERE I WANT TO DO SOMETHING LIKE CHANGE VALUES ONLY WHICH ROW IS UPDATED...... 
      // HOW CAN I UPDATE ROW ONLY...... 

     } 
    } 
} 

Derzeit Was mache ich gerade alle Datensätze aus der Datenbank aktualisieren? Wie kann ich die Zeile aktualisieren, die in der Datenbank eingefügt/aktualisiert wurde? Ich möchte nicht ganze RecyclerView aktualisieren?

Gibt es einen Mechanismus, um nur aktualisierte Zeile in ContentObserver zu benachrichtigen?

Antwort

0

In Ihrer onChange-Methode erhalten Sie einen Uri-Parameter, der angibt, was sich geändert hat.

Wenn Ihr Inhaltsanbieter korrekt ausgeführt wurde, sollte der URI eindeutig identifizieren, was sich geändert hat. Zum Beispiel, wenn Sie eine Tabelle items haben und die uri content://com.application.sample/items/42 empfangen, dann wissen Sie, dass es Element # 42 ist, das sich geändert hat.

Wenn Sie Sie Content Provider ändern können, könnten Sie gehen sogar noch weiter und haben unterschiedliche Uris zu wissen, was die Änderung:

  • content://com.application.sample/items/42/deleted
  • content://com.application.sample/items/42/inserted
  • content://com.application.sample/items/42/updated

Verwendung diese können Sie die relevanten notify??? Methoden auf Ihrem Adapter auslösen.