I am using the SDK "Corona" to develop Android applications in Lua.
I was wondering if you could all assist me in the following problem I have been experiencing. I am in the process of designing an app with text fields towards the bottom of the screen, but I would like the text fields to change position once touched, so that the keyboard does not overlap them when it pops up.
As such, I created a listener to execute code which changes the Y position of 2 fields when either one is touched, but for some odd reason, the code is not working. If I place the code in a button event listener however, it seems to work fine. Please refer to my code:
----------------email textbox -------------
local textField = native.newTextField( display.contentCenterX, display.contentCenterY + 60, 200, 40 )
textField.placeholder = "Email"
textField.isEditable = true
--function to handle events
local function touchListener( event )
textField.y = display.contentCenterY - 100
textField2.y = display.contentCenterY - 50
end
textField:addEventListener( "touch", touchListener )
I thank you in advance for your help.
If I'm correct, since textFields are a native object (and not a display object), they do not handle "touch" event.
As such you will need to use the "userInput" event to trigger the move of the textField.
Here is an example of the listener I have used in the past for this case (without the code to move around):
local function fctFieldListener(oEvent)
local oTextField = oEvent.target
if "began" == oEvent.phase then
-- Move the input up if at the bottom
elseif "editing" == oEvent.phase then
elseif "submitted" == oEvent.phase then
native.setKeyboardFocus( nil )
elseif "ended" == oEvent.phase then
-- Move the input back at his original place if adjusted
end
end
And you add it to the textfield like this:
oTextField:addEventListener( 'userInput', fctFieldListener )
Also, I highly recommend that you put your native.newTextField in a specific display group that you will be moving around, instead of moving around the textField itself, makes things a lot easier.
Related
We are developing QT cross platform application. We have one conversation ListView(Basically list of chats using qml ListView) and requirement is to perform some functionality depending on the first visible index in screen. to find first Visible index we are using function indexAt(real, real). Function call always returns -1.
Documentation which we refereed can be found here QML ListView
Here is sample code snippet
ListView
{
id: id_conversation_list
anchors.fill: parent
model: Conversations
spacing: 5
delegate: id_loader
clip: true
onContentYChanged:
{
console.log("====index===== " + id_conversation_list.indexAt(0, contentY));
}
}
Even i tested with fixed values like (0, 0) or (10, 50) but function always returns -1. If anybody already faced same issue please guide us. Is there any other possible way to find first visible index in qml Listview.
I'm starting with one programatically created AutoCompleteTextView view on my layout. After user typed valid data into the field, I'm creating a new AutoCompleteTextView object right under the first one by the same way, with the same parameters. I'm storing all of the field references in an ArrayList to keep up with the last one, this way I'm making sure that there will be new fields only under the one at the bottom (basically the last element in the reference list) - so it goes on at every field.
I would like to add this feature: when a new field is created, I change the last field's IME options to EditorInfo.IME_ACTION_NEXT and nextFocusForward attribute to the freshly created field - also programmatically. What I want to achieve: right when user presses Enter on the keyboard, last field's focus jumps to the new field. I'm using this code to set new IME options:
ArrayList<AutoCompleteTextView> fields = new ArrayList<>();
//Creating freshlyCreatedField, IT'S STILL NOT IN THE fields LIST!
AutoCompleteTextView currentlySelectedField = fields.get(fields.size() - 1); // last element
currentlySelectedField.setImeOptions(EditorInfo.IME_ACTION_NEXT);
currentlySelectedField.setNextFocusForwardId(freshlyCreatedField.getId());
currentlySelectedField.setSingleLine(true); //ACTV needs it to get IME to work
//Adding freshlyCreatedField to the fields list,
//so next time it will be the currentlySelectedField
But after running this code nothing happens to the currently selected AutoCompleteTextView object. Clearing and requesting focus did not work, and making it work by the reversed way (creating +1 "invisible" (technically GONE) field everytime) would be much more painful.
One more thing: after selecting any other field and re-selecting the one with configuration changes the Enter button works as it should first time! If I could do the same programmatically, it would solve my problem... so, any ideas how to do it? (Of course, I welcome better solutions also... ;) )
After some days, I've started to play with this problem again. Yes, it is a solution, but no, it's not so pretty as I would it to be like...
Anyhow, I created this code:
ArrayList<AutoCompleteTextView> fields = new ArrayList<>();
//Creating freshlyCreatedField, IT'S STILL NOT IN THE fields LIST!
//Last element
AutoCompleteTextView currentlySelectedField = fields.get(fields.size() - 1);
currentlySelectedField.setOnEditorActionListener(
new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_NEXT
|| actionId == EditorInfo.IME_ACTION_DONE
|| event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
freshlyCreatedField.requestFocus();
handled = true;
}
return handled;
}
});
//Adding freshlyCreatedField to the fields list,
//so next time it will be the currentlySelectedField
I put an EditorActionListener to the field actually under edit where the keyboard listens for one of the IME_ACTION_NEXT (if it's already set) and IME_ACTION_DONE action IDs (it's the default), or for the Enter key (for the case if someone would like to use physical keyboard). Then it jumps to the field below.
It works great, there aren't terrible problems with this approach. However I'm a little bit sad, because all of these possibilities stay invisible. The Done action button switches to Next only by clicking to somewhere else as I wrote it down in my question. So I think my "solution" can work, but it's not the best answer, so feel free to write your thoughts down if you have another idea... :)
I have a couple of if-statements and if one of them is true it will print a character on the screen.
char d = 'a';
char c = 'b';
if(A == TRUE) //see comments below
{
Print(200,200,d);
}
if(B == TRUE)
{
Print(200,200,c);
}
void Print(int x, int y, char u)
{
glRasterPos2f(x,y);
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, u);
}
The problem is that if A is true, it will print 'a' on the screen correctly, but if afterwards B is true and A not anymore it will print 'b' on the screen while the character 'a' is still there. How can I solve this so that only one character is on the screen. Any help would be appreciated.
Big thanks to datenwolf. The most important thing is to put the glutPostRedisplay in the right place. I placed it at the end of my void Print(..) function. I just looked where I should place it and for me this works now (it was just a small adjustment).
OpenGL's design is built on the premise, that the while window is redrawn if anything needs a change. Normally all drawing operations should be done from only a central display function. Changes that need to be reflected in what's visible on the screen should be dealt with by preparing the list of things to be drawn and then issue a full redraw event.
Update
Actually you have a completely different problem
In the statement if(A = TRUE) two things are happening:
A gets assigned the value TRUE
the result of that assignment (which is TRUE) is tested for truth, which it is and hence will always pass.
The same goes for if(B = TRUE).
The right operator to use is == (two equal signs in a row). With most compilers you can enable a warning and turn that into an error, that assignments are not allowed in a branching statement. A stylistic approach is to write tests for equality as
if( TRUE == A )
which avoids accidents like yours. However in your case you can simply write
if( A )
without any comparison operators at all. And I strongly suggest you do that.
I'm new to Android and I'm building a simple application to start with. It consists of a client with three screens. In the first screen the user is prompted for an Ip to connect to a server (I use an EditText and a button). If the connection is successfully established, some data will be retrieved from the server and the client will show the data on a blank screen (I use a TextView). This would be the second screen. Then, the user could ask the server for detailed information about any data that has been retrieved from the server, which would be the third screen (I use a TextView again).
The problem is that I don't know what's the best way to go about it. I have currently one activity and one XML file containing all the components of the view (EditText, button, TextView). Until now, I've been using setVisibility(View.GONE);to hide certain components depending on the screen the user is in. (For example in the first screen I have to hide both TextViews).
One of the problems I'm facing is that when I put the phone in a horizontal position the components I had hidden show up again. I don't know if hiding views is the ideal thing to do for my purpose.
I've thought that maybe I should use more than one activity, shouldn't I?
I really appreciate any help you can give me to structure my first app.
I would definitely recommend splitting up your App into multiple Activities/Fragments. Depending on how big the logic for each screen gets you will be glad you did it later on because each Activity only has one responsibility.
Look at your mail app for example. You got your List Activity showing you all your mails and then when you select one it starts the Detail Activity showing you the content of your mail. Each Activity is only responsible for one thing which make each one easier to write and maintain.
It also simplifies your layout definitions because each one only contains the relevant parts.
Seems like this is coming up a lot. Android destroys and recreates and Activity when the configuration changes. Screen rotation is part of the orientation. In order to avoid that, the Activity is responsible for retaining state. The mechanisms given for that are the onCreate and onSaveInstanceState. In your example, you could do something like the following:
int uiPhase = 1;
#Override
void onCreate( Bundle data ) {
uiPhase = data.getInt( "uiPhase", 1 );
// inflate layout
setPhase( uiPhase );
}
// invoke the following each time your screen changes
void setPhase( int newPhase ) {
uiPhase = newPhase;
switch( uiPhase ) {
case 1: // show UI elements for first screen, hide others
break;
case 2: // show UI elements for second screen, hide others
break;
case 3: // show UI elements for third screen, hide others
break;
}
}
#Override
void onSaveInstanceState( Bundle data ) {
data.put( "uiPhase", uiPhase );
}
I didn't want to complicate the pattern above too much, but a good method for setting visibility is as follows:
phase1view.setVisibility( uiPhase == 1 ? View.VISIBLE : View.GONE );
phase2view.setVisibility( uiPhase == 2 ? View.VISIBLE : View.GONE );
phase3view.setVisibility( uiPhase == 3 ? View.VISIBLE : View.GONE );
That pulls the repetition in the setPhase method quite a bit together.
Set button visibility to GONE (button will be completely "removed" -- the buttons space will be available for another widgets) or INVISIBLE (button will became "transparent" -- its space will not be available for another widgets):
use in place of
setVisibility(View.GONE)
change to
setVisibility(View.INVISIBLE) and try
I am new to android and programming. I am writing an app for calculating BMI. It works fine but there is a problem. The basic structure is:
Weight: "Edittext"
Height: "Edittext"
Reset Calculate <--- buttons
The app hangs whenever the user presses calculate button without entering a value (Height or weight). thats happening because a mathematical calculation is taking place without any values. how can i prevent the calculation from taking place when there are no values?????
Thankyou in advance
In the onClick function for the calculate button, check to see if the values make sense. If they don't, then don't do anything...
prior to any operation check for null values .
onCkick(View V)
{
if(editWeight.getText() != null or editHeight.getText() != null)
{
//do operation
}
}