#android #firebase #kotlin #google-cloud-firestore
#Android #firebase #kotlin #google-облако-firestore
Вопрос:
Я хочу реализовать поиск в моем recyclerview. Данные, которые я извлекаю, взяты из firebase (firestore). Когда я нажимаю на значок поиска и набираю любой текст, мое приложение выходит из строя, и я не могу понять, в чем может быть причина. Кто-нибудь может сказать мне, что не так с моим кодом?
class ActivityStudentList : AppCompatActivity() {
private lateinit var studentRecyclerView: RecyclerView
private lateinit var recyclerViewAdapter: RecyclerViewAdapter
private val db = FirebaseFirestore.getInstance()
private lateinit var studentArrayList: ArrayList<StudentRecyclerViewDataClass>
private lateinit var editStudentFab: ExtendedFloatingActionButton
private lateinit var addStudentFab: ExtendedFloatingActionButton
private lateinit var removeStudentFab: ExtendedFloatingActionButton
private lateinit var tempArrayList: ArrayList<StudentRecyclerViewDataClass>
private lateinit var newArrayList: ArrayList<StudentRecyclerViewDataClass>
private var clicked = false
private lateinit var obstructor: RelativeLayout
private val fromBottom: Animation by lazy { AnimationUtils.loadAnimation(this,R.anim.from_bottom_anim) }
private val toBottom: Animation by lazy { AnimationUtils.loadAnimation(this,R.anim.to_bottom_anim) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_student_list)
supportActionBar?.setDisplayHomeAsUpEnabled(false)
actionBar?.setDisplayShowTitleEnabled(false)
supportActionBar?.setDisplayShowTitleEnabled(false)
editStudentFab = findViewById(R.id.editStudentFab)
addStudentFab = findViewById(R.id.addStudentFab)
removeStudentFab = findViewById(R.id.removeStudentFab)
obstructor = findViewById(R.id.obstructor)
studentRecyclerView = findViewById(R.id.studentRecyclerView)
studentRecyclerView.layoutManager = LinearLayoutManager(this)
studentRecyclerView.setHasFixedSize(true)
studentArrayList = arrayListOf<StudentRecyclerViewDataClass>()
recyclerViewAdapter = RecyclerViewAdapter(studentArrayList)
studentRecyclerView.adapter = recyclerViewAdapter
studentRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(studentRecyclerView: RecyclerView, dx: Int, dy: Int) {
if (dy > 0) editStudentFab.hide() else if (dy < 0) editStudentFab.show()
}
})
getStudentData()
editStudentFab.setOnClickListener {
onEditButtonClicked()
}
addStudentFab.setOnClickListener {
startActivity(Intent(this,ActivityAddStudent::class.java))
}
removeStudentFab.setOnClickListener {
startActivity(Intent(this,ActivityAddStudent::class.java))
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.student_recycler_view_search, menu)
val search = menu?.findItem(R.id.student_recycler_view_search)
val searchView = search?.actionView as? SearchView
searchView?.isSubmitButtonEnabled = true
searchView?.setOnQueryTextListener(object: SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String?): Boolean {
TODO("Not yet implemented")
}
@SuppressLint("NotifyDataSetChanged")
override fun onQueryTextChange(newText: String?): Boolean {
tempArrayList.clear()
val searchText = newText!!.toLowerCase(Locale.getDefault())
if(searchText.isNotEmpty()){
newArrayList.forEach{
if(it.Name!!.toLowerCase(Locale.getDefault()).contains(searchText)){
tempArrayList.add(it)
}
}
studentRecyclerView.adapter!!.notifyDataSetChanged()
}else{
tempArrayList.clear()
tempArrayList.addAll(newArrayList)
studentRecyclerView.adapter!!.notifyDataSetChanged()
}
return false
}
})
return super.onCreateOptionsMenu(menu)
}
private fun onEditButtonClicked() {
setVisibility(clicked)
setAnimation(clicked)
clicked = !clicked
}
@SuppressLint("SetTextI18n")
private fun setAnimation(clicked: Boolean) {
obstructor = findViewById(R.id.obstructor)
addStudentFab = findViewById(R.id.addStudentFab)
removeStudentFab = findViewById(R.id.removeStudentFab)
editStudentFab = findViewById(R.id.editStudentFab)
if(!clicked){
obstructor.visibility = View.VISIBLE
editStudentFab.text = "Close"
editStudentFab.setIconResource(R.drawable.ic_outline_close_24)
addStudentFab.startAnimation(fromBottom)
removeStudentFab.startAnimation(fromBottom)
}else{
obstructor.visibility = View.INVISIBLE
editStudentFab.text = "Edit List"
editStudentFab.setIconResource(R.drawable.ic_outline_edit_24)
addStudentFab.startAnimation(toBottom)
removeStudentFab.startAnimation(toBottom)
}
}
private fun setVisibility(clicked: Boolean) {
addStudentFab = findViewById(R.id.addStudentFab)
removeStudentFab = findViewById(R.id.removeStudentFab)
if(!clicked){
addStudentFab.visibility = View.VISIBLE
removeStudentFab.visibility = View.VISIBLE
}else{
addStudentFab.visibility = View.INVISIBLE
removeStudentFab.visibility = View.INVISIBLE
}
}
private fun getStudentData() {
db.collection("StudentInfo").addSnapshotListener(object: EventListener<QuerySnapshot>{
@SuppressLint("NotifyDataSetChanged")
override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
if(error != null){
Log.e("Firestore Error",error.message.toString())
return
}
for(dc : DocumentChange in value?.documentChanges!!){
if(dc.type == DocumentChange.Type.ADDED){
studentArrayList.add(dc.document.toObject(StudentRecyclerViewDataClass::class.java))
}
}
recyclerViewAdapter.notifyDataSetChanged()
}
})
}
}
Код адаптера RecyclerView:
class RecyclerViewAdapter(private var studentList : ArrayList<StudentRecyclerViewDataClass>) : RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.recycler_view_student_list_item,parent,false)
return RecyclerViewHolder(itemView)
}
override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
val currentItem = studentList[position]
holder.name.text = currentItem.Name
holder.SRN.text = currentItem.SRN
holder.phone.text = currentItem.Phone
holder.age.text = currentItem.Age
}
override fun getItemCount(): Int {
return studentList.size
}
class RecyclerViewHolder(itemView : View ) : RecyclerView.ViewHolder(itemView){
val name : TextView = itemView.findViewById(R.id.tv_name)
val SRN : TextView = itemView.findViewById(R.id.tv_srn)
val phone : TextView = itemView.findViewById(R.id.tv_phone)
val age : TextView = itemView.findViewById(R.id.tv_age)
}
}
Комментарии:
1. Пожалуйста, используйте
android-studio
тег только для вопросов о самой IDE Android Studio. Для вопросов о программировании на Android в целом используйтеandroid
тег.2. Если ваше приложение выходит из строя, оно записывает сообщение об ошибке и трассировку стека в свой вывод logcat. Пожалуйста, найдите их и добавьте к своему вопросу (прямо под ним есть ссылка).
edit
3. Пожалуйста, отредактируйте свой вопрос и добавьте информацию, которую просил Фрэнк ван Пуффелен, а также, пожалуйста, ответьте с помощью @.
4. Кроме того, я думаю, что эта статья, как фильтровать данные Firestore дешевле? может помочь.