使用PageKeyedDataSource的SearchView不显示任何结果甚至错误

时间:2018-09-21 11:38:06

标签: android android-recyclerview android-search android-viewmodel android-paging

我正在尝试在一个片段中创建一个searchview,该片段在搜索时会向后端api请求数据,因此将结果分页,因此我使用PageKeyedDataSource在回收者视图中显示结果。 因此,当我执行Search Query时,它不会显示任何结果,甚至不会显示任何错误或警告

如果我的代码有任何问题,请帮助我!1 我在这里呆了几个星期!!!

UI代码:

  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    val view =  inflater.inflate(R.layout.users_fragment, container, false)
    val context = getContext() ?: return view
    val adapter = UserAdapter(context)
    rec_view = view.findViewById<RecyclerView>(R.id.usersRecycler)
    rec_view.layoutManager = LinearLayoutManager(MyApplication.getContext())
    viewModel = viewModel()
    initAdapter()

    return  view
}

private fun initAdapter() {
    adapter = UserAdapter(context)
    rec_view.adapter = adapter
    viewModel.items.observe(this,object:Observer<PagedList<Result>>{
        override fun onChanged(t: PagedList<Result>?) {
            adapter.submitList(t)
            adapter.notifyDataSetChanged()
        }


    })
}

private fun viewModel():UsersViewModel {
    val viewModelFactory = InjectorUtils.provideUserViewModel(context!!)
    return ViewModelProviders.of(this,viewModelFactory)[UsersViewModel::class.java]
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setHasOptionsMenu(true)
}

override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
    inflater?.inflate(R.menu.options_menu,menu)
    var searchItem:MenuItem = menu!!.findItem(R.id.search)
    var searchManager = activity?.getSystemService(Context.SEARCH_SERVICE) as SearchManager
    searchView = SearchView((context as FeedActivity).supportActionBar?.themedContext ?: context)
    searchItem.apply {
        setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW or MenuItem.SHOW_AS_ACTION_IF_ROOM)
        actionView = searchView
    }

    if(searchView != null){

        searchView!!.setOnQueryTextListener(object:SearchView.OnQueryTextListener{
            override fun onQueryTextSubmit(query: String): Boolean {
                viewModel.items.observe(this@UsersFragment,object :Observer<PagedList<Result>>{
                    override fun onChanged(t: PagedList<Result>?) {
                        adapter.submitList(t)
                        adapter.notifyDataSetChanged()
                        Timber.d("ViewModel Observed inside OnQueryTextSubmit()")
                    }
                })
                Timber.d(query)
                return true
            }

            override fun onQueryTextChange(newText: String): Boolean {
                /*
                * Do Nothing
                * */
                return true
            }
        })

    }

适配器:

 public class UserAdapter extends PagedListAdapter<Result,UserAdapter.UserViewHolder>{

private Context ctx;
public UserAdapter(Context ctx) {
    super(diffCallback);
    this.ctx = ctx;
}

private static DiffUtil.ItemCallback<Result> diffCallback =
        new DiffUtil.ItemCallback<Result>() {
            @Override
            public boolean areItemsTheSame(Result oldItem, Result newItem) {
                return oldItem.getPk() == newItem.getPk();
            }

            @Override
            public boolean areContentsTheSame(Result oldItem, Result newItem) {
                return oldItem.equals(newItem);
            }
        };

@NonNull
@Override
public UserViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    Timber.d("onCreateViewHolder() --> Adapter");
    View view = LayoutInflater.from(ctx).inflate(R.layout.user_row,parent,false);

    return new UserViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull UserViewHolder holder, int position) {
    Timber.d("onBindViewHolder() --> Adapter");
    Result result = super.getItem(position);
    if(result != null){

        /**
         * Set Data to Views
         * using @{holder}
         * */
        holder.textView.setText(result.getUsername());

        Glide
                .with(ctx)
                .load(result.getProfilePic())
                .into(holder.imageView);
    }
    else {
        Toast.makeText(ctx,"result is null",Toast.LENGTH_LONG).show();
    }
}

public class UserViewHolder extends RecyclerView.ViewHolder {

    TextView textView ;
    ImageView imageView;
    public UserViewHolder(View itemView) {
        super(itemView);
        Timber.d("UserViewHOlder");
        textView = itemView.findViewById(R.id.username);
        imageView = itemView.findViewById(R.id.userImage);
    }
}
 }

ViewModel:

class UsersViewModel internal constructor(private val repository: UserRepository): ViewModel() {
private val searchQuery = MutableLiveData<String>()
private val userResult = map(searchQuery) {
    repository.showUsers(it)
}
val items = switchMap(userResult) { it.value as LiveData<PagedList<Result>> }
fun showSearchResults(searchQuery: String): Boolean {
    if (this.searchQuery.value == searchQuery) {
        return false
    }
    this.searchQuery.value = searchQuery
    return true
}


fun showResult(searchQuery: String): LiveData<PagedList<Result>> {
            return repository.showUsers(searchQuery)
}


}

数据源:

 class UserDataSource(private var param:String):PageKeyedDataSource<Int,Result>(){
companion object {
    private val apiClient = ApiClient.getApiClient().create(UserClient::class.java)
    var page = 1
}
private var query:String
var executor = Executors.newSingleThreadExecutor()
init {
    query = param

}

override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, Result>) {
    Timber.d(query+"loadInitial()")
    val call: Call<UserSearchResult> = apiClient.getUserData(page, query)
        call.enqueue(object : Callback<UserSearchResult> {
            override fun onFailure(call: Call<UserSearchResult>?, t: Throwable?) {
                Timber.d("loadInitial() failure")
            }

            override fun onResponse(call: Call<UserSearchResult>?, response: Response<UserSearchResult>?) {
                var user_result = response?.body()
                Log.d("loadInitial() --> ",response?.body().toString())
                if (user_result == null) {
                    onFailure(call, HttpException(response))
                    return
                }
                callback.onResult(
                        user_result.results,
                        0,
                        user_result.count,
                        null,
                        page + 1
                )
            }
        })
    }

override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Result>) {
    page = params.key
    val call:Call<UserSearchResult> = apiClient.getUserData(page,query)
    call.enqueue(object :Callback<UserSearchResult>{
        override fun onFailure(call: Call<UserSearchResult>?, t: Throwable?) {
            Timber.d("loadAfter() Failure")
        }

        override fun onResponse(call: Call<UserSearchResult>?, response: Response<UserSearchResult>?) {
            var user_result = response?.body()
            Log.d("loadAfter() --> ",response?.body().toString())
            if(user_result == null){
                onFailure(call,HttpException(response))
                return
            }
            callback.onResult(
                    user_result.results,
                    page+1
            )
        }
    })

}

override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Result>) {
    /*
    * We only append data after retrieving
    * */
}

}

DataSourceFactory:

public class UserDataSourceFactory(param:String) : DataSource.Factory<Int, Result>() {
private var query:String
val sourceLiveData = MutableLiveData<UserDataSource>()
init {
    query  = param
}

override fun create(): DataSource<Int, Result> {
    Timber.d("UserDataSourcefactory create()")
    val source:UserDataSource = UserDataSource(query)
    sourceLiveData.postValue(source)
    return source
}



}

0 个答案:

没有答案