firebase创建数据库
One of the most important parts of building any website or web app is its search functionality. Search functionality helps to make interactions with products easier and faster. We live in a world where every millisecond counts and a bad search experience could lead to users discontinuing the use of a product.
建立任何网站或网络应用程序最重要的部分之一就是其搜索功能。 搜索功能有助于简化与产品的交互。 我们生活在一个毫秒级的世界中,糟糕的搜索体验可能会导致用户停止使用产品。
什么是即时搜索? (What is Instant Search?)
It’s a predictive search feature that tries to anticipate and guess the most likely completion of what a user’s search query is and displays information that is relevant to the user’s input instantly with every keystroke inputted in the search box.
它是一种预测性搜索功能,可尝试预测和猜测用户搜索查询的最可能完成情况,并通过在搜索框中输入每次击键立即显示与用户输入有关的信息。
先决条件: (Prerequisites:)
You must know the basics of Android, Firestore, and Kotlin.
您必须了解Android,Firestore和Kotlin的基础知识。
我们要实现什么: (What are we going to implement:)
入门: (Getting Started:)
The most important part of the Firestore is to define the database structure. So that we can query each keyword and match it with our actual display result.
Firestore最重要的部分是定义数据库结构。 这样我们就可以查询每个关键字并将其与我们的实际显示结果进行匹配。
让我们做一些代码: (Let's do some code:)
Create a layout file search_toolbar_custom_view.xml for the search toolbar layout.
为搜索工具栏布局创建布局文件search_toolbar_custom_view.xml 。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
<ImageView
android:id="@+id/search_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:contentDescription="@string/search_icon"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:src="@drawable/ic_search"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/search_edittext"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_toEndOf="@id/search_icon"
android:autofillHints="@string/search"
android:background="@drawable/search_edittext_"
android:hint="@string/search"
android:inputType="text"
android:maxLines="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/search_icon"
app:layout_constraintTop_toTopOf="parent" />
</RelativeLayout>
Creating an ArrayAdapter.kt class for recyclerview.
为recyclerview创建一个ArrayAdapter.kt类。
class ArrayAdapter(private var suggestions: List<String>, private val activity: Activity) :
RecyclerView.Adapter<ArrayAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflate = LayoutInflater.from(parent.context)
.inflate(R.layout.suggestion_textview_item, parent, false)
return ViewHolder(inflate, activity)
}
override fun getItemCount(): Int {
return suggestions.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(suggestions[position])
}
fun setList(suggestionList: List<String>) {
suggestions = suggestionList
notifyDataSetChanged()
}
class ViewHolder(itemView: View, val activity: Activity) : RecyclerView.ViewHolder(itemView) {
val text: MaterialTextView = itemView.suggestion_text
fun bind(data: String) {
text.text = data
itemView.setOnClickListener {
Log.d("Click",data)
}
}
}
}
Creating a layout for ArrayAdapter suggestion_textview_item.xml
创建ArrayAdapter suggestion_textview_item.xml布局
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.textview.MaterialTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/suggestion_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:paddingStart="56dp"
android:paddingTop="8dp"
android:paddingEnd="24dp"
android:paddingBottom="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.SearchResult.Title"
android:textColor="@color/textColorPrimary"
android:textSize="16sp" />
Now the main part of this article to Query the search and handling the dataset results in the UI and also we need to implement logic so that when a user gives a pause in the edittext then only we need to Query the database.
现在,本文的主要部分将在UI中查询搜索和处理数据集结果,并且我们还需要实现逻辑,以便当用户在edittext中给出暂停时,只需要查询数据库。
For this, we use Kotlin Coroutines' delay() function and some logic that it is.
为此,我们使用Kotlin Coroutines的delay()函数以及它的一些逻辑。
Here is code for SearchFragment.kt
这是SearchFragment.kt的代码
class SearchFragment : Fragment() {
val firestore = Firebase.firestore
lateinit var searchSuggestionAdapter: ArrayAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_search, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(activity as MainActivity).supportActionBar!!.title = getString(R.string.search)
(activity as MainActivity).supportActionBar!!.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
searchSuggestionAdapter =
ArrayAdapter(ArrayList(), requireActivity())
search_suggestion_recyclerview.apply {
layoutManager = LinearLayoutManager(requireContext())
adapter = searchSuggestionAdapter
}
val inflate = LayoutInflater.from(requireContext())
.inflate(R.layout.search_toolbar_custom_view, container, false)
(activity as MainActivity).supportActionBar!!.customView = inflate
inflate.search_edittext.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(s: CharSequence?, p1: Int, p2: Int, p3: Int) {
var searchFor = ""
val searchText = s.toString().trim()
if (searchText == searchFor)
return
searchFor = searchText
GlobalScope.launch(IO) {
delay(300)
if (searchText != searchFor)
return@launch
inflate.search_edittext.text.toString()
val suggestionList = ArrayList<String>()
val suggestionSnapshot =
Firebase.firestore.collection("tags").whereArrayContains(
"keywords",
searchText.toLowerCase(Locale.ROOT)
).limit(16)
.get().await()
if (suggestionSnapshot.isEmpty)
suggestionList.add("No Search Result Found")
suggestionSnapshot.forEach {
suggestionList.add(it["name"] as String)
}
withContext(Main)
{
searchSuggestionAdapter.setList(suggestionList)
}
}
}
override fun afterTextChanged(p0: Editable?) {
if (TextUtils.isEmpty(p0)) {
search_suggestion_recyclerview.visibility = View.GONE
category_recyclerview.visibility = View.VISIBLE
materialTextView2.visibility = View.VISIBLE
} else {
search_suggestion_recyclerview.visibility = View.VISIBLE
category_recyclerview.visibility = View.GONE
materialTextView2.visibility = View.GONE
}
}
})
}
}
Layout file for SearchFragment.kt
SearchFragment.kt的布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.SearchFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/search_suggestion_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/suggestion_textview_item" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/materialTextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="@string/trending_tags"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/category_recyclerview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/materialTextView2" />
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/progress_bar"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.ContentLoadingProgressBar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
恭喜!!! (Congratulations!!!)
Please follow me to see more articles
请关注我以查看更多文章
Happy Coding.
编码愉快。
firebase创建数据库