I'm trying to create a view programmatically, and change its background according to its click state.
I know I can do this with xml drawables, but I want to learn to program it too.
But if I press on my view, then slide my finger, the view gets stuck in pressed state. (white = 0xaaffffff background)
My code is this :
Edit:
I solved the problem. Here is the working code :
mainContainer.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
if (action==MotionEvent.ACTION_DOWN)
{
v.setBackgroundColor(0xaaffffff);
return false;
}
if(action==MotionEvent.ACTION_MOVE)
{
}
if(action==MotionEvent.ACTION_CANCEL)
{
v.setBackgroundColor(0x00ffffff);
}
if (action==MotionEvent.ACTION_UP)
{
v.setBackgroundColor(0x00ffffff);
return true;
}
return false;
}
});
As you see, I tried returning true wherever I want onTouch() to be called again. But apparently there is something I do not understand here.
What am I doing wrong ?
Thanks for any help.
What about returning true in your ACTION_UP aswell?
if (action==MotionEvent.ACTION_UP)
{
v.setBackgroundColor(0x00ffffff);
return true;
}
Related
I may be asking a basic question, but to be honest, I have no real developement or code knowledge. I've been requested to make a prototybe of some basic app, that is supposed mainly to be buttons on screens, activable or disactivable.
I've been coding this on Android Studio 3.0, I (hardly) managed to place PNGs files on the screen, making it looking like a button. When I was pressing it, nothing happened of course, so I searched there and there how to make it change when pressed This worked
casedanger1.setOnTouchListener(new View.OnTouchListener(){
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN :
casedanger1.setImageResource(R.drawable.casedanger1slct);
break;
case MotionEvent.ACTION_UP :
casedanger1.setImageResource(R.drawable.casedanger1);
break;
}
return false;
}
});
But when I try to disable again the button, it doesn't revert to the standard image (casedanger1)
How should I proceed ? I've been searching for days without a real solution. I have tried to make it a toggle button, which works, but makes the image bigger, and thus cropped.
Any hints that could help ? I'm really desperated, this is not something I'm familiar with.
Thank you
-Pliskin
I think you were close. Try this
casedanger1.setOnTouchListener(new View.OnTouchListener(){
// track if the image is selected or not
boolean isSelected = false;
public boolean onTouch(View v, MotionEvent event) {
if(isSelected) {
casedanger1.setImageResource(R.drawable.casedanger1slct);
} else {
casedanger1.setImageResource(R.drawable.casedanger1);
}
// toggle the boolean
isSelected = !isSelected;
return false;
}
});
I have a problem with my code at libGDX in Android Studio. I'm trying to have an object perform an action while I press the screen. If I let go, the previous action should be aborted and a second should begin. When I press again on the screen, the second action should stop again and start the first while I hold down.
I have unfortunately no idea how I should do this and the Internet there is unfortunately also no exact information about it.
This also means that I have no code, which I can show as an aid position.
I would be very happy if someone has a solution, or can help me. :)
I would use an input listener which has a boolean value called touching. Then in the touchDown event set the touching to true. Again in the input listener in the touchUp event set the touching to false.
public class MyController implements InputProcessor {
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
touching = false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
touching = true;
}
//.. more methods etc
}
In your application create this MyController and set it as the inputListsner with:
controller = new MyController();
Gdx.input.setInputProcessor(controller);
Now you can detect when the user is touching and do what ever action you need with:
if(controller.touching){
//user is touching do touching action
}else{
// user isn't touching do the non touchin action
}
You can use this way:
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
// PRESSED
return true; // if you want to handle the touch event
case MotionEvent.ACTION_UP:
// RELEASED
return true; // if you want to handle the touch event
}
return false;
}
});
Let me know if this helps..
You can use in this way inside render method :
if(Gdx.input.isTouched()){
//whether the screen is currently touched.
}else{
}
or
You can pass InputProcessor implemented class inside Gdx.input.setInputProcessor(..)
after then override touchDown(..) and touchUp(...) method of that interface,
choose flag or some other technique for your requirement.
Tapped:
if (Gdx.input.justTouched()) {
//do something; }
Untapped:
if (Gdx.input.getPressure()==0){
//do something-else; }
In a view I want to detect both single tap and double tap. It works fine with me. I can detect both single and double tap. Please find my code
#Override
public boolean onTouch(View view, MotionEvent me) {
// No dragging during animation at the moment.
// TODO: Stop animation on touch event and return to drag mode.
boolean result = true;
result = gestureDetector.onTouchEvent(me);//return the double tap events
if(result)
return false;
switch (me.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
}
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
private String fileName;
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
// event when double tap occurs
#Override
public boolean onDoubleTap(MotionEvent e) {
float x = e.getX();
float y = e.getY();
if(player!=null && player.isPlaying())
{
player.stop();
}
else
{
setFileName(x);
player = new AudioPlayer(fileName);
player.play();
}
return true;
}
}
I am doing some code in Action_UP event. So even when I do a double tap, for the first tap the ACTION_UP event is called and the corresponding code is executed. I want to prevent this from happening. How can I do this. I just want to make sure that the ACTION_UP is called only when the user is done with his gesture. Not immediately after his partial gesture . In this case its being called on finger up of first tap.
How can I make this work in android?
Thanks
According to gesture listener documentation, you need to return true for onSingleTapConfirmed & onDoubleTap. Otherwise the event is not consumed and gestureDetector.onTouchEvent(me); returns false.
I have ImageViews inside of a GridView, I had been using an OnItemClickListener along with an OnItemLongClickListener set on the GridView to open the image on a larger page and to delete the item respectively. Now, I have to implement rearranging of the ImageViews in the GridView, so I plan to move the deletion function to a double tap gesture, (please do not lecture me on android style guidelines (including the possibility of contextual actionbars, which I suggested), as this is what my boss asks for to emulate functions inside our ios app) in order to reserve long click for the drag and drop. I set an OnTouchListener on each view in the getView of my custom adapter, feeding a GestureDetecter with a listener extending SimpleOnGestureListener the given MotionEvent with onTouchEvent. I know what to do up to that point, but when I included (onDown of course, to get other callbacks) onDoubleTap, onSingleTapConfirmed, and onLongPressed all taps were interpreted as long clicks. And when I removed the both callback methods to be replaced with their listener counterparts once again (ie OnItemClickListeners) I received those two gestures but not the double tap, which makes sense, as double taps start out as a single tap unless you wait for a bit less than a second to confirm them as singles rather than potential doubles. I also tried placing the OnItemClickListener, but not the OnItemLongClickListener, with the callback in the extended SimpleOnGestureListener. In this case, only long presses were ever interpreted, but other gestures caused no response. Here is my code as it stands now, and do note that I returned false in the onTouchEvent in order to allow others (itemclicklisteners) to consume the events following the attempts made in the GestureDetector.
public class MainBoardGridAdapter extends GenericBoardGridAdapter implements OnItemLongClickListener {
private class Ges extends GestureDetector.SimpleOnGestureListener {
int pos;
public Ges(View v) {
pos = (Integer) v.getTag();
}
#Override
public boolean onDown(MotionEvent me) {
//this does get called but none of these methods below
return true;
}
#Override
public boolean onDoubleTap(MotionEvent me) {
new DeleteConfirmationPrompt(c, "board") {
#Override
protected boolean onDeleteConfirmed() {
// delete the visionboard
return deleteBoard(pos);
}
}; // Constructor shows dialog
return false;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
MainBoardGridAdapter.super.flagForUpdate(pos);
if (listener != null) {
listener.onBoardClick(pos, getName(pos));
} else {
Intent intent = new Intent(c, VisionBoardActivity.class);
intent.putExtra(VisionBoardActivity.EXTRA_VISION_BOARD_NAME, getName(pos));
frag.startActivityForResult(intent, MyBoardsFragment.REQUEST_EDIT);
}
return false;
}
}
#Override
public boolean onItemLongClick(AdapterView<?> parent, View v,
final int pos, long id) {
Toast.makeText(c, "Long", Toast.LENGTH_LONG).show();
return false;
}
// called by getView of extended adapter
#Override
public void onImageLoaded(ImageView iv, String data, View root) {
iv.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
(new GestureDetector(c, (new Ges(v)))).onTouchEvent(event);
return false;
}
});
}
}
And in the Activity, gv is my GridView:
gv.setOnItemLongClickListener(gridAdapter);
Also note that I had been using true in the return value in the GestureDetector methods, until trying the current configuration.There was no difference to be seen.
Thank you for your valuable time and help, I hope that someone will be able to point out what I am doing incorrectly.
-Jackson
I need to detect WHEN the screen is touched. The onTouchEvent method only detects when the finger is moving. I need method which returns boolean value true, when the finger touches screen and returns false, when its not.
Here's a very basic implementation of the onTouch method that modifies a boolean value to know if a the screen is touched. You may need to tweak it to suit your specific needs (and maybe handle multi touch)
private boolean mIsScreenTouched;
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN :
case MotionEvent.ACTION_MOVE :
mIsScreenTouched = true;
break;
case MotionEvent.ACTION_CANCEL :
case MotionEvent.ACTION_UP :
mIsScreenTouched = false;
break;
}
return true;
}
#Override
public boolean dispatchTouchEvent(MotionEvent e) {
// TODO Auto-generated method stub
super.dispatchTouchEvent(e);
if(btn.onTouchEvent(e)){
return btn.onTouchEvent(e);
}else{
return false;
}
}