I am attempting to make a simple android app that calculates the diameter of a sonar signal. The user inputs the depth(in meters) and angle(in degrees) and the app inputs the information into the formula:
2.0 * depth * Math.tan(angle / 2.0)
So I have created the UI and the java code and when I go to run the app in a VM it loads, I enter numbers in to test it, and when I hit the calculate button it does nothing. I am new to java and android development in general so if anyone could shed some light that would be great.
Here is the MainActivity.java
XML file for the UI widgets activity_main.xml
I suspect the problem is something to do with this code that includes the formula but I am not sure so any help would be greatly appreciated:
double depth1 = Integer.parseInt(depth.getText().toString());
double angle1 = Integer.parseInt(angle.getText().toString());
double result1 = 2.0 * depth1 * Math.tan(angle1 / 2.0);
result.setText(valueOf(result1));
It does nothing because you have added onClickListener on TextView instead of the Button here:
result.setOnClickListener(...)
You just need to change it to this:
// instance of your button
cal.setOnClickListener(...)
You are using the clicklistener of your result view, that is why the value is not displayed on clicking on the cal view (calculate button). Try the following.
cal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//converting the user input from a string to an integer for calculation
double depth1 = Integer.parseInt(depth.getText().toString());
double angle1 = Integer.parseInt(angle.getText().toString());
double result1 = 2.0 * depth1 * Math.tan(angle1 / 2.0);
result.setText(String.valueOf(result1));
}
});
We use setOnContextClickListener to register a callback to be invoked when this view is context clicked. If the view is not context clickable, it becomes context clickable.
So, as mentioned above, insteasd
result.setOnClickListener(...)
use
cal.setOnClickListener(...)
Please refer:
https://developer.android.com/reference/android/view/View.html#setOnContextClickListener(android.view.View.OnContextClickListener)
Related
Recently I've been trying to use a wired Xbox 360 controller to interface with my Arduino Uno (via Processing) that I'm using in a test circuit to control two brushed motors. I came across this video that uses the library to control a single servo motor along with videos made by the library's author. I made a few modifications to the code (from the first link) just to support the two motors, and it works (sort of). The only problem is that it accepts input from my Bluetooth mouse instead of the Xbox controller which are both connected to my laptop's USB ports. I set the text configuration file so that "Button 0" and "Button 2" -which correspond to the A and X buttons respectively- make two pins on the Arduino go high which feed into the bases of two transistors that control the motors. Instead, the left mouse button and scroll wheel button on my Bluetooth mouse controls these outputs.
I'm a bit confused about why this is happening and I've tried a few different things to resolve the issue. I thought that when creating the configuration file (with a program that comes with the library) I accidentally choose my mouse as the input device, so I made another configuration file just to make sure that this wasn't the case, though I'm not exactly sure what in the configuration file indicates the correct device to use. Maybe I'm missing something extremely obvious, I just know that I need a second set of eyes to look things over for me. If you have experience with this library your help would be much appreciated, thank you.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Configuration File:
Tests the xbox controller with motors.
lMotor Left Motor 1 BUTTON Button 0 0 0.0 0.0
rMotor Right Motor 1 BUTTON Button 2 0 0.0 0.0
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Java from Processing:
import processing.serial.*;
import net.java.games.input.*;
import org.gamecontrolplus.*;
import org.gamecontrolplus.gui.*;
import cc.arduino.*;
import org.firmata.*;
ControlDevice cont;
ControlIO control;
Arduino arduino;
//variables for the "A Button" and "X Button" on the xbox controller
ControlButton aButton;
ControlButton xButton;
//needed variables of type int for background function to work (change window color when buttons are pressed)
int aInt;
int xInt;
void setup() {
size(360, 200);
control = ControlIO.getInstance(this);
cont = control.getMatchedDevice("xboxtest");
if(cont == null) {
println("Error, something went wrong");
System.exit(-1);
}
//println(Arduino.list());
arduino = new Arduino(this, Arduino.list()[0], 57600);
arduino.pinMode(8, Arduino.OUTPUT);
arduino.pinMode(11, Arduino.OUTPUT);
}
//gets the input and is called in the looping function (void draw)
public void getUserInput() {
//rMotor and lMotor are references to the configuration file
aButton = cont.getButton("lMotor");
xButton = cont.getButton("rMotor");
aInt = 0;
xInt = 0;
if (aButton.pressed() == true) {
aInt = 1;
}
if (xButton.pressed() == true) {
xInt = 1;
}
}
void draw() {
getUserInput();
//changes the color of the interactive window when the input changes
background(100 * aInt, 100, 100 * xInt);
arduino.digitalWrite(8, aInt * 255);
arduino.digitalWrite(11, xInt * 255);
}
UPDATE: I was able to fix the problem after looking at some example code provided by the library that I was previously unaware of. In my defense, there is little support for this library and the video that I watched didn't use the line of code that I found in the example. I hope that this benefits someone in the future.
I ended up changing this:
cont = control.getMatchedDevice("xboxtest");
To this:
cont = control.filter(GCP.GAMEPAD).getMatchedDevice("xboxtest");
I need to double tap with two fingers simulataneously on logo to proceed to next screen?
Yes, there exists a method to perform a double tab:
TouchActions action = new TouchActions(driver);
action.doubleTap(element);
action.perform();
You can try below code with help of touch action.
Define Mobile element as mentioned below
MobileElement mobileElement= (MobileElement) driver.findElement(by);
And pass this element to below function.
public void tapTwiceOnElement(MobileElement mobileElement) {
int halfHeight = element.getLocation().getX();
int halfWidth = element.getLocation().getY();
new TouchAction(driver).press(ElementOption.point(halfWidth,halfHeight)).release().perform().press(ElementOption.point(halfWidth,halfHeight)).release().perform();
new TouchAction(driver).press(ElementOption.point(halfWidth,halfHeight)).release().perform().press(ElementOption.point(halfWidth,halfHeight)).release().perform();
}
this is a Java code for two finger double tap, in case anyone needs it:
Preconditions: you can change withPosition to withElement and x and y values need to be predefined.
MultiTouchAction secondTwoFingerPress = new MultiTouchAction(DeviceBucket.getDriver());
secondTwoFingerPress.add(new TouchAction(DeviceBucket.getDriver())
.tap(TapOptions.tapOptions()
.withPosition(PointOption.point(xPoint, yPoint))
.withTapsCount(2)));
secondTwoFingerPress.add(new TouchAction(DeviceBucket.getDriver())
.tap(TapOptions.tapOptions()
.withPosition(PointOption.point(xPoint1, yPoint1))
.withTapsCount(2)));
secondTwoFingerPress.perform();
Based on appium documentation: https://appium.io/docs/en/writing-running-appium/touch-actions/
You can use MultiTouch gesture.
Pseudocode example of tapping with two fingers:
action0 = TouchAction().tap(el)
action1 = TouchAction().tap(el)
MultiAction().add(action0).add(action1).perform()
Had an issue where I needed to place a marker at the exact centre of my map screen and looked at a lot of questions and answers that were not exactly what I wanted to do. The app allows the user to move map about and then once crosshairs that are exactly in the centre of the map are at the desired location, you tap a button and a marker appears at that location.
map.getProjection().fromScreenLocation almost met my needs but I did not have the coordinates so could not implement that solution.
So my answer hopefully will help someone in the same situation.
So my soltuion was to use the getCameraPosition method as follows. And its fired from the button R.id.addMarker in my xml.
findViewById(R.id.addMarker).setOnClickListener(
new View.OnClickListener(){
#Override
public void onClick(View view) {
if(myMap != null){
double myLat = myMap.getCameraPosition().target.latitude;
double myLng = myMap.getCameraPosition().target.longitude;
LatLng markerPoint = new LatLng(myLat, myLng);
myMap.addMarker(new MarkerOptions().position(markerPoint)).setTitle("next marker");
}
}
}
);
Hope it helps someone in the same predicament.
I don't understand why fromScreenLocation doesn't suit your needs...
If you pass the map's width and the map's height divided by two as it's parameters, this function will return you a LatLng object giving you the corresponding location in terms of latitude and longitude. After that, it is easy to place a Markerat this position.
I just began to develop a app with java, and I only got some experience in C. In my code in Activity.java (in android studio) I got things like, just to give some examples:
meteorite1.setX(meteoritePlacementX(meteorite1.getX()));
meteorite1.setY(-2000);
gnome.setX(330);
gnome.setY(800);
meteorite2.setX(meteoritePlacementX(meteorite2.getX()));
meteorite2.setY(meteoritePlacementY(meteorite1.getY()));
meteorite3.setX(meteoritePlacementX(meteorite3.getX()));
meteorite3.setY(meteoritePlacementY(meteorite2.getY()));
meteorite4.setX(meteoritePlacementX(meteorite4.getX()));
meteorite4.setY(meteoritePlacementY(meteorite3.getY()));
meteorite5.setX(meteoritePlacementX(meteorite5.getX()));
meteorite5.setY(meteoritePlacementY(meteorite4.getY()));
meteoritedestruction1.setX(0);
meteoritedestruction1.setY(-2000);
meteoritedestruction2.setX(0);
meteoritedestruction2.setY(-2000);
meteoritedestruction3.setX(0);
meteoritedestruction3.setY(-2000);
meteoritedestruction4.setX(0);
meteoritedestruction4.setY(-2000);
meteoritedestruction5.setX(0);
meteoritedestruction5.setY(-2000);
star1.setX(300);
star2.setX(150);
star3.setX(50);
star4.setX(500);
star5.setX(600);
star6.setX(350);
star7.setX(80);
star8.setX(450);
tinystar1.setX(302);
tinystar2.setX(240);
tinystar3.setX(57);
tinystar4.setX(660);
tinystar5.setX(400);
star1.setY(300);
star2.setY(-300);
star3.setY(-100);
star4.setY(100);
star5.setY(300);
star6.setY(500);
star7.setY(700);
star8.setY(900);
tinystar1.setY(300);
tinystar2.setY(-400);
tinystar3.setY(-200);
tinystar4.setY(150);
tinystar5.setY(30);
and
public float meteoritePlacementX(float X){
float MeteoriteNewX = 0f;
int random = (int )(Math.random() * 480 - 50);
MeteoriteNewX = random;
return MeteoriteNewX;
}
Which workes fine, but just on my phone (720 x 1280 pixels (~294 ppi pixel density)) which I tested my code at. Now I published my app, but on other device, the layout of the app is totally out of sync (which makes sense to me now, cause x and y are different for every screen). Buttons and pictures workes fine, but moving object like
meteorite1.setY(meteorite1.getY() + 20);
where I use x and y are broken on other devices. I use the relative layout.
So long story short; Is there a way to change x and y, so it becomes relative to the screen? Otherwise I need to change the whole code.
In general using placement based on hard coded pixel values is not a good practice. Not only would this break with backwards compatibility but also think about what you would have to do when 2k+ phones come out, you would need an entire refactor. Look at this question and the answer by Guillaume Perrot you can get get the maximum and minimum pixel values relative to the user's phone and use those instead of the 480 - 50 and your star set functions.
For the movement do
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = (WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE); // the results will be higher than using the activity context object or the getWindowManager() shortcut
wm.getDefaultDisplay().getMetrics(displayMetrics);
int maxWidth = displayMetrics.widthPixels;
//Make this percentage whatever you want
float movementPercentage = 0.02
//Will move the object 2 percent up the y axis
meteorite1.setY(meteorite1.getY() + maxWidth*movementPercentage);
I'm trying to animate UI elements. I would like to move an editText and a Button from the middle to the top of the screen and display results of an http call below them in a table. It would be great if anyone could point me in the right direction, at this point I don't know wether I should use Java or XML for this.
Thanks in advance.
Use Translation framework to achieve this, this works as:
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
So you need to write your code for moving view in y-axis direction, as follows:
mAnimation = new TranslateAnimation(0, 0, 0, 599);
mAnimation.setDuration(10000);
mAnimation.setFillAfter(true);
mAnimation.setRepeatCount(-1);
mAnimation.setRepeatMode(Animation.REVERSE);
view.setAnimation(mAnimation);
Here view may be anything, textview, imageView etc.
accepted answer caused an error inside my code, code snippet below almost identical to accepted answer & worked without causing errors, to slide an object off the screen. i needed gestures tied to keyPad to also 'slide away' , and switched from TranslateAnimation to ObjectAnimator (second block of code below).
final LinearLayout keyPad = (LinearLayout)findViewById(R.id.keyPad);
moveKeyPadUp(keyPad);
private void moveKeyPadUp(LinearLayout keyPad){
Animation animation = new TranslateAnimation(0,0,0,-500);
animation.setDuration(1000);
animation.setFillAfter(true);
keyPad.startAnimation(animation);
}
private void moveKeyPadUpdated(LinearLayout keyPad){
ObjectAnimator mover = ObjectAnimator.ofFloat(keyPad,"translationY",0,-500);
mover.setDuration(300);
mover.start();
}