how to disable dispatch touch event in some portion of screen - android

I want to disable dispatch touch for some area for your understanding here is my screen.
You can see Header,Footer and Mapview in image but when I clicked on location button(right side in header), My map is also getting notified (like it got touched) which I don't want. I want that only onClick event of button should be clicked not dispatch event.
Here is my XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<!-- include title bar for all screen -->
<include
android:id="#+id/include1"
layout="#layout/titlebar_layout"
android:layout_gravity="top" />
<FrameLayout
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.88"
>
<com.google.android.maps.MapView
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.63"
android:apiKey="0VkXbAOFvAq7b6uaGHSmnS2a2VosPxoS6ceHY_g"
android:clickable="true" >
</com.google.android.maps.MapView>
</FrameLayout>
<include
android:id="#+id/include2"
android:layout_gravity="bottom"
android:layout_marginBottom="38dp"
layout="#layout/bottom_layout" />
</LinearLayout>
Any help will be greatly appreciated.

You can override the dispatchTouchEvent, and check where the user has touched the screen..
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
//first check if the location button should handle the touch event
if(locBtn != null) {
int[] pos = new int[2];
locBtn.getLocationOnScreen(pos);
if(ev.getY() <= (pos[1] + locBtn.getHeight()) && ev.getX() > pos[0]) //location button event
return locBtn.onTouchEvent(ev);
}
return super.dispatchTouchEvent(ev);
}

The reason why MapView is receiving the dispatchTouchEvent() events is that Android starts dispacthing the the events for the last added view, and if it's not handled there, then it's dispatched to the last the view added before that one, and so on ...
In you xml layout, you first add Header, then MapView and for last Footer. So in your case, the the events are first dispatched to Footer, then to MapView, and for last to the Header.
You have to option to solve this:
The simplest is to reorder the items in your layout, starting with mapview and then adding all the others. You may need to use relative layout to be able to position them correctly. With this MapView will not see events that are handle by the button.
Keep your layout and let MapView receive the events. MapView will need to test if event should be handled by him or ignored. For that you can use the code sugested by #Nunu, which should work. Maybe you need to add to the button Y coordinate the button height.
good luck.

Use relative layout with Map View at bottom and Button to clicked at top.. and add click event for the button

use view.bringToFront() to get the view places above other views.

Related

How to set canvas (paint view) on top of listview and still have listview clickable?

I have a layout that contains a ListView and a few buttons in a RelativeLayout. I am trying to let the user draw on the page using a custom paint view layout. The good news is that I've got nearly everything working and looking how it should, however the last and most frustrating issue is that the ListView is no longer clickable at all. I would like to paint on top of the the ListView AND make it clickable.
The funny part is that the buttons on the page are still clickable, just the items in the ListView are not. I think what is happening is that the ListView is loaded by an adapter and gets loaded first (thus behind everything). What do I need to do in order to make the ListView clickable?
I've tried adding android:focusableInTouchMode="true" android:focusable="true" but it made no difference.
My layout is as follows:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
android:orientation="vertical" >
<ListView android:id="#+id/lv"
android:layout_height="match_parent"
android:layout_width="match_parent"
></ListView>
<com.my.app.PaintView
android:id="#+id/paintView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
Buttons Here.../>
</RelativeLayout>
The focusable attribute should be false for the element you do not want to receive touch events. To overlay your PaintView without having it intercept touch events, you can add a few XML attributes to it:
<com.my.app.PaintView
...
android:focusable="false"
android:clickable="false" />
As long as you don't set an OnClickListener or an OnTouchListener to your PaintView, touch events should simply pass through it to the Views behind it.
Managed to find a solution that works perfectly (at least for me). I imagine without the listview this would have been far easier, but I wanted the listview to work as well as drawing on the canvas. All I ended up having to do was set an onTouchListener in the main activity that had the ListView, then send it to the PaintView with the MotionEvent. Simple and it works perfectly:
listview.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
paintView.onTouchEvent(motionEvent);
return false;
}
});
In this example, the paintView.onTouchEvent could really be any method in the custom view, just kept it at "onTouchEvent" for simplicity.

Android: Passing touch event to overlapped view

I have a Relative layout which has two child layouts. First child is linear layout which is container of a fragment. The fragment has few buttons. The second child is a linear layout which has a View which is blank and transparent. The second child overlaps the first child.The first child is smaller than second child. I want to send touch events from second child to first child so that those buttons on the fragment which first child contains receives click.
I read few posts on internet for solving my problem but could not solve it.
So far i have overriden dispatchTouchEvent of Activity and have tried to detect whether touch is in bounds of first child and if so i do firstChild.onTouch(ev). Actually i just dont know what to do and just trying get it working. So please, help me.
#Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
float x,y,backViewX,backViewY,frontViewX,frontViewY;
x = ev.getX();
y = ev.getY();
frontViewX = frontView.getX();
frontViewY = frontView.getY();
backViewX = backView.getX();
backViewY = backView.getY();
if(y >= backViewY && y <= (backViewY+backViewHeight))
{
if(x >= backViewX && x<=(backViewX+backViewWidth))
{
return backView.onTouchEvent(ev);
}
}
return super.dispatchTouchEvent(ev);
}
Orignal Layout is not the exact as i described but it is little more complex but the concept is same as i described....i am shortning the layout for simplifying things.The frontLayout here overlaps layoutBackFragmentArea.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/back_view_background">
<LinearLayout
android:id="#+id/layoutBackFragmentArea"
android:layout_width="match_parent"
android:layout_height="#dimen/back_view_height"
android:orientation="vertical"
android:gravity="center_vertical"
android:background="#android:color/transparent">
</LinearLayout>
<LinearLayout
android:id="#+id/layoutFrontArea"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_vertical"
android:background="#android:color/transparent">
<View
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</RelativeLayout>
layoutBackFragmentArea will contain a fragment which has UI which should receive click events.

How to disable click listener of button if there is overlay

I am using frame layout and linear layout overlay, when click on overlay so button click listener is also invoked, kindly let me know how to handle this.
<LinearLayout
android:id="#+id/logLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/transparentBlack"
android:orientation="vertical" >
<com.valspals.classes.ButtonStyleM700
android:id="#+id/logDone"
android:layout_width="325dp"
android:layout_height="35dp"
android:layout_gravity="center"
android:layout_marginTop="25sp"
android:background="#drawable/btn_confirm_normal"
android:text="#string/iamdone"
android:textColor="#color/White"
android:textSize="#dimen/normalTextSize" />
<com.valspals.classes.ButtonStyleM700
android:id="#+id/woops"
android:layout_width="325dp"
android:layout_height="35dp"
android:layout_gravity="center"
android:layout_marginTop="15sp"
android:layout_marginBottom="25dp"
android:background="#drawable/btn_confirm_normal"
android:text="#string/woops"
android:textColor="#color/White"
android:textSize="#dimen/normalTextSize" />
</LinearLayout>
above this there is frame layout, basically its a parent layout. behind this layout i have two buttons and problem is that they are click able from this linear layout overlay
There are several options you could use for this. The easiest would be setting a global variable and checking it when onClick is called.
i.e. you have a boolean overlayShowing = false;
In your event listener, just check for !overlayShowing
However, that will still allow the button's click animation to show. If you want to prevent that as well, you could intercept the touch events on the top layout (your FrameLayout) and prevent them from being passed to the below layouts if the overlay is visible.
e.g. In your overridden FrameLayout:
#Override
public boolean onInterceptTouchEvent(MotionEvent e){
return overlayShowing;
}
This will intercept the touch event and prevent it from passing it on the chain when the overlay is showing.
If your overlay is only shown by toggling the View's visibility, you could simplify that even further by checking the FrameLayout's visibility in the onInterceptTouchEvent() method. e.g.
#Override
public boolean onInterceptTouchEvent(MotionEvent e){
return getVisibility() == View.VISIBLE;
}

Possible to make a View not touchable just like a Window in android?

A window can be set to not touchable, which means that you can click anything behind that activity just by setting the whole window to not touchable with the following code:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
Now my question is: Is it possible to make only the RelativeLayout NOT TOUCHABLE, I mean the user is able to touch anything behind that RelativeLayout, but he will not be able to touch anything behind the Button in that RelativeLayout.
This is my xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/rl"
style="#android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="44dp"
android:text="Button" />
</RelativeLayout>
I need the relativelayout to be NOT TOUCHABLE, the user can touch anything behind it.
I only need the button in the relativelayout to be touchable
Hence, Button touchable, RelativeLayout Not Touchable.
I can touch the button, but I can't touch the RelativeLayout I only touch things behind it.
When using
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
The whole window is being set to not touchable with the Button as well, which is not what I want.
I hope my question is understandable.
EDIT:
All i'm trying to do is Displaying a single button on another application (Skype, for example)
I only want that button to be clickable with Skype app together.
Try adding android:duplicateParentState="true" to your RelativeLayout this will propagate the events down the view tree.
If that does not work, try overriding this method.
http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)
In your java code write like this
ArrayList<View> touchables;
RelativeLayout RelativeLayout_ = (RelativeLayout) findViewById(R.id. rl);
touchables = RelativeLayout_.getTouchables();
for (View touchable : touchables)
{
if (!(touchable.getId()==R.id.button1))
{
touchable.setEnabled(false);
}
}
Hope it will work

How to place a pushpin on MapView that does not move with the map?

How to place a pushpin in middle of the MapView so that we can move navigate the a location to that pushpin to select that location.
There are many approaches you can implement to achieve this.
You can add MapView and push pin(image view) to relative layout, and set property of push pin center in parent, on click on push pin calculate mid-point of map, and work accordingly.
Calculate MapView's center point, and add overlay on that point. Override on touch event, and onKeyUp event, recalculate mid point, and redraw overlay.
To expand on jeet's Jan 30th answer, here's some layout xml to do the first method - which I believe is easier and will look better and move smoother than the 2nd suggestion.
Pretty simple, but maybe would save someone a few mins:
<RelativeLayout ...>
<com.google.android.maps.MapView
android:layout_width="match_parent"
android:layout_height="match_parent"
... />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/map_location_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/map_location_pin" />
</RelativeLayout>
</RelativeLayout>

Categories

Resources