I am writing an Android app that needs to respond to touch events. I want my app to change the color of my list item to a custom color. I have written the following code, but only the MotionEvent.ACTION_DOWN section is working. The LogCat shows that ACTION_CANCEL and ACTION_UP aren't called at all. Could you please help me understand why my code isn't working.
This is my code...
view.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
view.setBackgroundColor(Color.rgb(1, 1, 1));
Log.d("onTouch", "MotionEvent.ACTION_UP" );
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
view.setBackgroundColor(Color.rgb(23, 128, 0));
Log.d("onTouch", "MotionEvent.ACTION_DOWN" );
}
if (event.getAction() == MotionEvent.ACTION_CANCEL) {
view.setBackgroundColor(Color.rgb(1, 1, 1));
Log.d("onTouch", "MotionEvent.ACTION_CANCEL" );
}
return false;
}
});
If you return false from onTouch method, no further events get delivered to the listener. You should return true at least in case of event.getAction() == MotionEvent.ACTION_DOWN.
Refactor your code as given below:
view.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
view.setBackgroundColor(Color.rgb(1, 1, 1));
Log.d("onTouch", "MotionEvent.ACTION_UP" );
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
view.setBackgroundColor(Color.rgb(23, 128, 0));
Log.d("onTouch", "MotionEvent.ACTION_DOWN" );
return true;
}
if (event.getAction() == MotionEvent.ACTION_CANCEL) {
view.setBackgroundColor(Color.rgb(1, 1, 1));
Log.d("onTouch", "MotionEvent.ACTION_CANCEL" );
}
return false;
}
});
Related
Problem is on a service view back button is giving me a response but Home and Recent Apps button is not triggering
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_HOME: //Not getting
minimizeApp();
return true;
case KeyEvent.KEYCODE_BACK: //getting
finish(false);
return true;
case KeyEvent.KEYCODE_APP_SWITCH: //Not getting
//minimizeApp();
return true;
}
return true;
}
in the same service, I have tried to add and remove different flags but can't gets what I want.
mLayoutParams =new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN|
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON|
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
|WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
|WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
,
PixelFormat.TRANSLUCENT);
I am getting Back pressed but I want to catch Event of home and recent app pressed.
Updated
I got the solution
li = LayoutInflater.from(this);
LinearLayout lia= new LinearLayout(this) {
//home or recent button
public void onCloseSystemDialogs(String reason) {
if (reason.equals("homekey")){
finisha(false);
}
if (reason.equals("recentapps")){
finisha(false);
}
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
|| event.getKeyCode() == KeyEvent.KEYCODE_APP_SWITCH
|| event.getKeyCode() == KeyEvent.KEYCODE_HOME
) {
//The Code Want to Perform.
// return true;
}
if (event.getKeyCode() == KeyEvent.KEYCODE_HOME){
}
if (event.getKeyCode() == KeyEvent.KEYCODE_APP_SWITCH){
}
return super.dispatchKeyEvent(event);
}
};
lia.setFocusable(true);
final View root = (View) li.inflate(R.layout.layout_alias_locker, lia);
Is there a way to make the SwipeRefreshLayout have a small deadzone so that if the user scrolls to the top and keeps scrolling, it wont immediately try bring down the pull to refresh? i would like it to have a small dead zone because the pull to refresh is interfering with a view pager in the ListView.
if the user swipes the viewpager and moves their finger down very slightly through the drag, it starts to do the pull to refresh and the swipe motion is lost and the viewpager just resets its position.
i've tried doing something like this
mSwipeRefreshLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN)
p1 = new Point((int) event.getX(), (int) event.getY());
else if(event.getAction() == MotionEvent.ACTION_MOVE)
p2 = new Point((int) event.getX(), (int) event.getY());
if(p1 != null && p2 != null && Math.abs(p1.y - p2.y) < 50) {
return true;
}
return false;
}
});
and
mSwipeRefreshLayout.setOnDragListener(new View.OnDragListener() {
#Override
public boolean onDrag(View v, DragEvent event) {
if(event.getAction() == DragEvent.ACTION_DRAG_ENTERED)
p1 = new Point((int) event.getX(), (int) event.getY());
else if(event.getAction() == DragEvent.ACTION_DRAG_LOCATION)
p2 = new Point((int) event.getX(), (int) event.getY());
if(p1 != null && p2 != null && Math.abs(p1.y - p2.y) < 50) {
return true;
}
return false;
}
});
but p2 doesnt get set properly it seems so not sure what to do
In my activity I have an ImageView. It has pinch-zoom feature.
When I touch on ImageView I show thumbnails layout.
But when I pinch on ImageView thumbnail layout shows. I want to block it?
How can I do it?
Here is my code to show thumbnail layout:
image.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Boolean openThumbnails=true;
if(event.getAction() == MotionEvent.ACTION_UP && openThumbnails){
Log.e("event.getAction()", "MotionEvent.ACTION_UP");
if(thumbnailsLayout.getVisibility()==View.GONE && header.getVisibility()==View.GONE && openThumbnails){
thumbnailsLayout.setVisibility(View.VISIBLE);
header.setVisibility(View.VISIBLE);
header.bringToFront();
}
else{
thumbnailsLayout.setVisibility(View.GONE);
header.setVisibility(View.GONE);
}
}
else if(event.getAction() == MotionEvent.ACTION_DOWN){
Log.e("event.getAction()", "MotionEvent.ACTION_DOWN");
return true;
}
else if(event.getAction()==MotionEvent.ACTION_MOVE){
Log.e("openThumbnails before", openThumbnails.toString());
openThumbnails=false;
Log.e("openThumbnails and after", openThumbnails.toString());
}
return false;
}
});
Your openThumbnails is always true. You set it at the start of method. Every touch event (e.g. Action_up, action_move) you set openThumbnail to true. That's why you always show it.
image.setOnTouchListener(new OnTouchListener() {
Boolean openThumbnails=true;
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP && openThumbnails){
Log.e("event.getAction()", "MotionEvent.ACTION_UP");
if(thumbnailsLayout.getVisibility()==View.GONE && header.getVisibility()==View.GONE && openThumbnails){
thumbnailsLayout.setVisibility(View.VISIBLE);
header.setVisibility(View.VISIBLE);
header.bringToFront();
}
else{
thumbnailsLayout.setVisibility(View.GONE);
header.setVisibility(View.GONE);
}
}
else if(event.getAction() == MotionEvent.ACTION_DOWN){
Log.e("event.getAction()", "MotionEvent.ACTION_DOWN");
return true;
}
else if(event.getAction()==MotionEvent.ACTION_MOVE){
Log.e("openThumbnails before", openThumbnails.toString());
openThumbnails=false;
Log.e("openThumbnails and after", openThumbnails.toString());
}
return false;
}
});
I'm trying to call the onTouch method from a different class but I have no idea what to pass in for MotionEvent. Using null makes the app force close. Heres the code
public final class Touch {
private static final String TAG = Touch.class.getSimpleName();
public boolean onTouchEvent(MotionEvent event, Droid droid, Thread thread) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
droid.handleActionDown((int)event.getX(), (int)event.getY());
/*if (event.getY() > getHeight() - 50)
{
thread.setRunning(false);
((Activity)getContext()).finish();
}
else
{
Log.d(TAG, "Coords: x=" + event.getX() + ",y=" + event.getY());
}*/
}
if (event.getAction() == MotionEvent.ACTION_MOVE)
{
// the gestures
if (droid.isTouched())
{
// the droid was picked up and is being dragged
droid.setX((int)event.getX());
droid.setY((int)event.getY());
}
}
if (event.getAction() == MotionEvent.ACTION_UP)
{
// touch was released
if (droid.isTouched())
{
droid.setTouched(false);
}
}
return true;
}
}
Thats the class, how would I call that in the main thread? Currently I'm trying:
public void Touch()
{
MotionEvent event = null;
touch.onTouchEvent(event, droid, thread);
}
As null is the only thing that I can think of to pas in.
Try:
MotionEvent event = MotionEvent.obtain(downTime, eventTime, action, x, y, metaState);
I'm trying to use setontouchlistener. What I would like to do if I hold an imagebutton for an example 5 seconds, I get alerted... this is how I would do it:
final ImageButton imageButton1 = (ImageButton) findViewById(R.id.imageButton1);
imageButton1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// do something
return false;
}
});
How can I implement something like this with setontouchlistener after x seconds?
Working solution:
imageButton1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mTouchDownTime = event.getEventTime();
Log.v("CustomDebug", "Message: " + mTouchDownTime);
}
if (event.getAction() == MotionEvent.ACTION_UP) {
long elapsedTime = event.getEventTime() - mTouchDownTime;
Log.v("CustomDebug", "Message: " + elapsedTime);
}
return false;
}
});
onTouch gets called twice, the first time with a MotionEvent ACTION_DOWN and a second time with the MotionEvent ACTION_UP
so pseudocode:
if Event == ACTION_DOWN
saveTime = time();
elseif Event == ACTION_UP and time()-savetime > 5
doStuff because the guy hold it for 5sec.