B4A Library [Class] SearchView - More powerful alternative to AutoCompleteEditText

Status
Not open for further replies.
Edit: better to use B4XDialog + B4XSearchTemplate

SearchView is made of an EditText and ListView. When the user enters text into the EditText the ListView shows the items that start with this text or that contain the text (in this order).

This view is useful for allowing the user to select an item from many items.

Advantages over AutoCompleteEditText:
  • SearchView uses an internal index that is built when you call SetItems. This allows it to quickly find the matches.
  • SearchView also shows items that contain the input text (not just prefixes).
  • The class code can be further customized as needed.

upload_2017-2-21_17-48-19.png


Tutorial about handling large, searchable lists: https://www.b4x.com/android/forum/t...e-list-with-searchview-b4xserializator.61872/
 

Attachments

  • SearchView.zip
    45.1 KB · Views: 1,205
Last edited:

Anser

Well-Known Member
Licensed User
Is there any way to customize the search view to work in a general way ? For eg. Modify/set the ListView's Text Color, EditText's Hint text etc that are used inside the SearchView class

I know that I can change the EditText's and ListView's properties inside the SearchView class.

I will be using SearchView in my project in different activities. In some Activity, I will be using SearchView to list ItemCode, in some activity I will use SearchView to list Customer's name. Suppose, if I want to have different hint texts for different search views in the same project.

I am looking for a solution such that I can modify these properties from the Activity itself

For Eg
B4X:
Dim SV as SearchView
SV.Initialiaze(me, "sv")
SV.lv.SingleLineLayout.Label.Color = Colors.DarkGray
SV.et.Hint = "Enter ItemName"

Instead of having multiple copies of the SearchView customised for each Activity screen, a general one is desirable


Any hint regarding this will be useful.

Thanks & Regards

Anser
 
Last edited:

Anser

Well-Known Member
Licensed User
OK. I got it done using Public Sub

B4X:
Public Sub Hint(HintText As String)
    et.Hint = HintText
End Sub

Public Sub ListViewColour(TextColor As Int)
    lv.SingleLineLayout.Label.TextColor = TextColor
End Sub

In the Activity, I am calling like the below given code
B4X:
svMachine.Hint("Machine Number")
svMachine.ListViewColour(Colors.DarkGray)

I hope that this is the right way.

By the way, while using other views, assigning such values are as given below. What changes should I make in the code to change the behavior as given below.

B4X:
svMachine.Hint = "Machine Number"
svMachine.ListViewColour = Colors.DarkGray

Edit :-

Its better to make the et and lv public so that it can be accessed from the Activity code. :) So both the above said Public Sub's in the Class are not required. I am just learning B4A classes. :)

Regards
Anser
 
Last edited:

Anser

Well-Known Member
Licensed User
I have an issue with the SearchView. I am sure that its something wrong with the way I am doing it.

I have a Searchview and just below the SearchView, I have few other views for eg a button spread across the width of the activity.

The problem is that the when I use the SearchView, the SerchView's ListView (ie the dropdown list) is hidden behind the button ie the drop down list is not shown. If I remove all the views below the SearchView then it is shown

What should I do to show the SearchView's ListView/drop down list above the other views that are placed just below the SearchView ?

Regards

Anser
 
Last edited:

Luis Felipe

Member
Licensed User
Do you want to put SearchView inside ULV? It is problematic to put a scrollable view inside another scrollable view.

However you can modify the code and add the ListView used by SearchView to the activity instead of the parent. This way the list will float above the ULV when it is visible.
I was thinking using the SearchView field at the top of the Activity in order to search in a list of bus stop (more than 2.000) and with the possible result use the ULV just after in order to show more information (there are a lot) without changing of Activity.
Those changes means a lot of additional work ?
Thanx Erel.
 

Prosg

Active Member
Licensed User
I try to add the seachview with CustomListView but i have a problem.

The bug is at
Private Sub et_TextChanged (Old As String, New As String)
lv.Clear

Object not initialized

Erel said in a previous post:
However you can modify the code and add the ListView used by SearchView to the activity instead of the parent. This way the list will float above the ULV when it is visible.

how can i do this ? i find this but it's as Panel
upload_2015-11-9_7-49-21.png
 

Prosg

Active Member
Licensed User
custList.Add(addSearchView("Poste recherché",svPoste , installation.indexPoste ,"svPoste"), 90dip, "")

Sub addSearchView(Text As String, oSearch As SearchView, oIndex As Object, nomEvent As String) As Panel
Dim p As Panel
p.Initialize("")
p.Color = Colors.white

Dim lbl As Label
lbl.Initialize("")
lbl.Text = " " & Text
lbl.Gravity = Bit.Or(Gravity.CENTER_VERTICAL, Gravity.LEFT)
lbl.TextColor = Colors.ARGB(255, 70,90,117)
lbl.TextSize = 18
lbl.Typeface = Typeface.DEFAULT_BOLD

'Add editText
oSearch.Initialize(Me, nomEvent)
oSearch.SetItems(oIndex)
p.AddView(lbl, 0dip, 2dip, custList.AsView.Width, 46dip)
'p.AddView(oSearch, 10dip, 30dip, (custList.AsView.Width -20dip), 46dip)
oSearch.AddToParent(p, 10dip, 30dip,(custList.AsView.Width -20dip), 46dip)
Return p
End Sub

if i do :
oSearch.AddToParent(p, 10dip, 30dip,(custList.AsView.Width -20dip), 46dip)
or
oSearch.AddToParent(Activity, 10dip, 30dip,(custList.AsView.Width -20dip), 46dip)

Same error i have


LogCat connected to: B4A-Bridge: samsung SM-G925F-352564074677609
--------- beginning of main
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
Installing file.
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:com.fitnjob.prosg
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
(Intent) Intent { cmp=com.fitnjob.prosg/.httputils2service }
** Activity (main) Pause, UserClosed = false **
** Activity (modcandidat) Create, isFirst = true **
~w:1004,modcandidat,72
** Activity (modcandidat) Resume **
** Activity (modcandidat) Pause, UserClosed = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = true **
** Activity (modcandidat) Resume **
~w:1001,modcandidat,344
searchview_et_textchanged (B4A line: 48)
lv.Clear
java.lang.RuntimeException: Object should first be initialized (ListView).
at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:50)
at anywheresoftware.b4a.objects.ListViewWrapper.Clear(ListViewWrapper.java:197)
at com.fitnjob.prosg.searchview._et_textchanged(searchview.java:166)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
at anywheresoftware.b4a.objects.EditTextWrapper$1.afterTextChanged(EditTextWrapper.java:83)
at android.widget.TextView.sendAfterTextChanged(TextView.java:9017)
at android.widget.TextView.setText(TextView.java:4859)
at android.widget.TextView.setText(TextView.java:4674)
at android.widget.EditText.setText(EditText.java:114)
at android.widget.TextView.setText(TextView.java:4649)
at android.widget.TextView.setTransformationMethod(TextView.java:2284)
at android.widget.TextView.applySingleLine(TextView.java:8636)
at android.widget.TextView.setInputType(TextView.java:5091)
at anywheresoftware.b4a.objects.EditTextWrapper.setInputType(EditTextWrapper.java:174)
at com.fitnjob.prosg.searchview._initialize(searchview.java:224)
at com.fitnjob.prosg.modcandidat._addsearchview(modcandidat.java:785)
at com.fitnjob.prosg.modcandidat._actionbar1_click(modcandidat.java:443)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:882)
at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:839)
at com.fitnjob.prosg.ahaactionbar._lsvnavigationdrawer_itemclick(ahaactionbar.java:2264)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
at anywheresoftware.b4a.BA$2.run(BA.java:299)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6837)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
 
Last edited:

Prosg

Active Member
Licensed User
B4X:
Public Sub Initialize (Callback As Object, EventName As String)

    lv.Initialize("lv")
    lv.SingleLineLayout.ItemHeight = 50dip
    lv.SingleLineLayout.Label.TextSize = 14
    lv.Visible = False
   
    et.Initialize("et")
    'Remove the suggestions bar
    et.InputType = Bit.Or(et.INPUT_TYPE_TEXT, 0x00080000)
   
    prefixList.Initialize
    substringList.Initialize
    mCallback = Callback
    mEventName = EventName
End Sub

Always the same bug^^
 

Prosg

Active Member
Licensed User
i fix the problem Erel,

Your searchView must be initialize in Sub Activity_Create(FirstTime As Boolean)


If not it's bugging

regards
 

Prosg

Active Member
Licensed User
Hello,

I use customDialog with searchView... but when i click on the list... nothing happen... the lv_ItemClick don't fire

it seem that it have a delay cause when i click Ok, the event fire

any idea to resolve this ?
 
Last edited:

Dave61

Member
Licensed User
It is possible to type text into the SearchView which doesn't appear in the list.
For my application that is good - I want the list to appear as a list of previous phrases typed so they will show as the person is typing and if they see the phrase already in the list they can click on it and it appears in the edittext.

But, if the phrase doesn't already exist I want them to be able to type it in themselves (which they can already) and when they are finished I want them to press another 'Send' button and 2 things to happen:
1) The text they typed will be included as part of the message sent. To do that I need sv.text to be available (exposed?) but it isn't.
2) The text they typed will then be added to the lv so it is there next time they attempt to type a phrase.

Does this functionality already exist in the sv and I just can't find it? Or do I have to modify the class? I hope the former as modifying classes is something I am not really sure how to do.
 

deantangNYP

Active Member
Licensed User
Try the attached example. It shows the Panel with SearchView when you press the button.

Please help me with this SearchViewExample on panels.
I wanted to temporary remove the "sv" (Button2) and subsequently AddToParentAgain (Button3) it back.
But Button3 gives me error "Object should first be initialized (ListView)".
May i know how to reInitialize the objects after i remove?
Thanks

i added 2 buttons into the example
B4X:
'Remove sv from Panel1
Sub Button2_Click
    Panel1.RemoveAllViews
End Sub

'Add sv back into Panel1
Sub Button3_Click
     sv.Initialize(Me, "sv")
    sv.AddToParent(Panel1, 0, 0, Panel1.Width, Panel1.Height)
End Sub
 
Last edited:
Status
Not open for further replies.
Top