RecycleView List with SearchView is empty after back press

Posted

技术标签:

【中文标题】RecycleView List with SearchView is empty after back press【英文标题】:RecycleView List with SearchView ist empty after back pressed 【发布时间】:2020-01-22 22:06:51 【问题描述】:

我正在努力使用搜索视图设置我的回收视图,这并不是因为我的搜索视图确实适用于我的回收视图。过滤器起作用,并且在我输入搜索查询后,我希望它们显示项目。但是当我单击列表项以显示详细信息并在详细信息视图中按后退按钮时,列表不会显示我的项目,列表是空的。我认为这与我的过滤设置有关,因为当我不设置 OnQueryTextListener 时,它就可以正常工作。也许有人对我有什么我想念的暗示。 我有一个带有 2 个不同片段的选项卡式布局,它们都有一个回收视图:

class WorkoutListFragment : Fragment() 

private var adapter: WorkoutListTabAdapter? = null

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? 
    return inflater.inflate(R.layout.fragment_workout_list, container, false)


override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
    super.onViewCreated(view, savedInstanceState)

    adapter = WorkoutListTabAdapter(childFragmentManager)

    viewPager.adapter = adapter
    workoutListTabs.setupWithViewPager(viewPager);


我只显示 1 个列表片段以使其更清晰

class WorkoutCustomListFragment : Fragment() 

private lateinit var mAdapter: WorkoutListAdapter
private lateinit var listViewModel: ListViewModel

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? 

    listViewModel = ViewModelProviders.of(this.activity!!).get(ListViewModel::class.java)

    val dataBinding: FragmentCustomWorkoutListBinding =
        DataBindingUtil.inflate(
            inflater,
            R.layout.fragment_custom_workout_list,
            container,
            false
        )
    val view: View = dataBinding.root
    dataBinding.viewmodel = listViewModel
    return view


override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
    super.onViewCreated(view, savedInstanceState)

    setupRecycleView()
    listViewModel.getWorkouts().observe(this, Observer  workouts ->
        mAdapter.setData(workouts)
    )

    listViewModel.openWorkoutDetail.observe(this, EventObserver  workoutId ->
        val action =
            WorkoutListFragmentDirections.actionWorkoutListFragmentToWorkoutDetailFragment(
                workoutId
            )
        findNavController().navigate(action)
    )

    listViewModel.openCreateWorkoutEvent.observe(this, EventObserver 
        val action =
            WorkoutListFragmentDirections.actionWorkoutListFragmentToWorkoutCreateFragment(0)
        findNavController().navigate(action)
    )

    setUpSwipeHandler(mAdapter)

    customListSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener 
        override fun onQueryTextSubmit(p0: String?): Boolean 
            mAdapter.filter.filter(p0)
            return false
        

        override fun onQueryTextChange(p0: String?): Boolean 
            mAdapter.filter.filter(p0)
            return false
        
    )


private fun setupRecycleView() 
    mAdapter = WorkoutListAdapter(listViewModel)
    workoutList.adapter = mAdapter
    workoutList.layoutManager = LinearLayoutManager(activity)


private fun setUpSwipeHandler(
    adapter: WorkoutListAdapter
) 
    ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
        0,
        ItemTouchHelper.RIGHT
    ) 
        override fun onMove(
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder,
            target: RecyclerView.ViewHolder
        ): Boolean 
            return false
        

        override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) 
            val workoutToDelete = adapter.getWorkout(viewHolder.adapterPosition)
            listViewModel.delete(workoutToDelete.id)
            Toast.makeText(
                activity,
                "Workout $workoutToDelete.title wurde gelöscht",
                Toast.LENGTH_SHORT
            ).show()
            adapter.removeItemFromList(workoutToDelete.id)
            adapter.notifyItemRemoved(viewHolder.adapterPosition)
            adapter.notifyDataSetChanged()
        
    ).attachToRecyclerView(workoutList)


还有我的适配器

class WorkoutListAdapter(private val viewModel: ListViewModel) :
RecyclerView.Adapter<WorkoutListAdapter.ViewHolder>(), Filterable 

private var mWorkouts = ArrayList<Workout>()
private var mWorkoutsFull = ArrayList<Workout>()

override fun getItemCount(): Int 
    return mWorkouts.size


fun setData(workouts: List<Workout>?) 
    mWorkouts = workouts as ArrayList<Workout>
    mWorkoutsFull.addAll(workouts)
    notifyDataSetChanged()


inner class ViewHolder(private val binding: WorkoutlistWorkoutItemBinding) :
    RecyclerView.ViewHolder(binding.root) 
    fun bind(workout: Workout) 
        binding.workout = workout
        binding.viewModel = viewModel
        binding.executePendingBindings()
    


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder 
    val layoutInflater: LayoutInflater = LayoutInflater.from(parent.context)
    val itemBinding: WorkoutlistWorkoutItemBinding =
        WorkoutlistWorkoutItemBinding.inflate(layoutInflater, parent, false)
    return ViewHolder(itemBinding)


override fun onBindViewHolder(holder: ViewHolder, position: Int) 
    val item = mWorkouts[position]
    holder.bind(item)


fun getWorkout(position: Int): Workout 
    return mWorkouts[position]


override fun getFilter(): Filter 
    return workoutListFilter


fun removeItemFromList(id: Int) 
    val workout = mWorkouts.find  it.id == id 
    val index = mWorkouts.indexOf(workout)
    mWorkouts.removeAt(index)


private val workoutListFilter: Filter = object : Filter() 
    override fun performFiltering(constraint: CharSequence?): FilterResults 
        val filterList = ArrayList<Workout>()

        if (constraint!!.isEmpty() || constraint == null) 
            filterList.addAll(mWorkoutsFull)
         else 
            val searchString = constraint.toString().toLowerCase().trim()

            for (workout in mWorkoutsFull) 
                if (workout.title.toLowerCase().contains(searchString)) 
                    filterList.add(workout)
                
            
        

        val results = FilterResults()
        results.values = filterList
        return results
    

    override fun publishResults(p0: CharSequence?, filterResult: FilterResults?) 
        mWorkouts.clear()
        mWorkouts.addAll(filterResult!!.values as ArrayList<Workout>)
        notifyDataSetChanged()
    


最后我的视图模型(也许它有帮助)我正在处理实时数据

class ListViewModel @Inject constructor(
    private var workoutRepository: WorkoutRepository,
    private var finishedWorkoutRepository: FinishedWorkoutRepository
) : ViewModel() 

    private val _openWorkoutDetailEvent = MutableLiveData<Event<Int>>()
    val openWorkoutDetail: LiveData<Event<Int>> = _openWorkoutDetailEvent

    private val _openCreateWorkoutEvent = MutableLiveData<Event<Int>>()
    val openCreateWorkoutEvent: LiveData<Event<Int>> = _openCreateWorkoutEvent

    fun getStandardWorkouts(): LiveData<List<Workout>> 
        return workoutRepository.getStandardWorkouts()
    

    fun getWorkouts(): LiveData<List<Workout>> 
        return workoutRepository.getWorkouts()
    

    fun openWorkoutDetail(workoutId: Int) 
        _openWorkoutDetailEvent.value = Event(workoutId)
    

    fun openCreateWorkout() 
        _openCreateWorkoutEvent.value = Event(0)
    

    fun delete(workoutId: Int) 
        workoutRepository.delete(workoutId)
    

最好的问候

【问题讨论】:

【参考方案1】:

您在 publishResults 中清除列表 mWorkouts 列表而不检查是否找到了一些结果,添加检查为:

if (filterResults.values != null && filterResults.count > 0) 
    mWorkouts.clear()
    mWorkouts.addAll(filterResult!!.values as ArrayList<Workout>)
    notifyDataSetChanged()
    

【讨论】:

好吧,我错过了。但是当我添加这个搜索本身不再起作用时,当我输入搜索项时,我的列表中的项目不会被过滤:D 您可能需要调试编写搜索查询时究竟发生了什么。 我可以使用它: val list = filterResult!!.values as ArrayList if (filterResult!!.values != null && list.count() > 0) mWorkouts. clear() mWorkouts.addAll(filterResult!!.values as ArrayList) notifyDataSetChanged() Ty

以上是关于RecycleView List with SearchView is empty after back press的主要内容,如果未能解决你的问题,请参考以下文章

convert-sorted-list-to-binary-search-tree

recycleview中使用checkbox导致的重复选中问题

RecycleView 如何在滚动时隐藏显示顶视图(不是工具栏)

Access-Control-Allow-Origin with Wikipedia API with Javascript

想要删除recycleview上的一个项目。单击按钮删除单击。该项目在firebase数据库中删除但在循环视图中该项目存在

循环控制语句 之 with_list