I'm relatively a rookie/beginner with Java/Android programming. I've been trying to make it so while I press a given button in my application it produces a DTMF tone, but when I try to use setOnTouchListener the Android Studio shows me that error. It also gives me an error for MotionEvent which states Expression expected
Here are the important parts of the code:
boolean pressedCCW = false;
class SendCCWTone extends AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... arg0){
ToneGenerator toneGen;
toneGen = new ToneGenerator(AudioManager.STREAM_DTMF,100);
while(pressedCCW){
toneGen.startTone(ToneGenerator.TONE_DTMF_1);
}
toneGen.stopTone();
toneGen.release();
createLog("CCW");
return null;
}
}
final Button buttonCCW = (Button) findViewById(R.id.counter_clockwise);
buttonCCW.setOnTouchListener(new View.OnTouchListener(){// Where the error is
#Override
public boolean onTouch(View v, MotionEvent event){// Where the other error is located
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
if(pressedCCW == false){
pressedCCW = true;
new SendCCWTone().execute();
}
break;
case MotionEvent.ACTION_UP:
pressedCCW = false;
}
return true;
}
});
You are creating OnTouchListener inside of setOnClickListener. If you need TouchListener then you should register using setOnTouchListener instead of setOnClickListener
buttonCCW.setOnTouchListener(new View.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event){
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
if(pressedCCW == false){
pressedCCW = true;
new SendCCWTone().execute();
}
break;
case MotionEvent.ACTION_UP:
pressedCCW = false;
}
return true;
}
});
This problem can be solved if you place setOnTouchListener inside the onCreate() method of your activity.
Rather than use setOnClickListener, you can set onClick in the XML and point to a method (it does the same thing and looks nicer). In this case, you'd have a method like produceSound:
public void produceSound(View view) {
// your onClick method
}
and in the activity's XML, find where that button, counter_clockwise, is and add: android:onClick="produceSound" to the button's XML.
More here if you're curious: How exactly does the android:onClick XML attribute differ from setOnClickListener?
However, if you're using onTouch, then you will have to stick with what everyone else is suggesting. XML does not support an android:onTouch attribute.
Try to add this to your code :
implements View.OnTouchListener
and use setOnTouchListner instead of setOnClickListener.
buttonCCW.setOnListener(new View.OnTouchListener(){// Where the error is
#Override
public boolean onTouch(View v, MotionEvent event){// Where the other error is located
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
if(pressedCCW == false){
pressedCCW = true;
new SendCCWTone().execute();
}
break;
case MotionEvent.ACTION_UP:
pressedCCW = false;
}
return true;
}
});
Related
I was creating Ontouchlistener But i got 2 error. 1st unexpected token and 2nd Cannot resolve constructor 'Intent(anonymous android.view.View.OnTouchListener, java.lang.Class<com.krish.galaxypdfviewer.Website>)'
And when i tried onclick listener it worked without any error but i want to use Ontouchlistener
Here is the code whats wrong here?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton actionButton = findViewById(R.id.action_button);
defineView();
handleIntent();
defineActionBar();
checkPermission();
long start;
actionButton.setOnTouchListener(new View.OnTouchListener(){
#Override
public boolean onTouch(final View v, final MotionEvent event){
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
start=System.currentTimeMillis();
return true;
case MotionEvent.ACTION_UP:
if(System.currentTimeMillis()-start<500){ //Click is less than 500ms, you can adjust this value later...
//Do what you want on click over here...
}else{
openWebsite(); //It's a long click, do what you want over here...
}
return true;
default:
return false;
}
});
public void openWebsite() {
Intent intent = new Intent(this, Website.class);
startActivity(intent);
}
There's a missing closing curly brace for the onTouch method.
actionButton.setOnTouchListener(new View.OnTouchListener(){
#Override
public boolean onTouch(final View v, final MotionEvent event){
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
start=System.currentTimeMillis();
return true;
case MotionEvent.ACTION_UP:
if(System.currentTimeMillis()-start<500){ //Click is less than 500ms, you can adjust this value later...
//Do what you want on click over here...
}else{
openWebsite(); //It's a long click, do what you want over here...
}
return true;
default:
return false;
}
} // this one closes onTouch
});
I have two views which are siblings of each other. They both cover the full screen. So one is behind the other. If the upper one gets touched (onTouch), I delegate the touch events to the one underneath it (with dispatchTouchEvent).
But sometimes I want to delay that delegation, till the next time onTouch gets called. But somehow that does not work.
An example to clarify:
To viewA - which is in front of viewB - I have applied the following (simplified) code:
viewA.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
int touchType = event.getActionMasked();
if (touchType == MotionEvent.ACTION_DOWN) {
savedEvent = event;
return true; // I also tried returning false here
} else {
if (savedEvent != null) {
viewB.dispatchTouchEvent(savedEvent);
savedEvent = null;
}
viewB.dispatchTouchEvent(event);
return true; // I also tried returning false here
}
}
});
To test the dispatchTouchEvent call, I have the following code for viewB
viewB.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
Log.d("test", "test"); // this code gets logged, so it is being called, but the view seems to not execute any of the touch events
return true;
}
});
When I change to code for viewA to this:
viewA.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
viewB.dispatchTouchEvent(event);
return true;
}
});
everything works just fine.
But the thing is that for my use case, I sometimes have to call the dispatchTouchEvent method with the event parameter outside its originating onTouch method, so to speak.
Is this even possible? And if yes, how?
So I found out what prevents it from working. If you manually call dispatchTouchEvent you should pass through an event that you created yourself with MotionEvent.obtain().
Working example:
viewA.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
int touchType = event.getActionMasked();
if (touchType == MotionEvent.ACTION_DOWN) {
// do not do this, somehow passing on a reference of the event directly does not work:
// savedEvent = event;
// this works though:
savedEvent = MotionEvent.obtain(event);
return true;
} else {
if (savedEvent != null) {
viewB.dispatchTouchEvent(savedEvent);
savedEvent = null;
}
viewB.dispatchTouchEvent(event);
return true;
}
}
});
Although I don't understand why that does work and just passing the event reference directly does not, I tested this and it does work perfectly.
I am trying to implement some button events without any reference to the XML-File and with databinding instead of FindByID. Is this possible? I am having the problem that, within the OnKeyListener, the bound InputBox from which I try to get the typed text seems inaccessible (this.binding shows in red color where I put it bold). Is this a wrong approach or am I making a mistake? I'd like to avoid all that FindByID-Lines.
this.binding =
DataBindingUtil.setContentView(this, R.layout.content_main);
this.binding.EditNumber.setText("553");
this.binding.EditNumber.setOnKeyListener(new OnKeyListener()
{
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
Cat supertest = Manager.CreateMainCat(this.**binding**.EditNumber.toString());
this.**binding**.DisplayCurrentBudget.setText(supertest.getsName());
return true;
default:
break;
}
}
return false;
}
});
Thank you very much
Strangely, it works when I simply put the binding in another method:
(...)
this.binding.Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
xxx();
}
});
}
public void xxx()
{
Cat supertest = Manager.CreateMainCat(this.binding.EditNumber.getText().toString());
this.binding.DisplayCurrentBudget.setText(supertest.getsName());
}
But this doesn't:
this.binding.Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cat supertest = Manager.CreateMainCat(this.binding.EditNumber.getText().toString());
this.binding.DisplayCurrentBudget.setText(supertest.getsName());
}
The propblem is solved easily, but I'd be very interested to know what's going if someone has the answer :)
So, I'm making a simple android game in Android Studio, and I am trying to make the player x-coordinate follow the x-coordinate of my finger. However, I only get it to where it "teleports" to the x-coordinate I want it to. How can I make it follow my finger when I swipe over the screen?
#Override
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
player.setX((int)event.getX());
}
return super.onTouchEvent(event);
}
You'll have to use android.view.View$OnTouchListener .
Here is an example.
private final class TileOnTouchListener implements OnTouchListener {
#Override
public boolean onTouch(View view, MotionEvent e) {
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
player.setX((int)e.getX());
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
return true;
}
}
For more info check this.
In my android app, I'm trying to check whether a boolean has changed and if it has then do something. But it's not constantly checking it. I believe I need a listener, but I'am unaware on how to structure it or where to put it. I've looked online and can really only find onClicks etc, no boolean ones.
Here is what I have so far:
public boolean gameStartTouch = false;
public boolean titleVisible = true;
/*
public boolean isJumping = false;
public boolean isGrounded = false;
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_main);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
if (gameStartTouch == false) {
gameStartTouch = true;
titleVisible = false;
}
break;
}
return true;
}
and this is what needs to go in the listener:
ImageView titleView = (ImageView) findViewById(R.id.titleImg);
ImageView startNotifView = (ImageView) findViewById(R.id.startNotifImg);
if (titleVisible == false) {
titleView.setVisibility(View.INVISIBLE);
startNotifView.setVisibility(View.INVISIBLE);
} else {
titleView.setVisibility(View.VISIBLE);
startNotifView.setVisibility(View.VISIBLE);
}
Thanks in advance. I couldn't find much info on it for these circumstances specifically.
Do some modifying to your code, manage it like so
#Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
titleView.setVisibility(View.INVISIBLE);
startNotifView.setVisibility(View.INVISIBLE);
break;
}
return true;
}
I would put your findViewById() calls in onCreate to avoid unnecessary resource fetching. The only thing I see is that you are only actually switching your booleans once. Is there any other time you plan to reset gameStartTouch to false and titleVisible to true after the first touch?
#fire_head you can simply declare titleView and startNotifView as your class private members. Initialize them in onCreate method like this:
ImageView titleView = (ImageView) findViewById(R.id.titleImg);
ImageView startNotifView = (ImageView) findViewById(R.id.starting);
and access them in handleGameStartTouch method.
Sorry, I had to post it as an answer as I couldn't comment on the answer above.