Run multiple performClick() with UI update - android

button.performClick();
For software demonstration purposes, I want to show the user interface updating after each button performClick(). For example, if the Activity was a calculator I can currently simulate the pressing of buttons [1], [2] and [3] using
btn1.performClick();
btn2.performClick();
btn3.performClick();
However, these updates to the EditText too quickly with no visible pause, i.e. it appears "123" are written to the screen simultaneously. What I want is:-
btn1.performClick() updates UI so people can physically see only button press updated to the EditText before the next button does. Similarly with btn2.performClick() and then btn3.performClick().

You may want to use a library like Robotium, and use Solo.waitForText Method to do what you want.
The problem is that we can not determine in advance the time that it will take to display the text, as it depends on the content of your onClick method.
It's why Robotium may be useful for what you want.

You can either use
Thread.sleep(delay);
or use
handler.postDelayed(Runnable,delay);

Use handler for btn2.performClick() and btn3.performClick() like...
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// do something after 100ms
btn2.performClick();
}
}, 100);

Related

floating View displaying on hover in android

I am trying to implement some hints when a user is hovering a button or another view, I see that android have support for onHoverListener but I don't understand how it really works. However I did try to find a solution how to make a floating editText on a button hover but I didn't find any ideas.
I am thinking that hover in android is the same think with long click because you can't hover with finger without clicking the view.
OnHoverListener is only implemented in 2 specific situations: a) when a Bluetooth or USB mouse is plugged into the device, or b) on Galaxy Note devices, when the S-Pen (stylus) is hovering over the object.
In specific setups/situations this can be a very neat feature, but unfortunately, most users will never even know it exists. For your situation, you may want to implement an OnLongClickListener for showing hints/tips as that is pretty standard in Android.
This example will show a TextView or ImageView hint for 5 seconds when a long-click is initiated:
btn.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
findViewById(R.id.hint).setVisibility(View.VISIBLE);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
findViewById(R.id.hint).setVisibility(View.GONE);
}
}, 5000);
return true;
}
});
Hope this helps,
I want to add up on Aaron's answer.
Some devices with sensitive screens - Samsung S5 comes to mind - don't even need an s-pen.
Just need to hold your finger 1/2 inch over the screen and it would trigger it.

simulate and dispatch touch event

I have loaded a HTML page (say it has a text and a button at the end of the page to share the text) inside a WebView.
The thing is i want to simulate the touch event of that share button and dispatch it to webview. That is (once the user spends some time in reading the text i would like to simulate the share button click (onClick method should be called) in an automated fashion so that even if user doesn't click share i have made it mandatory to be shared.
That's the logic. I refereed to some questions reg touch events in Stack Overflow and found that dispatchTouchEvent and MotionEvent should be used but not clear how to use them and apply my logic.
It would be really helpful if someone could explain its usage with respect to the above quoted idea in a detailed manner.
This is possible if you know the x,y coordinates where to click.
in this java example (not mine) it shows that given a rectangle of a DOM element, it will simulate a click:
The advantage here is that you can simulate the click even if the user didnt initiate an action (which is restricted by the browser itself)
https://github.com/46cl/cordova-android-focus-plugin/blob/master/src/android/Focus.java
This is a cordova example. See here for an example on how to call it from a regular android program:
Android Webview: Execution of javascript from java method called from javascript
runOnUiThread(new Runnable() {
public void run() {
final long uMillis = SystemClock.uptimeMillis();
webView.dispatchTouchEvent(MotionEvent.obtain(uMillis, uMillis,
MotionEvent.ACTION_DOWN, centerLeft, centerTop, 0));
webView.dispatchTouchEvent(MotionEvent.obtain(uMillis, uMillis,
MotionEvent.ACTION_UP, centerLeft, centerTop, 0));
}
});
you would need to dispatch the call from your javascript passing the rect to your java code:
here is an example (of a cordova app) calling the java method from javascript:
https://github.com/46cl/cordova-android-focus-plugin/blob/master/www/focus.js

How can I wait for button click in android?

I'm about to finish my Simon Says game, but I still have one crucial problem.
After my buttons are shown to the player, I have to wait (according to the level, e.g, if 5 buttons were showed to the user, I have to wait the user to click 5 buttons). I have searched around the internet, but the only answer was "You cannot freeze the android Application... blah blah blah".
Here it is my code:
public boolean playerTurn(){
//Enable buttons
buttonUp.setClickable(true);
buttonDown.setClickable(true);
buttonRight.setClickable(true);
buttonLeft.setClickable(true);
/*
Wait for a button clicks depends on the level, but HOW?
e.g, if the level is 5, I have to wait for 5 button clicks
and after it, I can continue to run the code
*/
/*Check if the user typed the correct order
*If pressed the correct order
*return true;
*else
*return false
*/
}
For each button do something like this:
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
buttonsPressedCount++;
if (buttonsPressedCount >= 5) {
// Do whatever you wanted to do
}
}
});
In this way, each button will listen for clicks and update a global counter. Finally when your global counter is greater than 5, you can proceed. The application is never "paused", it just only moves on the next section when five buttons have been clicked.
I'm not near a computer so no code example (will post later). Basically, you can set a class level counter. Provide an OnClickListener for each button - can be same or different. In the listener increment the counter and check if it reached 5 or not. If it did, check the pattern and clear counter.
You can use RxBindings for this purpose. Convert the clicks into a stream of events, and add a subscriber to it, which will react to the event of a click.
Here's how you can do it,
RxView.clicks(button)
.take(5)
.subscribe(aVoid ->
{
// Do your stuff
});
This will add a subscriber to the click event, and will only take the first five events.
Hope it helps.

Android - Trigger a loop that repeatedly redraws in a listener (force invalidate even though UI thread is busy)

I have a view that contains a user's drawing. When clicking a 'play' button I want to have a loop that draws the image from start to finish.
In attempting to do this I basically have a loop inside of an onClickListener for the play button that essentially invalidates the view, waits, sets the next set of points and invalidates again.
The problem is that the image doesn't actually redraw until after the entire image is draw. So essentially nothing happens and then it's all of a sudden done. After doing some research, my assumption is that invalidate is telling the main UI thread to redraw when it gets time, but it's already hung up on dealing with the listener, so it doesn't actually draw until the loop is finished. I've tried calling onDraw directly, using postInvalidate, and just about any other ridiculous thing I can think of, but I'm not sure how to get this to work.
Here are some code snippets:
In my PaintActivity(Which has a PaintAreaView)
The scrubber indicates the progress of the drawing. The first to lines in onProgressChanged works when I manually use the seek bar, but not when pressing play, which is why I tried adding all the extras.
_scrubber.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
_paintAreaView.setPointsToDraw(_scrubber.getProgress());
_paintAreaView.invalidate();
_mainViewGroup.invalidate();
_paintAreaView.postInvalidate();
_mainViewGroup.postInvalidate();
_paintAreaView.drawPoints(_paintAreaView.getCanvas());
_paintAreaView.invalidate();
}...
My Play Button stuff:
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
...
playDrawing();
...
}
});
private void playDrawing()
{
int endPoint = getPaintPointCount();
while(_scrubber.getProgress() < endPoint)
{
_scrubber.incrementProgressBy(1);
try{
Thread.sleep(10);
}catch(InterruptedException e)
{
Thread.currentThread().interrupt();
}
//_paintAreaView.setPointsToDraw(_scrubber.getProgress());
//_paintAreaView.invalidate();
//_mainViewGroup.invalidate();
if(_isPaused)
break;
}
}
I'm not a huge fan of using that sleep, but I've struggled with other solutions and that's my next thing to research. But for this question, incrementing the progress bar does successfully call onProgressChanged, but again it just isn't drawing the view until it's out of that play button click listener.
If I have to wait until I'm out of the listener to get this to work, I'm new enough that I'm not sure how I would approach that.
Sorry for my bad code, any help is much appreciated to help me understand what's happening here and what I need to understand to get this to work.
Thank you!
I got it to work, I'm not sure if all I did was necessary, but here are the changes I made based on my Main UI thread theory being the problem.
I created a class Thread member variable:
private Thread _drawThread;
In onCreate():
_drawThread = new Thread(){
public void run(){
playDrawing();
}
};
play Button onClick:
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
...
_drawThread.start();
}
});
Seems to be doing just what I want! Except the app crashes the second time I hit play :) From here I don't think it'll be to bad to figure out that issue though.
EDIT-----
Creating the Thread in my play button onClickListener instead of having it be a member variable fixed the crashing. I incorrectly assumed the thread would be destroyed as soon as the listener went out of scope on the main thread, but I guess that's not the case.

Robotium waitForView to disappear?

I'm using robotium 3.1 and I'd like to wait for a view to disappear, is there some way I can do that easily? My current way involves a ugly busy-loop with sleeps that makes no one happy.
To clarify what I'd like to happen:
waitForView(<View>) //The view appears
//The view is visible for a few seconds
waitForViewNotThere(<View>) //waits until the view has disappeared
The view that appears doesn't contain any text or such either. Any input is very much appreciated.
This is how:
final TextView helloWorldText = solo.getText("Hello world!");
solo.waitForCondition(new Condition() {
#Override
public boolean isSatisfied() {
return helloWorldText.getVisibility() == View.INVISIBLE;
}
}, 10000);
Whatever you do you are probably going to have some sort of sleep in the loop. (If you look at robotiums source it also uses sleeps). You can keep them to a minimum by using the waitforidlesync method on instrumentation that waits for the Ui thread to become idle.
if you want to wait for a view to disappear, use solo.waitForDialogToClose(long timeout).
Parameters :
timeout - the amount of time in milliseconds to wait.
returns : true if the Dialog is closed before the timeout and false if it is not closed.

Categories

Resources