I am making app using API and fetched all the data perfectly. I also have search bar on recycler view. Now I want to save the search history which user searches on the app. I have followed the solutions from stackoverflow but I am not able to save the history.
Search history in Android quick search
I want to know that where I have to make searchable.xml ? Also I am using edittext for performing search in my code so I have remove edittext and replace with searchable?
I little confused in using and setting up the content provider.
My xml file:
<?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.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:visibility="gone"/>
<TextView
android:id="#+id/txt_error_popular"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/connection_problem"
android:visibility="gone"/>
<EditText
android:id="#+id/search_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionSearch"
android:inputType="text"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:hint="#string/search_for_something"
android:layout_marginBottom="4dp"
android:importantForAutofill="no" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_photos"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:scrollbars="vertical">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
My main activity where I am performing search:
search(DEFAULT_SEARCH)
search_box?.setOnEditorActionListener(object : TextView.OnEditorActionListener{
override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean {
if (actionId == EditorInfo.IME_ACTION_SEARCH){
val searchTerm = search_box.text.trim()
if (searchTerm.isNotEmpty()){
rv_photos?.scrollToPosition(0)
photoAdapter.submitList(null)
search(searchTerm.toString())
currentFocus?.let {
val inputManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputManager.hideSoftInputFromWindow(it.windowToken, HIDE_NOT_ALWAYS)
}
}
return true
}
return false
}
})
}
private fun search(searchTerm: String){
viewModel.performSearch(searchTerm)
}
Now I just want to save the recent search?
Just use roomDb to store your search history and whenever the user clicks on the search box fetch the search list
Check this latest codelab by google which guides you through roomDb
https://developer.android.com/codelabs/android-room-with-a-view-kotlin#0
Related
I have an activity which I will show xml for below, containing a webView inside an appBarLayout. Now to be frank, I don't know where the appBarLayout came from because I dont remember adding it in. But anyways, the screen has stacked in the following order top->bottom: a textView, a videoView, and a webView. So the HTML being displayed in the webview is only maybe the bottom half of the screen. Below the xml snippet, I have a image of how this looks from the design POV. The closest I ever got to scrolling is if the webView and friends are NOT children of appBarLayout but then the webview takes up entire screen which is not desirable.
I admit, this probably is setup wrong but I will gladly take whatever advice you have and suggestions on editing the way this is arranged/configured.
Activity XML
<androidx.coordinatorlayout.widget.CoordinatorLayout 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=".Lesson">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:isScrollContainer="true"
android:scrollbars="vertical"
android:theme="#style/Theme.ProjectName.AppBarOverlay"
android:verticalScrollbarPosition="right">
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="64dp"
android:fontFamily="#font/reem_kufi"
android:gravity="center"
android:isScrollContainer="false"
android:linksClickable="true"
android:text="Title Goes Here"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:textStyle="bold" />
<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
android:id="#+id/videoView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<WebView
android:id="#+id/lessonContentView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadeScrollbars="true"
android:isScrollContainer="true"
android:nestedScrollingEnabled="true"
android:overScrollMode="ifContentScrolls"
android:persistentDrawingCache="scrolling"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_scrollFlags="scroll" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Kotlin File
class Lesson : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityLessonBinding
private lateinit var webView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLessonBinding.inflate(layoutInflater)
setContentView(binding.root)
webView = findViewById(R.id.lessonContentView)
if(webView != null){
webView.requestFocus()
webView.settings.javaScriptEnabled = true
webView.isSoundEffectsEnabled = true
webView.isVerticalScrollBarEnabled = true
webView.settings.loadWithOverviewMode = true
webView.settings.allowContentAccess = true
webView.settings.domStorageEnabled = true
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
if (url != null) {
view?.loadUrl(url)
}
return true
}
}
webView.loadUrl("file:///android_asset/lesson.html")
}
val youTubePlayerView: YouTubePlayerView? = findViewById(R.id.videoView)
if (youTubePlayerView != null) {
lifecycle.addObserver(youTubePlayerView)
}
youTubePlayerView?.addYouTubePlayerListener(object : AbstractYouTubePlayerListener() {
override fun onReady(youTubePlayer: YouTubePlayer) {
val videoId = "yJdkdiAly0w"
youTubePlayer.cueVideo(videoId, 0F)
}
})
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_lesson)
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
}
Component Tree & Design
How it looks now
How it looked when I got it to scroll but not how I wanted
I have already tried the advice given on several posts here on StackOverflow so please do not just mark as Duplicate and run off. Probably a quarter of the code in the project right now is from me trying to get scrolling to work with the advice of this site.
I have tried messing with all the scroll attributes for basically every view on here.
I have added StackOverflow recommended items such as the app:layout_behavior and these webview settings below:
webView.isVerticalScrollBarEnabled = true
webView.settings.loadWithOverviewMode = true
webView.settings.allowContentAccess = true
When I got it to scroll but wasnt correct, shown in image link earlier, I had removed all the views from the appBarLayout parent making everything a direct child of what this says is a "CoordinatorLayout".
Received help outside of SO (Discord) and I will go over the changes below.
First, I removed the appBarLayout. As originally mentioned, I wasn't even sure about it or how it got there as a parent of everything. I also removed ITS PARENT the coordinatorLayout by changing it to a constraintLayout. This is the parent of my 3 needed pieces (text, video, web) all stacked on top of each other. A few attributes were removed from the xml as well.
Please feel free to comment if you see this in the future and have questions about how I solved this.
<?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:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Lesson">
<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
android:id="#+id/videoView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView2" />
<TextView
android:id="#+id/textView2"
android:layout_width="412dp"
android:layout_height="54dp"
android:fontFamily="#font/reem_kufi"
android:gravity="center"
android:isScrollContainer="false"
android:linksClickable="true"
android:text="Winds & Temperatures Aloft"
android:textAlignment="center"
android:textColor="#000000"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<WebView
android:id="#+id/lessonContentView"
android:layout_width="412dp"
android:layout_height="0dp"
android:fadeScrollbars="true"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/videoView"
app:layout_constraintVertical_bias="0.483"
app:layout_scrollFlags="scroll" />
</androidx.constraintlayout.widget.ConstraintLayout>
I have an issue on my app I am trying to solve it from 2 days now but I can't find anything about it.
Almost every single button in a fragment which is added dynamically at my Activity onCreate are not clickable for some users. Nobody in my team experiences the issue so, I reached a user with the bug and made some test with him and here are the results:
If he clicks just once the button doesn't work but if he spams it, the button sometimes trigger.
I have also placed some debugging in his version and this is what I found:
user_hud_main_button.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> report += "down;"
MotionEvent.ACTION_UP -> report += "up;"
}
false
}
user_hud_main_button.setOnClickListener {
report += "click;"
toggleMainButton()
Analytics.send(Event.Type.BtnAddMain)
}
edit: the setOnTouchListener has been added only for debug purpose while working on the problem
while on my test phones I get:
down;up;click;down;up;click;down;up;click;
the user get:
down;up;down;up;down;up;down;up;
The up and down events are correctly sent but not the onclick. Why does this happen and why only for few users ?
Here is the layout of the activity:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:name="com.hulab.mapstr.newArch.MapFragment"
android:id="#+id/activity_map_fragment_map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
...
<FrameLayout
android:id="#+id/activity_map_hud_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<!-- Bottom drawer -->
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/main_bottom_sheet"></include>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
activity code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
supportFragmentManager.beginTransaction().add(R.id.activity_map_hud_container, UserHUDFragment()).commit()
...
}
UserHUDFragment:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
user_hud_main_button.setOnClickListener {
toggleMainButton()
Analytics.send(Event.Type.BtnAddMain)
}
...
}
UserHUD layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/user_hud">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/user_hud_current_map_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/user_hud_main_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:elevation="1dp"
app:fabSize="normal"
app:useCompatPadding="true"
android:src="#drawable/add_fab_button" />
...
</androidx.constraintlayout.widget.ConstraintLayout>
...
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
Thanks in advance and sorry for my english
It is not allowed to have both onTouch and onClick listener on one view. You can do everything with onTouchListener.
Ok the problem was that I had a "infinite loop" from my activity asking for a permission when users declined it with "don't ask again" option, so every click event was broken
I've created menu for NavigationView by adding ListView inside my NavigationView. Then I made custom ArrayAdapter where each menu item is added. Each menu item has custom xml layout attached to it. Root of this layout is used by onClickListener triggering function passed to menu item class as parameter.
Everything works perfectly, but as I click on item, it will not trigger this function, only as I double click. Why is this behavior happening?
Code:
This is class for menu item (multiple different items are extending this class)
Not every menu item has click event (for example section headers)
abstract class DrawerItem(var itemName: String, var imgResID: Int, var onClick: (() -> Unit)? = null)
This is how onClick is called inside getView function for some menu items:
val root: LinearLayout = view.findViewById(R.id.root)
root.setOnClickListener {
menuItem.onClick?.invoke()
}
XML layout for NavigationView:
<com.google.android.material.navigation.NavigationView
android:id="#+id/drawer_menu"
android:layout_gravity="left"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:background="#color/white">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/navigation_header_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
<ListView
android:id="#+id/lst_menu_items"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</com.google.android.material.navigation.NavigationView>
Layout of one menu item type:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:id="#+id/root"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:background="#drawable/navig_menu_selector"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:duplicateParentState="true"
android:clickable="false"
android:padding="#dimen/padding_medium">
<ImageView
android:id="#+id/navig_ico"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_gravity="center_vertical"/>
<TextView
android:id="#+id/navig_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingStart="#dimen/padding_medium"
style="#style/navig_item_text"/>
</LinearLayout>
<include layout="#layout/custom_separator"/>
</LinearLayout>
Clear the app's cache or delete it altogether and try downloading it again. I don't know the cause, but I solved the problem.
I have the following screen on Android Application:
When I press the SearchView, the screen shrinks like that:
I want the screen to stay still (as in the first image) when keyboard appears.
Here is my xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="10"
android:minWidth="25px"
android:minHeight="25px">
<SearchView
android:minWidth="25px"
android:minHeight="25px"
android:background="#drawable/rounded_border"
android:clickable="true"
android:iconifiedByDefault="false"
android:focusable="false"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/searchViewCustomers" />
<android.support.v7.widget.RecyclerView
android:id="#+id/customersRecyclerView"
android:scrollbars="vertical"
android:layout_weight="8"
android:layout_width="match_parent"
android:layout_height="0dp" />
<Button
android:text="Нов"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/button1" />
</LinearLayout>
I've tried the solutions for that found in internet but they are not working for me maybe because they are for Android(Java). If there is a way to do than in xml not in C# code it's much better.
I want the screen to stay still (as in the first image) when keyboard appears.
If you don't want the screen to auto adjust, you can set WindowSoftInputMode of your activity to SoftInput.AdjustNothing like this:
[Activity(Label = "Sample", MainLauncher = true,WindowSoftInputMode = SoftInput.AdjustNothing)]
public class MainActivity : Activity
{
RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
...
}
I'm using the searchview at the top of my activity positioned just below the action bar, the problem is that the suggestions are displayed over the searchview so the user cant see the typed the text
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v7.widget.SearchView
android:id="#+id/fragment_map.searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.SearchView>
<RelativeLayout
android:layout_below="#id/fragment_map.searchView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/map_container">
<!-- The map fragments will go here -->
</RelativeLayout>
</RelativeLayout>
no clue what the official answer even means. a work colleague aided me and I wanted to show how this can be achieved:
it can be done programatically by getting the textview as an AutoCompleteTextview:
imagine you have a searchview in xml like this:
<android.support.v7.widget.SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginRight="10dp"
android:animateLayoutChanges="true"
android:paddingLeft="0dp"
app:closeIcon="#drawable/close_x_icon"
app:queryBackground="#drawable/search_bg_expanded"
app:searchHintIcon="#drawable/empty_drawable"
app:searchIcon="#null" />
then in code do this:
val searchText = searchView.findViewById<TextView>(android.support.v7.appcompat.R.id.search_src_text) as? AutoCompleteTextView
searchText?.dropDownAnchor = searchView.id
so once you cast it to an AutocompleteTextView you can change the anchor basically.
fixed by adding this view to the bottom of the relativelayout and setting it to the anchor
<View android:id="#+id/fragment_map.dropDownAnchor"
android:layout_below="#id/fragment_map.searchView"
android:layout_width="match_parent"
android:layout_height="0dp" />