【问题标题】:Android - dynamically change a list with an edittext error - LiveData + Room + ViewModelAndroid - 动态更改带有edittext错误的列表 - LiveData + Room + ViewModel
【发布时间】:2020-10-17 21:40:36
【问题描述】:

我想根据编辑文本的文本动态更改列表。下面的技术有效,但是当我在同一个活动中多次更改时,我得到一个错误。我认为随着变化的增加,我观察到的倍数过多,但我还没有一个替代方案的想法。我指定我的列表视图显示照片,它是一个画廊。而且我不想要搜索按钮,我希望它能够实时完成。

还有一个问题,当我进行搜索时,大约十分之一的显示照片与其来源不匹配,当我显示它(打开显示单张照片的活动)时,原始来源会显示,或者当我在编辑文本中更改一个字母时,原始来源又回来了,真的很奇怪。

提前谢谢你

带有编辑文本的活动:

// 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);
         }
    });
}

Util 用于房间中的查询(我没有在 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); 

【问题讨论】:

标签: android mvvm android-room viewmodel android-livedata


【解决方案1】:

您必须添加两个函数,一个在视图模型类中并从视图或活动中调用它(观察)并命名它(refreshAllPhotos()), 回收器视图适配器类中的另一个函数称为 (updateAllPhotos()),此函数应在每次在编辑文本中搜索时清除所有照片列表,但刷新函数应在每次运行时调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    相关资源
    最近更新 更多