How to change the colour of a cardview when selected?clicked - java

I'm trying out card view instead of a button, I love the amount of info you can add to them. But I'm trying to make it so if they press the card it changes colour. I want it to change back once they release, so that it works in a similar way to my buttons.
I can get it so that it changes on click but it stay like that until the activity is destroyed.
This is the code I use for changing the colour at the moment:
public void setSingleEvent(GridLayout maingrid) {
for (int i = 0; i < maingrid.getChildCount(); i++) {
final CardView cardView = (CardView) maingrid.getChildAt(i);
final int finalI = i;
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(mcontext, "Button: " + finalI, Toast.LENGTH_SHORT).show();
cardView.setCardBackgroundColor(mcontext.getResources().getColor(R.color.buttonPressed));
if (finalI == 0) {
mcontext.startActivity(new Intent(mcontext, Genre_Streaming.class));
}
}
});

You can try using OnTouchListener with ACTION_DOWN and ACTION_UP to handle Press/Release events instead of OnClickListener.
Modified Code:
public void setSingleEvent(GridLayout maingrid) {
for (int i = 0; i < maingrid.getChildCount(); i++) {
final CardView cardView = (CardView) maingrid.getChildAt(i);
final int finalI = i;
cardView.setOnTouchListener(new OnTouchListener () {
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == android.view.MotionEvent.ACTION_DOWN) {
Toast.makeText(mcontext, "Button: " + finalI, Toast.LENGTH_SHORT).show();
cardView.setCardBackgroundColor(mcontext.getResources().getColor(R.color.buttonPressed));
if (finalI == 0) {
mcontext.startActivity(new Intent(mcontext, Genre_Streaming.class));
}
} else if (event.getAction() == android.view.MotionEvent.ACTION_UP) {
/* Reset Color */
cardView.setCardBackgroundColor(mcontext.getResources().getColor(R.color.red));
}
return true;
}
}
}
Link: http://developer.android.com/reference/android/view/MotionEvent.html#ACTION_UP

You could try using an onTouchListener instead of an onClickListener to capture the "Motion event" this is an Object used to report movement (mouse, pen, finger, trackball) events.
cardview.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// set color here
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// set other color here
}
}
};
here is a list of motion event constants from the android documentation page

Related

Stop focus on EditText when keyboard is hidden

I'm from iOS development and new in Android app making, something looks really strange to me in Android, why EditText stay focused when keyboard is hidden ??
I've tried to set a OnFocusChangeListener on my EditText but this is not working when the keyboard hide, the listener isn't called.
I've also tried to detect keyboard hiding with a onChangeListener but it doesn't work.. (only with hard keyboard apparently).
#Override
public void onFocusChange(View v, boolean hasFocus) {
// not called when keyboard hides
}
});
I've been looking for a while and I only found answer for stopping focus at first launch but that's not what I'm looking for..
Thanks
Okay, kind of this
private void setUpEtxFocusListener() {
etx.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean hasFocus) {
if (hasFocus) {
if ((LOG_DEBUG)) Log.d(TAG, "etx : GOT Focus");
} else {
if ((LOG_DEBUG)) Log.d(TAG, "etx : LOST Focus");
}
}
});
and when clicked outside, etx will lose focus and you hide the keyboard
//this will trigger etx setOnFocusChangeListener - onFocus change() - NO FOCUS clause
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (v instanceof EditText) {
Rect outRect = new Rect();
v.getGlobalVisibleRect(outRect);
if (!outRect.contains((int) event.getRawX(), (int) event.getRawY())) {
v.clearFocus();
// just an utility class to hide.
UtilExtra.hideKeyboard(this);
}
}
}
return super.dispatchTouchEvent(event);
}
Try this:
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
you can simply use this code and your focus will be gone
editText.clearFocus();
To catch keyboard's open/close event use this code:
//...
private int layoutSize = 0;
private boolean isKeyboardVisible = false;
//...
#Override
public void onCreate(Bundle savedInstanceState) {
setKeyboardOpenListener();
}
//...
private void setKeyboardOpenListener() {
View activityRootView = findViewById(android.R.id.content);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
if (activityRootView.getHeight() + Util.getStatusBarHeight(this) >= layoutSize) {
layoutSize = activityRootView.getHeight();
if (isKeyboardVisible) {
isKeyboardVisible = false;
onKeyboardClose();
}
} else {
if (!isKeyboardVisible) {
isKeyboardVisible = true;
onKeyboardOpen();
}
}
});
}
//...
public static int getStatusBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
Use editText.clearFocus() and editText.setCursorVisible(false) both methods, It may helps you.

Get X and Y coordinates of OnLongClickListener

I want to get the X & Y coordinates of the location where i long click and set the button to this location, but i don't get it because there is no MotionEvent as with the onClick method.
private View.OnLongClickListener layoutOnTouchListener(){
return new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
RelativeLayout.LayoutParams positionRules = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
positionRules.leftMargin = (int) v.getX();
positionRules.topMargin = (int) v.getY();
mainButton.setLayoutParams(positionRules);
Log.d("X", String.valueOf(v.getX()));
return true;
}
};
}
Thats the code i tried.
You can try setonkeyListener and check whether it's long click or not
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (null != keyEvent && keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
if (System.currentTimeMillis() - mLastClickedTime > DEFAULT_PRESSED_DELAY) {
Log.d(TAG, "onKey: single presed");
onKeyPressed(view, keyEvent);
} else {
Log.d(TAG, "onKey: repeat pressed");
onKeyRepeatPressed(view);
}
mLastClickedTime=System.currentTimeMillis();
}
return false;
}
If it's long click take the x and y points

Detecting swipes, click, hold on one View Android

I have an ImageView which fills my whole Activity. I need to be able to detect 4 touch events :
Hold (longer than 400 ms)
Click
Swipe Left
Swipe Right
At the moment I am able to detect the first two using the following code :
imageView.setOnTouchListener(new View.OnTouchListener() {
private Timer timerr = new Timer();
private long LONG_PRESS_TIMEOUT = 400; // TODO: your timeout here
private boolean wasLong = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d(getClass().getName(), "touch event: " + event.toString());
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// HOLD DETECTED
timerr.schedule(new TimerTask() {
#Override
public void run() {
SlideShow.this.runOnUiThread(new Runnable() {
#Override
public void run() {
}, LONG_PRESS_TIMEOUT);
return true;
}
if (event.getAction() == MotionEvent.ACTION_UP) {
if (!isPaused && !wasLong) {
// CLICK DETECTED
timerr.cancel();
timerr = new Timer();
if (!wasLong) {
return false;
}
});
Now I am trying to use the code from this question to implement the swipe right and swipe left actions. Android Swipe on List The problem with this is that this works on listview, where you can implement an onTouchListener for the whole listview, and a seperate onItemClickListener for the list item. I do not know how to adapt this to this situation though where only one Listener is available.
Gesture Detector is the way to go.
Alternatively,
image.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x1 = event.getX();
y1 = event.getY();
t1 = System.currentTimeMillis();
return true;
case MotionEvent.ACTION_UP:
x2 = event.getX();
y2 = event.getY();
t2 = System.currentTimeMillis();
if (x1 == x2 && y1 == y2 && (t2 - t1) < CLICK_DURATION) {
Toast.makeText(getActivity(), "Click", Toast.LENGTH_SHORT).show();
} else if ((t2 - t1) >= CLICK_DURATION) {
Toast.makeText(getActivity(), "Long click", Toast.LENGTH_SHORT).show();
} else if (x1 > x2) {
Toast.makeText(getActivity(), "Left swipe", Toast.LENGTH_SHORT).show();
} else if (x2 > x1) {
Toast.makeText(getActivity(), "Right swipe", Toast.LENGTH_SHORT).show();
}
return true;
}
return false;
}

Running out of memory using many editTexts and onclicklisteners

I have an application that has a layout with ~150 editText's and a mainActivity that has an onClickListener for each of these editTexts, and a button which loops through them all and clears them.
The application was running fine, and without making any significant changes I am now getting the following logCat error everytime i start up the application:
Out of memory on a 2903056-byte allocation.
Is there any obvious bad practices I am doing here that is causing the memory loss?
Some of my code below as illustration (this is repeated many times obviously)
box0101.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
box0301.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
box0401.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
box0501.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
box0601.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
and also some buttonclick listeners that set off some loops
btnClear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clearBoard();
}
});
public void clearBoard() {
final int ROW_COUNT = 14;
final int COL_COUNT = 9;
final String ROWS[] = {"01","02","03","04","05","06","07","08","09","10","11","12","13","14","15"};
final String COLS[] = {"01","02","03","04","05","06","07","08","09","10"};
for(int i=0; i<ROW_COUNT; i++) {
for(int j=0; j<COL_COUNT; j++) {
String a = ROWS[i];
String b = COLS[j];
int editTextId = getResources().getIdentifier("box" + a + b , "id", getPackageName());
EditText et=(EditText)findViewById(editTextId);
et.setText("");
}
}
}
As #alex.veprik mentioned: try to use one OnClickListener, and assign it to all your EditText-objects. If you create a new OnClickListener for every EditText-object, although they all do the same, this will eat a lot of your memory.
Example)
View.OnTouchListener boxListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
txtHint.setText(hintPrefix + onOneClick);
return false;
}
});
//boxes is a list of all your boxes
for(int i=0; i < boxes.size(); i++) {
boxes.get(i).setOnTouchListener(boxListener);
}
It might also be wise to put the creation of your EditText-objects in a loop, and to store only the list of all boxes in a member variable. So instead of having 150 variables, you now only need one for the list, while at the same time keeping all the references. (this doesn't affect your memory problem, but it's good code style)
List<EditText> boxes = new ArrayList<EditText>();
for (int i = 0; i < NBR_OF_BOXES; i++) {
boxes.add(new EditText());
}
As #zapl recommended, it might also be good to use a memory profiler.
Instead of having a onTouch() method for each EditText, use a switch statement to create a case for each EditText, using the EditText ID
public boolean onTouch(View v, MotionEvent event) {
switch(v.getId())
{
case R.id.editTextID:
//Do something, etc
}
return false;
}

Detecting a long press in Android

I am currently using onTouchEvent(MotionEvent event) { } to detect when the user presses my glSurfaceView is there a way to detect when a long click is made.
I'm guessing if I can't find much in the dev docs then it will be some sort of work around method. Something like registering ACTION_DOWN and seeing how long it is before ACTION_UP.
How do you detect long presses on Android using opengl-es?
GestureDetector is the best solution.
Here is an interesting alternative. In onTouchEvent on every ACTION_DOWN schedule a Runnable to run in 1 second. On every ACTION_UP or ACTION_MOVE, cancel scheduled Runnable. If cancelation happens less than 1s from ACTION_DOWN event, Runnable won't run.
final Handler handler = new Handler();
Runnable mLongPressed = new Runnable() {
public void run() {
Log.i("", "Long press!");
}
};
#Override
public boolean onTouchEvent(MotionEvent event, MapView mapView){
if(event.getAction() == MotionEvent.ACTION_DOWN)
handler.postDelayed(mLongPressed, ViewConfiguration.getLongPressTimeout());
if((event.getAction() == MotionEvent.ACTION_MOVE)||(event.getAction() == MotionEvent.ACTION_UP))
handler.removeCallbacks(mLongPressed);
return super.onTouchEvent(event, mapView);
}
Try this:
final GestureDetector gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
public void onLongPress(MotionEvent e) {
Log.e("", "Longpress detected");
}
});
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
};
I have a code which detects a click, a long click and movement.
It is fairly a combination of the answer given above and the changes i made from peeping into every documentation page.
//Declare this flag globally
boolean goneFlag = false;
//Put this into the class
final Handler handler = new Handler();
Runnable mLongPressed = new Runnable() {
public void run() {
goneFlag = true;
//Code for long click
}
};
//onTouch code
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
handler.postDelayed(mLongPressed, 1000);
//This is where my code for movement is initialized to get original location.
break;
case MotionEvent.ACTION_UP:
handler.removeCallbacks(mLongPressed);
if(Math.abs(event.getRawX() - initialTouchX) <= 2 && !goneFlag) {
//Code for single click
return false;
}
break;
case MotionEvent.ACTION_MOVE:
handler.removeCallbacks(mLongPressed);
//Code for movement here. This may include using a window manager to update the view
break;
}
return true;
}
I confirm it's working as I have used it in my own application.
I have created a snippet - inspired by the actual View source - that reliably detects long clicks/presses with a custom delay. But it's in Kotlin:
val LONG_PRESS_DELAY = 500
val handler = Handler()
var boundaries: Rect? = null
var onTap = Runnable {
handler.postDelayed(onLongPress, LONG_PRESS_DELAY - ViewConfiguration.getTapTimeout().toLong())
}
var onLongPress = Runnable {
// Long Press
}
override fun onTouch(view: View, event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
boundaries = Rect(view.left, view.top, view.right, view.bottom)
handler.postDelayed(onTap, ViewConfiguration.getTapTimeout().toLong())
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
handler.removeCallbacks(onLongPress)
handler.removeCallbacks(onTap)
}
MotionEvent.ACTION_MOVE -> {
if (!boundaries!!.contains(view.left + event.x.toInt(), view.top + event.y.toInt())) {
handler.removeCallbacks(onLongPress)
handler.removeCallbacks(onTap)
}
}
}
return true
}
When you mean user presses, do you mean a click? A click is when the user presses down and then immediately lifts up finger. Therefore it is encompassing two onTouch Events. You should save the use of onTouchEvent for stuff that happens on the initial touch or the after release.
Thus, you should be using onClickListener if it is a click.
Your answer is analogous: Use onLongClickListener.
The solution by MSquare works only if you hold a specific pixel, but that's an unreasonable expectation for an end user unless they use a mouse (which they don't, they use fingers).
So I added a bit of a threshold for the distance between the DOWN and the UP action in case there was a MOVE action inbetween.
final Handler longPressHandler = new Handler();
Runnable longPressedRunnable = new Runnable() {
public void run() {
Log.e(TAG, "Long press detected in long press Handler!");
isLongPressHandlerActivated = true;
}
};
private boolean isLongPressHandlerActivated = false;
private boolean isActionMoveEventStored = false;
private float lastActionMoveEventBeforeUpX;
private float lastActionMoveEventBeforeUpY;
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
longPressHandler.postDelayed(longPressedRunnable, 1000);
}
if(event.getAction() == MotionEvent.ACTION_MOVE || event.getAction() == MotionEvent.ACTION_HOVER_MOVE) {
if(!isActionMoveEventStored) {
isActionMoveEventStored = true;
lastActionMoveEventBeforeUpX = event.getX();
lastActionMoveEventBeforeUpY = event.getY();
} else {
float currentX = event.getX();
float currentY = event.getY();
float firstX = lastActionMoveEventBeforeUpX;
float firstY = lastActionMoveEventBeforeUpY;
double distance = Math.sqrt(
(currentY - firstY) * (currentY - firstY) + ((currentX - firstX) * (currentX - firstX)));
if(distance > 20) {
longPressHandler.removeCallbacks(longPressedRunnable);
}
}
}
if(event.getAction() == MotionEvent.ACTION_UP) {
isActionMoveEventStored = false;
longPressHandler.removeCallbacks(longPressedRunnable);
if(isLongPressHandlerActivated) {
Log.d(TAG, "Long Press detected; halting propagation of motion event");
isLongPressHandlerActivated = false;
return false;
}
}
return super.dispatchTouchEvent(event);
}
The idea is creating a Runnable for execute long click in a future, but this execution can be canceled because of a click, or move.
You also need to know, when long click was consumed, and when it is canceled because finger moved too much. We use initialTouchX & initialTouchY for checking if the user exit a square area of 10 pixels, 5 each side.
Here is my complete code for delegating Click & LongClick from Cell in ListView to Activity with OnTouchListener:
ClickDelegate delegate;
boolean goneFlag = false;
float initialTouchX;
float initialTouchY;
final Handler handler = new Handler();
Runnable mLongPressed = new Runnable() {
public void run() {
Log.i("TOUCH_EVENT", "Long press!");
if (delegate != null) {
goneFlag = delegate.onItemLongClick(index);
} else {
goneFlag = true;
}
}
};
#OnTouch({R.id.layout})
public boolean onTouch (View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
handler.postDelayed(mLongPressed, ViewConfiguration.getLongPressTimeout());
initialTouchX = motionEvent.getRawX();
initialTouchY = motionEvent.getRawY();
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_CANCEL:
if (Math.abs(motionEvent.getRawX() - initialTouchX) > 5 || Math.abs(motionEvent.getRawY() - initialTouchY) > 5) {
handler.removeCallbacks(mLongPressed);
return true;
}
return false;
case MotionEvent.ACTION_UP:
handler.removeCallbacks(mLongPressed);
if (goneFlag || Math.abs(motionEvent.getRawX() - initialTouchX) > 5 || Math.abs(motionEvent.getRawY() - initialTouchY) > 5) {
goneFlag = false;
return true;
}
break;
}
Log.i("TOUCH_EVENT", "Short press!");
if (delegate != null) {
if (delegate.onItemClick(index)) {
return false;
}
}
return false;
}
ClickDelegateis an interface for sending click events to the handler class like an Activity
public interface ClickDelegate {
boolean onItemClick(int position);
boolean onItemLongClick(int position);
}
And all what you need is to implement it in your Activity or parent Viewif you need to delegate the behavior:
public class MyActivity extends Activity implements ClickDelegate {
//code...
//in some place of you code like onCreate,
//you need to set the delegate like this:
SomeArrayAdapter.delegate = this;
//or:
SomeViewHolder.delegate = this;
//or:
SomeCustomView.delegate = this;
#Override
public boolean onItemClick(int position) {
Object obj = list.get(position);
if (obj) {
return true; //if you handle click
} else {
return false; //if not, it could be another event
}
}
#Override
public boolean onItemLongClick(int position) {
Object obj = list.get(position);
if (obj) {
return true; //if you handle long click
} else {
return false; //if not, it's a click
}
}
}
setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
int action = MotionEventCompat.getActionMasked(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
longClick = false;
x1 = event.getX();
break;
case MotionEvent.ACTION_MOVE:
if (event.getEventTime() - event.getDownTime() > 500 && Math.abs(event.getX() - x1) < MIN_DISTANCE) {
longClick = true;
}
break;
case MotionEvent.ACTION_UP:
if (longClick) {
Toast.makeText(activity, "Long preess", Toast.LENGTH_SHORT).show();
}
}
return true;
}
});
Here is an approach, based on MSquare's nice idea for detecting a long press of a button, that has an additional feature: not only is an operation performed in response to a long press, but the operation is repeated until a MotionEvent.ACTION_UP message is received. In this case, the long-press and short-press actions are the same, but they could be different.
Note that, as others have reported, removing the callback in response to a MotionEvent.ACTION_MOVE message prevented the callback from ever getting executed since I could not keep my finger still enough. I got around that problem by ignoring that message.
private void setIncrementButton() {
final Button btn = (Button) findViewById(R.id.btn);
final Runnable repeater = new Runnable() {
#Override
public void run() {
increment();
final int milliseconds = 100;
btn.postDelayed(this, milliseconds);
}
};
btn.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN) {
increment();
v.postDelayed(repeater, ViewConfiguration.getLongPressTimeout());
} else if (e.getAction() == MotionEvent.ACTION_UP) {
v.removeCallbacks(repeater);
}
return true;
}
});
}
private void increment() {
Log.v("Long Press Example", "TODO: implement increment operation");
}
option: custom detector class
abstract public class
Long_hold
extends View.OnTouchListener
{
public#Override boolean
onTouch(View view, MotionEvent touch)
{
switch(touch.getAction())
{
case ACTION_DOWN: down(touch); return true;
case ACTION_MOVE: move(touch);
}
return true;
}
private long
time_0;
private float
x_0, y_0;
private void
down(MotionEvent touch)
{
time_0= touch.getEventTime();
x_0= touch.getX();
y_0= touch.getY();
}
private void
move(MotionEvent touch)
{
if(held_too_short(touch) {return;}
if(moved_too_much(touch)) {return;}
long_press(touch);
}
abstract protected void
long_hold(MotionEvent touch);
}
use
private double
moved_too_much(MotionEvent touch)
{
return Math.hypot(
x_0 -touch.getX(),
y_0 -touch.getY()) >TOLERANCE;
}
private double
held_too_short(MotionEvent touch)
{
return touch.getEventTime()-time_0 <DOWN_PERIOD;
}
where
TOLERANCE is the maximum tolerated movement
DOWN_PERIOD is the time one has to press
import
static android.view.MotionEvent.ACTION_MOVE;
static android.view.MotionEvent.ACTION_DOWN;
in code
setOnTouchListener(new Long_hold()
{
protected#Override boolean
long_hold(MotionEvent touch)
{
/*your code on long hold*/
}
});
I found one solution and it does not require to define runnable or other things and it's working fine.
var lastTouchTime: Long = 0
// ( ViewConfiguration.#.DEFAULT_LONG_PRESS_TIMEOUT =500)
val longPressTime = 500
var lastTouchX = 0f
var lastTouchY = 0f
view.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
lastTouchTime = SystemClock.elapsedRealtime()
lastTouchX = event.x
lastTouchY = event.y
return#setOnTouchListener true
}
MotionEvent.ACTION_UP -> {
if (SystemClock.elapsedRealtime() - lastTouchTime > longPressTime
&& Math.abs(event.x - lastTouchX) < 3
&& Math.abs(event.y - lastTouchY) < 3) {
Log.d(TAG, "Long press")
}
return#setOnTouchListener true
}
else -> {
return#setOnTouchListener false
}
}
}

Categories