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以上是关于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数据库中删除但在循环视图中该项目存在