11package com.codingwithmitch.openapi.ui.main.blog
22
3+ import android.app.SearchManager
4+ import android.content.Context.SEARCH_SERVICE
35import android.os.Bundle
46import android.util.Log
57import android.view.*
8+ import android.view.inputmethod.EditorInfo
9+ import android.widget.EditText
10+ import androidx.appcompat.app.AppCompatActivity
11+ import androidx.appcompat.widget.SearchView
612import androidx.lifecycle.Observer
713import androidx.navigation.fragment.findNavController
814import androidx.recyclerview.widget.LinearLayoutManager
915import androidx.recyclerview.widget.RecyclerView
16+ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
1017import com.codingwithmitch.openapi.R
1118import com.codingwithmitch.openapi.models.BlogPost
1219import com.codingwithmitch.openapi.ui.DataState
1320import com.codingwithmitch.openapi.ui.main.blog.state.BlogViewState
1421import com.codingwithmitch.openapi.ui.main.blog.viewmodel.setBlogPost
22+ import com.codingwithmitch.openapi.ui.main.blog.viewmodel.setQuery
1523import com.codingwithmitch.openapi.ui.main.blog.viewmodel.setQueryExhausted
1624import com.codingwithmitch.openapi.util.ErrorHandling
1725import com.codingwithmitch.openapi.util.TopSpacingItemDecoration
@@ -21,9 +29,11 @@ import loadFirstPage
2129import nextPage
2230
2331class BlogFragment : BaseBlogFragment (),
24- BlogListAdapter .Interaction
32+ BlogListAdapter .Interaction ,
33+ SwipeRefreshLayout .OnRefreshListener
2534{
2635
36+ private lateinit var searchView: SearchView
2737 private lateinit var recyclerAdapter: BlogListAdapter
2838
2939 override fun onCreateView (
@@ -36,13 +46,14 @@ class BlogFragment : BaseBlogFragment(),
3646
3747 override fun onViewCreated (view : View , savedInstanceState : Bundle ? ) {
3848 super .onViewCreated(view, savedInstanceState)
49+ (activity as AppCompatActivity ).supportActionBar?.setDisplayShowTitleEnabled(false )
3950 setHasOptionsMenu(true )
4051
4152 initRecyclerView()
4253 subscribeObservers()
4354
4455 if (savedInstanceState == null ){
45- viewModel.loadFirstPage ()
56+ onBlogSearchOrFilter ()
4657 }
4758 }
4859
@@ -66,6 +77,55 @@ class BlogFragment : BaseBlogFragment(),
6677 })
6778 }
6879
80+ private fun initSearchView (menu : Menu ){
81+ activity?.apply {
82+ val searchManager: SearchManager = getSystemService(SEARCH_SERVICE ) as SearchManager
83+ searchView = menu.findItem(R .id.action_search).actionView as SearchView
84+ searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName))
85+ searchView.maxWidth = Integer .MAX_VALUE
86+ searchView.setIconifiedByDefault(true )
87+ searchView.isSubmitButtonEnabled = true
88+ }
89+
90+ // ENTER ON COMPUTER KEYBOARD OR ARROW ON VIRTUAL KEYBOARD
91+ val searchPlate = searchView.findViewById(R .id.search_src_text) as EditText
92+ searchPlate.setOnEditorActionListener { v, actionId, event ->
93+
94+ if (actionId == EditorInfo .IME_ACTION_UNSPECIFIED
95+ || actionId == EditorInfo .IME_ACTION_SEARCH ) {
96+ val searchQuery = v.text.toString()
97+ Log .e(TAG , " SearchView: (keyboard or arrow) executing search...: ${searchQuery} " )
98+ viewModel.setQuery(searchQuery).let {
99+ onBlogSearchOrFilter()
100+ }
101+ }
102+ true
103+ }
104+
105+ // SEARCH BUTTON CLICKED (in toolbar)
106+ val searchButton = searchView.findViewById(R .id.search_go_btn) as View
107+ searchButton.setOnClickListener {
108+ val searchQuery = searchPlate.text.toString()
109+ Log .e(TAG , " SearchView: (button) executing search...: ${searchQuery} " )
110+ viewModel.setQuery(searchQuery).let {
111+ onBlogSearchOrFilter()
112+ }
113+
114+ }
115+ }
116+
117+ private fun onBlogSearchOrFilter (){
118+ viewModel.loadFirstPage().let {
119+ resetUI()
120+ }
121+ }
122+
123+ private fun resetUI (){
124+ blog_post_recyclerview.smoothScrollToPosition(0 )
125+ stateChangeListener.hideSoftKeyboard()
126+ focusable_view.requestFocus()
127+ }
128+
69129 private fun handlePagination (dataState : DataState <BlogViewState >){
70130
71131 // Handle incoming data from DataState
@@ -120,6 +180,12 @@ class BlogFragment : BaseBlogFragment(),
120180 }
121181 }
122182
183+ override fun onCreateOptionsMenu (menu : Menu , inflater : MenuInflater ) {
184+ super .onCreateOptionsMenu(menu, inflater)
185+ inflater.inflate(R .menu.search_menu, menu)
186+ initSearchView(menu)
187+ }
188+
123189 override fun onItemSelected (position : Int , item : BlogPost ) {
124190 viewModel.setBlogPost(item)
125191 findNavController().navigate(R .id.action_blogFragment_to_viewBlogFragment)
@@ -130,6 +196,11 @@ class BlogFragment : BaseBlogFragment(),
130196 // clear references (can leak memory)
131197 blog_post_recyclerview.adapter = null
132198 }
199+
200+ override fun onRefresh () {
201+ onBlogSearchOrFilter()
202+ swipe_refresh.isRefreshing = false
203+ }
133204}
134205
135206
0 commit comments