I would like to create a RecyclerView in which a user can long click an image and preview the full sized image until they release the long click.
I have it mostly working but the issue I am having is that if I begin the long click, then drag my finger (while still holding the click down), the listener no longer waits for my ACTION_UP event and the preview image never goes away. Is there a way to sort of ignore the dragging/scrolling so that my preview image view goes away when I release the long click?
This is what I have for event listeners:
/* Long press will trigger hover previewer */
holder.thumbnailImageView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View pView) {
holder.thumbnailImageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View pView, MotionEvent pEvent) {
pView.onTouchEvent(pEvent);
// We're only interested in when the button is released.
if (pEvent.getAction() == MotionEvent.ACTION_UP) {
if (isImageViewPressed) {
// Do something when the button is released.
isImageViewPressed = false;
mHoverView.setVisibility(View.GONE);
}
}
return false;
}
});
isImageViewPressed = true;
GlideApp.load(item.getUrl()).into(mHoverView);
mHoverView.setVisibility(View.VISIBLE);
return true;
}
});
/* Long press will trigger hover previewer */
holder.thumbnailImageView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View pView) {
isImageViewPressed = true;
GlideApp.load(item.getUrl()).into(mHoverView);
mHoverView.setVisibility(View.VISIBLE);
return true;
}
});
holder.thumbnailImageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View pView, MotionEvent pEvent) {
pView.onTouchEvent(pEvent);
// We're only interested in when the button is released.
if (isImageViewPressed && pEvent.getAction() == MotionEvent.ACTION_UP) {
// Do something when the button is released.
isImageViewPressed = false;
mHoverView.setVisibility(View.GONE);
}
return true;
}
});
This will work and your code is not working as longClickListener does't get's the event of action down(and neither of action down) and what you are doing currently is setting the listener for touch which never got Action_DOWN i.e by default the View's ontouch() return false on Action_Down so u have to override and return true before action down is called so that it get's action move and action up etc.
Related
I have a button that I would like clickable only by a stylus.
I used the method setClickable to enable or disable the click on the button, but how can I do that is clickable only with a pen?
the button should be clickable only when MotionEvent.TOOL_TYPE_STYLUS
how do i can?
you could override the Button's onTouchListener, and return immediately it the touch event is not performed through TOOL_TYPE_STYLUS. To retrieve this information, you can use
getToolType(int pointerX)
From the documentation
Gets the tool type of a pointer for the given pointer index
if it returns TOOL_TYPE_STYLUS, then you can simply check the MotionEvent for the ACTION_DOWN/ACTION_UP, and call performClick(). E.g.
b.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS) {
if (event.getAction() == MotionEvent.ACTION_UP ) {
performClick();
return true;
}
}
return false;
}
});
I am currently trying to detect an ongoing touch event in my Android app.
In detail I want to recognize within a fragment whether the user touches any part of the app's screen.
Android's OnTouchListener works as expected except if the touch event lasts longer than a few seconds without moving.
For example the first 1-2 seconds of touch are being detected but everything after won't.
Is there something like an "OnPressListener" or a workaround?
If it's a well defined gesture you are trying to detect, have a look at GestureDetector.
http://developer.android.com/reference/android/view/GestureDetector.html
You can use
aButton.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View arg0) {
Toast.makeText(getApplicationContext(), "Long Clicked " ,
Toast.LENGTH_SHORT).show();
return true; // <- set to true
}
});
on your aButton and if you are using API < 19 you have to add
android:longClickable="true"
Attribute to your aButton in layout xml.
I finally found it out.
The solution is to use a simple OnTouchListener:
private boolean pressed = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
pressed = true;
} else if ((action == MotionEvent.ACTION_UP)
|| (action == MotionEvent.ACTION_CANCEL)) {
pressed = false;
}
return true;
}
I am pulling my hair out trying to find a reliable way to consistently allow a user to long press on a gridview item for up to 15 seconds and ALWAYS ALWAYS receive a ACTION_UP when the users finger is released. I also would like to allow unlimited movement once a long press is detected NOTHING besides a finger being lifted should interrupt this process.
Some additional info this is all inside of a gridview which is inside of a pager , but ik what i want to do is possible bc ik of other apps that do such a thing flawlessly
Here is my most recent attempt, but ive tried dozens:
public class recordVideo implements OnLongClickListener,OnTouchListener {
private int position;
private String clicked_uid;
public recordVideo(int position){
this.position=position;
}
#Override
public boolean onLongClick(View v){
//do things
// Do something when your hold starts here.
isSpeakButtonLongPressed = true;
Log.i("START_RECORD","longClick");
return true;
}
#Override
public boolean onTouch(View pView, MotionEvent pEvent) {
pView.onTouchEvent(pEvent);
if (pEvent.getAction() == MotionEvent.ACTION_DOWN) {
Log.i("START","video");
}
// We're only interested in when the button is released.
if (pEvent.getAction() == MotionEvent.ACTION_UP) {
// We're only interested in anything if our speak button is currently pressed.
Log.i("STOP_RECORD","video");
if (isSpeakButtonLongPressed) {
// Do something when the button is released.
isSpeakButtonLongPressed = false;
// Log.i("STOP_RECORD","video");
}
}
return true;
}
I have to develop one apps, in that i want to fire one action, like button is vibrate contentiously during press,i leave press it stop vibration.
In onTouch - event occur only during press,but when i press button contentiously -> event occur contentiously
like i press button for 1 minute it vibrate for same time,if leave press it stop.
i don't know which method used for this, so, please any one help me to do like this.
my code is below to do that : but it not work for continuous action during press (using thread it work for vibrate only, if i join more code with that it give error see in following.
**Edit : **
i got solution for vibrate using like below but when i write code (below vibrator.vibrate(100); ) for some animation that continuous during press then i got error : Only the original thread that created a view hierarchy can touch its views. i also try with runOnUIThread also but with that it not work.
img_laser_ballpen.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
MainActivity.this.vibrating = true;
img_laser_light.setVisibility(View.VISIBLE);
new Thread(new Runnable() {
public void run() {
while (MainActivity.this.vibrating) {
// ADD CODE FOR MAKING VIBRATION
vibrator.vibrate(100); // it works properly
//Animation shake = AnimationUtils.loadAnimation(
MainActivity.this, R.anim.shake);
//img_laser_light.startAnimation(shake); //if it open then give error
}
//
}
}).start();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
MainActivity.this.vibrating = false;
img_laser_light.setVisibility(View.INVISIBLE);
}
return vibrating;
}
});
You could like this
Button btn = (Button) findViewById(YOUR_BUTTON_ID);
btn.setOnTouchListener(new OnTouchListener() {
public boolean onTouch (View v, MotionEvent event){
if(event.getAction() == MotionEvent.DOWN){
// Start vibrating
}else if (event.getAction() == MotionEvent.UP){
// Stop vibrating
}
}
});
This answer has a good example of catching these events; namely - you should use the OnTouchListener instead of OnClickListener.
// this goes wherever you setup your button listener:
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
// START VIBRATE HERE
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// STOP VIBRATE HERE
return true;
}
}
};
Edit:
You should return true after handling your vibrate so that other events are fired for this view. From the documentation:
onTouch() - This returns a boolean to indicate whether your listener consumes this event. The important thing is that this event can have multiple actions that follow each other. So, if you return false when the down action event is received, you indicate that you have not consumed the event and are also not interested in subsequent actions from this event. Thus, you will not be called for any other actions within the event, such as a finger gesture, or the eventual up action event.
You could opt for the following:
Button btn = (Button) findViewById(YOUR_BUTTON_ID);
boolean vibrating = true;
btn.setOnTouchListener(new OnTouchListener() {
public boolean onTouch (View view, MotionEvent event){
if(event.getAction() == MotionEvent.DOWN){
YOUR_CLASS_NAME.this.vibrating = true;
new Thread(
new Runnable(){
public void run(){
while(YOUR_CLASS_NAME.this.vibrating){
//ADD CODE FOR MAKING VIBRATION
}
}
}
).start();
}else if (event.getAction() == MotionEvent.UP){
YOUR_CLASS_NAME.this.vibrating = false;
}
}
});
The most common way to handle a button click is:
button.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
//exeute some code here
}
});
So I click the button, hold for a while and it executes the code when my finger actually leaves the button. When I hold it, I can't click it anymore (I mean while clicking - nothing happens).
1) Is it possible to execute the code when I my finger touches the button (not when it leaves)?
2) Is it possible to execute the code when I hold the button and then my second finger touches it (I want to use multitouch feature)?
As #Raghunandan commented, use setOnTouchListener as follow..
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN) {
Log.e(TAG,"Down");
return true;
}
if (event.getAction()==MotionEvent.ACTION_MOVE){
Log.e(TAG,"Move");
return true;
}
if (event.getAction()==MotionEvent.ACTION_UP){
Log.e(TAG,"Up");
return true;
}
return false;
}
});