【发布时间】: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);
【问题讨论】:
-
乍一看,这似乎是一个类似的问题:stackoverflow.com/questions/16585221/…
标签: android mvvm android-room viewmodel android-livedata