Android recyclerview item onTouchListener - java

I want to be able to receive touch events (down, move and maybe up) from my recyclerview items. Now it does not fire at all. Here is my code:
FragmentMain.java
noteRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
#Override
public boolean onInterceptTouchEvent(#NonNull RecyclerView rv, #NonNull MotionEvent e) {
return false;
}
#Override
public void onTouchEvent(#NonNull RecyclerView rv, #NonNull MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN) {
child1 = rv.findChildViewUnder(e.getX(), e.getY());
Log.e("down", "aaa");
} else if (e.getAction() == MotionEvent.ACTION_MOVE) {
Log.e("move", "aaa");
}
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
});
How to solve that?

You have to place touchlistener in your adapter class in the onBindViewHolder method like this:
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.itemView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
// place your code here
Toast.makeText(getApplicationContext(), "Action Down", Toast.LENGTH_SHORT).show();
}
if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
// place your code here
Toast.makeText(getApplicationContext(), "Action Move", Toast.LENGTH_SHORT).show();
}
return false;
}
});
}

Related

OnclickListener not working when including onTouchListener with it

I am having a little issue when trying to use both onTouchListener and onCLickListener for the ok button within a dialog. Basically when I click on the OK button to dismiss the dialog, it recognises the onTouch but it doesn't perform the onClick where I want the dialog to close, the dialog remains open. What am I doing incorrectly in my implementation?
questionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// custom dialog
final Dialog dialog = new Dialog(MainActivity.this);
dialog.setContentView(R.layout.custom_dialog);
Button dialogButton = dialog.findViewById(R.id.dialog_button_OK);
// if button is clicked, close the custom dialog
dialogButton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
setButtonPress(v, event);
return true;
}
});
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
});
public void setButtonPress(View v, MotionEvent event){
int sdk = android.os.Build.VERSION.SDK_INT;
Button view = (Button) v;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
v.setBackgroundDrawable(getResources().getDrawable(R.drawable.love_heart_dark));
} else {
v.setBackground(getResources().getDrawable(R.drawable.love_heart_dark));
}
break;
case MotionEvent.ACTION_UP:
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
v.setBackgroundDrawable(getResources().getDrawable(R.drawable.love_heart));
} else {
v.setBackground(getResources().getDrawable(R.drawable.love_heart));
}
break;
case MotionEvent.ACTION_CANCEL: {
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
v.setBackgroundDrawable(getResources().getDrawable(R.drawable.love_heart));
} else {
v.setBackground(getResources().getDrawable(R.drawable.love_heart));
}
break;
}
}
Try this
Button dialogButton = dialog.findViewById(R.id.dialog_button_OK);
// if button is clicked, close the custom dialog
dialogButton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
setButtonPress(v, event);
return false;
}
});
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
You cannot use two actions on a single view at once.
Try this
Boolean b = false;
questionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// custom dialog
final Dialog dialog = new Dialog(MainActivity.this);
dialog.setContentView(R.layout.custom_dialog);
Button dialogButton = dialog.findViewById(R.id.dialog_button_OK);
// if button is clicked, close the custom dialog
dialogButton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(b==false){
setButtonPress(v, event);
b=true;
return true;
}
else{
//perform on click here
}
}
});
dialog.show();
}
});

Double tap in an activity extends view

i'm working on android app for painting and i want when i do double tap a bitmap appear in the view. here i do some debug but i don't know why it's not working.
Actually this class implements another class TouchEventView which contain Touchevent and motion event.
i have tried also implements double tap in the other class but it's not working as well
public class PlotActivity extends AppCompatActivity implements
GestureDetector.OnDoubleTapListener,GestureDetector.OnGestureListener{
private TouchEventView tev;
private TextView message;
private GestureDetectorCompat gestureDetector;
public static final String DEBUGTAG="JWP";
Button enreg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plot);
tev = (TouchEventView) findViewById(R.id.canva);
this.gestureDetector = new GestureDetectorCompat(this, this);
gestureDetector.setOnDoubleTapListener(this);
}
public void clearCanvas(View v){
tev.clearCanvas();
}
public void enregInfo(View v){
tev.savetofile();
}
#Override
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
Log.i(DEBUGTAG, "onLongPress: " );
return true;
}
#Override
public boolean onTouchEvent(MotionEvent event){
this.gestureDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
#Override
public boolean onDoubleTap(MotionEvent motionEvent) {
Log.i(DEBUGTAG, "onLongPress: " );
return true;
}
#Override
public boolean onDoubleTapEvent(MotionEvent motionEvent) {
Log.i(DEBUGTAG, "onLongPress: " );
return true;
}
#Override
public boolean onDown(MotionEvent motionEvent) {
return true;
}
#Override
public void onShowPress(MotionEvent motionEvent) {
}
#Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
return true;
}
#Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
return true;
}
#Override
public void onLongPress(MotionEvent motionEvent) {
}
#Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
return true;
}
}

How to play audio only while button is held down?

I am trying to make a simple app: there is one button in the middle which a child would press. As long as that button is held down it would play a certain MP3.
At the moment, I tried with onClick, but, that plays only when the button is released.
Instead of using an onClickListener which exposes nothing more then an interface for press and release, you would need to use an onTouchListener - which exposes all touch events of a view.
myButton.setOnTouchListener( new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch ( event.getAction() ) {
MotionEvent.ACTION_DOWN:
// start playing
return true;
MotionEvent.ACTION_UP:
// stop playing
return true;
}
return false;
}
});
Try something like this. Using the boolean "playing" you can create a thread/loop elsewhere to check if still playing and keep audio going.
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if (arg1.getAction()==MotionEvent.ACTION_DOWN) {
playing = true;
} else {
playing = false;
}
return true;
}
});
Try the OnFocusChangeListener
Button.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
// code to execute when Button loses focus, i.e. stop music
}
}
});
Since a button is a view component you can use View.OnTouchListener event listener with ACTION_BUTTON_PRESS & ACTION_BUTTON_RELEASE MotionEvent.
Here is an example:
yourButton.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_BUTTON_PRESS){
// Start Video
return true;
} else if (event.getAction() == MotionEvent.ACTION_BUTTON_RELEASE) {
// End Video
return true;
}
return false;
}
});
This is my code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void start_recording(View view){
MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.test1);
mediaPlayer.start();
}
}

Android do not execute setOnTouchListener if setOnLongClickListener has been executed

I have an app where you can press on a screen and a method gets executed, and where you can long press and another method gets executed. The problem is, when I long press on the screen the normal onClickListener also gets executed, which I don't want.
They both are simple onClickListeners, the normal one is using the MotionEvent ACTION_UP. Is there any way to prevent that from happening?
So I don't want to execute the ACTION_UP in the normal onTouchListener when the onLongClickListener executed.
Code:
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
}
return false;
}
});
layout.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
return true;
}
});
If you still want to onTouch
int flag=0
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if(flag==0){
//do something
}else{
flag=0;
}
}
return false;
}
});
layout.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
flag=1
return true;
}
});
LongClick and Click are in the same level, while Touch isn't (actually LongClick an Click are dispatched from onTouchEvent).
In your code, you always return false in onTouch method, so you don't comsume the event and it will be passed to the next level (LongClick, Click...), this is why when you long press the screen you have the both method called.
Suggestion1:
Use ClickListener instead of TouchListener.
Suggestion2:
Use GestureDetector to handle all events (touch, longclick...). This is an example
Suggestion3:
Use a flag to perform the desired event.
private boolean longClick = false;
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (longClick) {
longClick = false;
}
return false;
}
});
layout.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
longClick = true;
return false;
}
});
Suggestion4:
Use a handler with runnable. Example1 and Example2
If onclick does the same as you intended use onclick listner instead of ontouch that way you wont trigger onclick when you longclick.

Intercept click touch but not scroll in Android

I've searching through web and doc to intercept a click event and let super manage scroll in an Android application.
Eg : by default when I scroll on my view an another view moved with it. I'm able to get click event but at the moment of I get onDown returning true; the other view is not able to scroll with it. I've tried to return false on onScroll by it didn't make it.
I've both code with basic onTouchListener or GestureDetectorCompat doing the same stuff.
WIth Gesture Detector :
mGestureDetector = new GestureDetectorCompat(mContext, new ClickListener());
mRootFrameLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
});
class ClickListener extends GestureDetector.SimpleOnGestureListener {
#Override
public boolean onDown(MotionEvent e) {
Log.d(LOG_TAG, "onDown");
return true;
}
#Override
public void onShowPress(MotionEvent e) {
Log.d(LOG_TAG, "onShowPress");
}
#Override
public boolean onSingleTapUp(MotionEvent event) {
Log.d(LOG_TAG, "click");
return true;
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.d(LOG_TAG, "onScroll");
return false;
}
#Override
public void onLongPress(MotionEvent e) {
Log.d(LOG_TAG, "onLongPress");
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.d(LOG_TAG, "onFling");
return false;
}
}
Is there a way to defer event on a special view with DispatchTouchEvent or anything else ?

Categories