Android Question Managing textfield and automation

dexMilano

Active Member
Licensed User
Longtime User
I have a simple problem but maybe it is not.

I've 2 textfield in a form (and other controls).
When I open the form data are loaded form a DB and the view is fulfilled.
If I type something in the first field, something else should be automatically added to the second.
Then I've a save button that save everything (and the 2 fields too)

I wrote many very bad codelines (shame on me) but I didn't find a clean solution.

1st version has been using the TextChanged event on the 1st field.
This has the issue that fires every character and also if I set the text of the 1st field by code when the view is created

2nd version has been using FocusChanged event on the 1st field.
This has the issue that fires only if I change the focus on another textfield; if I click on a button the event is not executed (stay in queue until I didn't click on another field)

I'm sure my scenario is not particular.
So I think some good solution should be available but I cannot find it.
Thanks in advance for every clue.

dex
PS. Sorry for my English I hope the request is clear enaough.
 

LucaMs

Expert
Licensed User
Longtime User
It would take a LostFocus, as in VB.Net.

A bad but working solution is that you use a global boolean variable; set it to True when the first EditText gets the focus; then, on each button (sigh) check this variable (which you will need to set to False in various places) and call the "first EditText FocusChanged")

(in italiano forse lo avrei spiegato meglio :))

P.S. you should not call "first EditText FocusChanged" but the same sub that it calls
 
Last edited:
Upvote 0

stevel05

Expert
Licensed User
Longtime User
You can add an OnFocus listener with the reflection library that fires on focus gained and focus lost with a flag to tell you which.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
An example is worth a thousand words :) see attached.
 

Attachments

  • oft.zip
    6.9 KB · Views: 176
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Many thanks, i'll try it (ehm... now!)


Grrrrrr i hate this msg:

upload_2014-1-22_18-37-45.png
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Ah OK the Designer just has two EditText objects, EditText1 & EditText2, just create a new layout with those in it. The main code module should load.

If needed it just contains:

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private EditText1 As EditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("1")
   
    Dim R As Reflector
    R.Target = EditText1
    R.SetOnFocusListener("ETFocus")

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ETFocus(ViewTag As Object,Focus As Boolean)
    Log(Focus)
End Sub
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Thanks, but I had already solved the problem by creating a new project and copying your Main.

Your code adds a listener to an EditText but this already exists:

B4X:
Sub EditText1_FocusChanged (HasFocus As Boolean)

what changes?

The problem is that which would an event that fires when the EditText loses focus.

The boolean parameter is not enough.

When i click on a button, neither of the two events fire
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
The reflection one does fire when the edittext loses focus. Try the demo and select edittext1 then press Next, or whatever the key is on your soft keyboard to send it to the next edittext and the Focus sub will be called with Focus = false.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
The reflection one does fire when the edittext loses focus. Try the demo and select edittext1 then press Next, or whatever the key is on your soft keyboard to send it to the next edittext and the Focus sub will be called with Focus = false.

the edittext loses focus only when the focus is set on other edittext (or other input view, maybe) but not clicking a button
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Try this:

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Private Button1 As Button
    Private EditText1 As EditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("1")
  
    Dim R As Reflector
    R.Target = EditText1
    R.SetOnFocusListener("ETFocus")
    R.Target = Button1
    R.RunMethod2("setFocusableInTouchMode",True,"java.lang.boolean")

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ETFocus(ViewTag As Object,Focus As Boolean)
    Log(Focus)
End Sub
Sub Button1_Click
    'Button1.RequestFocus  !!not needed
    Log("Clicked")
End Sub
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
To avoid showing the button focused is a bit convoluted, but you could do something like this:

B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Private Button1 As Button
    Private EditText1 As EditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("1")

    Dim R As Reflector
    R.Target = EditText1
    R.SetOnFocusListener("ETFocus")
    R.Target = Button1
    R.RunMethod2("setFocusableInTouchMode",True,"java.lang.boolean")
    R.SetOnFocusListener("BtnFocus")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
Sub ETFocus(ViewTag As Object,Focus As Boolean)
    Log(Focus)
End Sub
Sub Button1_Click
    Log("Clicked")
    EditText1.RequestFocus
End Sub
Sub BtnFocus(ViewTag As Object,Focus As Boolean)
    'The first click will focus the button so treat it as a click
    If Focus Then Button1_Click
End Sub
 
Upvote 0

dexMilano

Active Member
Licensed User
Longtime User
Well,
this is very interesting and may be a little too sophisticated, I need some time to understand it well.
But I cannot say this is a clean solution.
I'm surprised that this regular scenario needs a so weird solution.

As said,
I've to understand exactly your solution.
In any case, thanks for your suggestions.

dex
 
Upvote 0
Top