簡體   English   中英

Android - 動態更改帶有 edittext 錯誤的列表 - LiveData + Room + ViewModel

[英]Android - dynamically change a list with an edittext error - LiveData + Room + ViewModel

我想根據編輯文本的文本動態更改列表。 下面的技術有效,但是當我在同一活動中多次更改時,我收到錯誤消息。 我認為隨着變化的增加,我需要觀察的倍數過多,但我還沒有替代方案的想法。 我指定我的列表視圖顯示照片,它是一個畫廊。 我不想要一個搜索按鈕,我希望它可以實時完成。

還有一個問題,當我進行搜索時,大約十分之一的顯示照片與其來源不匹配,當我顯示它時(打開一個顯示單張照片的活動),原始來源會顯示,或者當我在編輯文本里改了一個字母,原來的源又回來了,真的很奇怪。

先感謝您

帶有編輯文本的活動:

// RecyclerView
        RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getApplicationContext(), 3);
        recyclerView = findViewById(R.id.photo_album_recycler_view);
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(mAdapter);

        // ViewModel
        PhotoViewModel photoViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(PhotoViewModel.class);
        photoViewModel.getAllPhotos().observe(PhotoAlbumActivity.this, new Observer<List<Photo>>() {
            @Override
            public void onChanged(List<Photo> photos) {
                mAdapter.submitList(photos);
            }
        });

        edtSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                search = charSequence.toString().replaceAll(" ", "%");
                photoViewModel.getSearchPhotos(search).observe(PhotoAlbumActivity.this, photos -> mAdapter.submitList(photos));
            }

            @Override
            public void afterTextChanged(Editable editable) {
            }
        });

和錯誤:

W/oehpad.visiopa: Throwing OutOfMemoryError "Failed to allocate a 2132760 byte allocation with 2030720 free bytes and 1983KB until OOM, max allowed footprint 536870912, growth limit 536870912" (VmSize 2779292 kB)
E/AndroidRuntime: FATAL EXCEPTION: arch_disk_io_0
    Process: fr.visioehpad.visiopad, PID: 20843
    java.lang.RuntimeException: Exception while computing database live data.
        at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:92)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: android.database.sqlite.SQLiteException: unknown error (code 0 SQLITE_OK[0]): Native could not create new byte[]
        at android.database.CursorWindow.nativeGetBlob(Native Method)
        at android.database.CursorWindow.getBlob(CursorWindow.java:430)
        at android.database.AbstractWindowedCursor.getBlob(AbstractWindowedCursor.java:45)
        at fr.visioehpad.visiopad.data.repository.PhotoDao_Impl$6.call(PhotoDao_Impl.java:375)
        at fr.visioehpad.visiopad.data.repository.PhotoDao_Impl$6.call(PhotoDao_Impl.java:354)
        at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:90)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:764) 
I/Process: Sending signal. PID: 20843 SIG: 9

編輯 :

最后,我發現了一個問題,我使用彈出窗口進行搜索,但如果我使用 EditText 動態地使用它也是一樣的:

活動 :

// Get photos with the filter
photoViewModel.getPhotos().observe(this, new Observer<List<Photo>>() {
      @Override
      public void onChanged(List<Photo> photos) {
          mAdapter.submitList(photos);
      }
});

btnSearch.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
          searchPopup = new SearchPopup(PhotoAlbumActivity.this, search, "test");
          searchPopup.setOnBtnClickListener(new SearchPopup.OnBtnClickListener() {

              @Override
              public void OnValidClick(String texte) {

              // On vérifie si on laisse affiche le bouton pour annuler la recherche
              if (texte.isEmpty()){
                     btnRemoveSearch.setVisibility(View.INVISIBLE);
              } else {
                     btnRemoveSearch.setVisibility(View.VISIBLE);
              }

              search = texte;
              photoViewModel.refreshData(search);
              searchPopup.dismiss();
           }
       });
    }
});

視圖模型:


private MutableLiveData<List<Photo>> photos = new MutableLiveData<>();

public MutableLiveData<List<Photo>> getPhotos(){
      return photos;
}

/**
 * Actualisation des données lors d'une nouvelle recherche.
 * @param words les mots à rechercher
 */
public void refreshData(String words) {
    ExecutorService service =  Executors.newSingleThreadExecutor();
    service.submit(new Runnable() {
         @Override
         public void run() {
             List<Photo> freshPhotosList = mRepository.getSearchPhotos(DataSearchUtils.getTextForSearch(words));
                photos.postValue(freshPhotosList);
         }
    });
}

用於在房間中查詢的實用程序(我沒有在 SQL (LIKE + IN) 中找到等效的 CONTAINS):

public static String getTextForSearch(String search) {
    // init with percent to search all first or if search is empty
    String str = "%";
    if (!search.trim().isEmpty()) {
        str += search.replaceAll(" ", "%");
        str += "%";
    }
    return str;
}

存儲庫:

public List<Photo> getSearchPhotos(String chaine) {
    return mPhotoDao.getSearchPhotos(userId, chaine);
}

道:

@Query("SELECT * FROM photo_table " +
            "WHERE userId = :userId " +
            "AND ( (description LIKE :chaine) " +
            "OR (dateForSearch LIKE :chaine) " +
            "OR (contactFrom LIKE :chaine)) " +
            "ORDER BY date DESC")
List<Photo> getSearchPhotos(Long userId, String chaine); 

您必須添加兩個函數,一個在視圖模型類中並從視圖或活動(observe)調用它並命名(refreshAllPhotos()),另一個在回收器視圖適配器類中調用(updateAllPhotos()),以及每次在編輯文本中搜索時,此函數都應清除所有照片列表,但每次運行活動時都應調用刷新函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM