带有改造和 mvvm android 的搜索功能

问题描述 投票:0回答:1

我有一个 Android 应用程序,我在其中使用 MVVM 和 Retrofit。
我想在这个应用程序中应用搜索,我有一个用于搜索的 api,并且 api 通过邮递员正确返回结果,但是当我尝试在 android 中构建它时,我感到很困惑,因为我得到了错误的结果。 这是我的代码
SearchRepo.java

public class SearchRepo {
    private Application application;
    private ApiService apiService;

    public SearchRepo(Application application) {
        this.application = application;
        this.apiService = RetrofitClient.getClient(BASE_URL)
                .create(ApiService.class);
    }

    public void SearchForKeyWord(String lang, String keyword, int perPage,
                                 SearchRepositoryCallBack<ProductModel> callBack) {
        apiService.search(lang,keyword,perPage)
                .enqueue(new Callback<ProductModel>() {
                    @Override
                    public void onResponse(Call<ProductModel> call, Response<ProductModel> response) {
                        if (response.isSuccessful()) {
                            callBack.onSuccess(response.body());
                        } else {
                            callBack.onFailure("Error : "+response.code());
                        }
                    }

                    @Override
                    public void onFailure(Call<ProductModel> call, Throwable t) {
                        callBack.onFailure("Error : "+t.getMessage());
                    }
                });
    }

    public interface SearchRepositoryCallBack<T> {
        void onSuccess(T post);
        void onFailure(String error);
    }
}

SearchViewModel.java

public class SearchViewModel extends AndroidViewModel {
    private SearchRepo search;
    private MutableLiveData<ProductModel> searchResult = new MutableLiveData<>();
    public SearchViewModel(@NonNull Application application) {
        super(application);
        this.search = new SearchRepo(application);
    }

    public void searchProducts(String lang,String keyword,int perPage) {
        search.SearchForKeyWord(lang, keyword, perPage, new SearchRepo.SearchRepositoryCallBack<ProductModel>() {
            @Override
            public void onSuccess(ProductModel post) {
                searchResult.postValue(post);
            }

            @Override
            public void onFailure(String error) {
                Log.e(APITAG,error);
            }
        });
    }

    public LiveData<ProductModel> getSearchResult() {
        return searchResult;
    }
}

searchFragment.java中的搜索方法

private void search(String lang, String keyword, int perPage) {
        productViewModel.searchProduct(lang,keyword,perPage);
        productViewModel.getResultList().observe(getViewLifecycleOwner(), new Observer<ProductModel>() {
            @Override
            public void onChanged(ProductModel productModel) {
                List<Product> mlist = productModel.getData();
                for (int i=0;i<mlist.size();i++) {
                    System.out.println(i);
                    System.out.println("My List "+mlist.size());
                    System.out.println("My List "+mlist.get(i).getName());
                }
                System.out.println("=====================================");
            }
        });
    }

当我输入文本进行搜索时,我会得到正确的结果,但是如果我删除该单词并尝试编写另一个单词,我会得到旧的结果和正确的结果,结果的数量呈指数级增长。
示例

1
======
input -> m
expected -> "moon" , "mine"
actual output -> "moon" , "mine"
=====================
2
======
input -> a
expected -> "apple" , "alpha"
actual output -> "moon" , "mine" , "apple" , "alpha" , "apple" , "alpha"
====================
3
======
input -> l
expected -> "locus" , "lord"
actual output -> "apple" , "alpha" , "apple" , "alpha" , "locus" , "lord" , "locus" , "lord"

那么问题是什么以及如何解决它

java android mvvm retrofit
1个回答
0
投票

每次在片段中调用

search(String lang, String keyword, int perPage)
时,您都会创建一个新的观察者,因此,第一次调用搜索函数时,您有一个观察者,第二次您有两个观察者,依此类推。它们都处于活动状态并工作,直到片段死亡,因此它们打印
searchResult
mutableLiveData 发出的新数据。

您必须只有一个观察者来观察您的

searchResult
可变实时数据,因此请将这段代码放入您的
onCreateView()
或任何其他在片段的整个生命周期中调用一次的函数中。

productViewModel.getResultList().observe(getViewLifecycleOwner(), new Observer<ProductModel>() {
            @Override
            public void onChanged(ProductModel productModel) {
                List<Product> mlist = productModel.getData();
                for (int i=0;i<mlist.size();i++) {
                    System.out.println(i);
                    System.out.println("My List "+mlist.size());
                    System.out.println("My List "+mlist.get(i).getName());
                }
                System.out.println("=====================================");
            }
        });

要搜索新字符串,只需使用以下代码:

productViewModel.searchProduct(lang,keyword,perPage);

不要创建新的观察者来获取新结果,新结果将可以在您在

onCreateView()
中创建的之前的观察者上访问。

© www.soinside.com 2019 - 2024. All rights reserved.