give multitouch to view A, and A is behind to B View - android

I have two view A and B
A is MATCH_PARENET (width, height) and B is also MATCH_PARENT (width, height)
A view is covered by B View and B view is INVISIBLE
I have given Multitouch listener to A, but because of A is covered by B, I can not touch to A view because on top of A there is INVISIBLE, B view
Can any one help me how to do zoom-in out, rotate and move to view A
I have done by one way but it is not properly working
multiTouchListener = new MultiTouchListener();
a.setOnTouchListener(multiTouchListener);
b.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
multiTouchListener.onTouch(a, event);
return true;
}
});
I have given b's touch event to a,
but right now a is constantly moving if I simple drag my finger and stop

prevent B from getting touches, add these lines to the xml properties of B:
<View
...
android:focusable="false",
android:focusableInTouchMode="false",
android:clickable="false" />
make sure you do not add any click/touch listeners in code to B, as it'll revert those properties.

Related

"Nephew" views block pinch gesture

I have a hierachy of custom views build as following:
Custom View A has a few View B's as children
Custom View B is like a button and needs to react to click/tap
Custom View C has a pinch gesture on it and is a sibling of A, and is under A in the view hierarchy
When pinching only on the Custom View A, everything goes well, as A does not catch any motion event and the view under it, C, receives the events and makes the pinch gesture (zoom in/out) correctly.
When tapping the Custom View B, the view is clicked and it is all good.
The issue is, when trying to pinch and one finger starts on View B, it catches its events and those are not propagated under it and no pinching ever happens on the Custom View C.
I would like to have View B react to tap only and pass all other events (pinch) to the view underneath itself, in this case Custom View C.
How can I achieve that scenario?
Found the solution!
We try to find a TapConfirmed event (using a gestureDetector to find it), and we dispatch the event directly to the sibling to pass the event:
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (conditionToIntercept) {
return true;
}
return false;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(conditionToIntercept{
if (!gestureDetectorCompat.onTouchEvent(event)) {
siblingView.dispatchTouchEvent(event);
return true;
}
}
return false;
}

How to detect touch when you are moving over a button

I have created a button at the center of the layout with width 50dp.If I touch the screen at left extreme side of the layout(where the is no button) and hold down (Keep pressing ) till I reach the button in center then it should detect the touch .How can I do that .I have tried both onCLicklistener() and onTouchListener() but I still cannot detect the touch .
Basically like gesture but I thought button had a way of detecting that.
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// Toast text : entered within button
return false;
}
}))
If we set Click or Touch listener to Button which is 50dp width at center, then the listener will get callback only if the user click/touch initiating from button.
While in your problem case, You are initiating click/touch from outside and coming to button.
So, button listener will not get callback from Android Framework
For your requirement to work, we need to add some logic, i have tried to add it here :
activity_main.xml :
<RelativeLayout android:id="#+id/parentLayout" ... >
<Button android:id="#+id/buttonCenter ... />
</RelativeLayout>
MainActivity.java :
// apply touch listener to parentLayout
button = (Button) findViewById(R.id.buttonCenter);
parent = (RelativeLayout) findViewById(R.id.parentLayout);
parent.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("tag","in onTouch...");
checkTouch(event);
return true;
}
});
// check if touch entered button area
// save button left, right, top and bottom edge
// update : This is API i found on google documentation
float[] params;
button.getLocationOnScreen(params);
public void checkTouch(MotionEvent event) {
x = event.getX();
y = event.getY();
if(x >= param[0] && x <= (param[0]+button.getWidth())) {
if(y >= param[1] && y <= (param[1]+button.getHeight())) {
Log.d("tag","this touch is in button area");
// do what you want to do when touch/click comes in button area
}
}
}
Actually when you place a touch MotionEvent.ACTION_DOWN event is dispatched on the view which you touch and as you move MotionEvent.ACTION_MOVE events will be dispatched for every pixel point moved and until you release viz. until MotionEvent.ACTION_UP event is dispatched on that same view the events will not be handed over to any other view.
That is why it is not detecting on the button since it is actually the event of its parent view. So write an ontouchlistener on the parent and in that handle the touch according to the event.getRawX() & event.getRawY() positions in pixels.

Android pass OnClick Event to underlying View in FrameLayout

Idea: I want to display an image as background. On this image, somewhere on the screen there is a little clickable View. On top of this all, a black draggabke image with a little transparent whole (displaying the underlying Views).
This is solved with a FrameLayout, whereas the image is the first frame, the View is the second frame and the ''Viewport'' is the third frame.
Now the goal is, that the user can click that second frame, if it is visible in the viewport. The problem is, that this transparency is only ''in the png'', not in the frame itself. So the solution would be to propagate the OnClick coordinates to the underlying frame. How is this possible? Is there a functionality for a FrameLayout in such cases?
Making the upper layer as clickable false, i think the click event should be ignored by it and passed to the second frame
Create a custom class that extends FrameLayout
Add the following overridden methods
#Override public boolean onTouchEvent(MotionEvent event) {
return false;
}
#Override public boolean onInterceptTouchEvent(MotionEvent event) {
return true;
}
Then add touch listener to frame layout like
framelayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
underLyingView.onTouchEvent(motionEvent);
return false;
}
});
This will pass onclick event to the view underLyingView which lies under FrameLayout

android touch event

I have two views, view A and B.
When I trigger the touch event "move" on view A, View B will show and overlay on the View A. At the same time, I want View B can receive the same touch event "move" from View A. Is it possible to send the same touch event to View B from system?
Yes, you can call the onTouchEvent() method of viewB and pass it the MotionEvent that was given to viewA Like this:
viewA.setOnTouchListener(new OnTouchListener() {
#Override
public onTouch(View v, MotionEvent me){
viewB.onTouchEvent(me);
}
});
That should pass all of the events that come to viewA on to viewB.

keep ontouch event when view is removed and add

I have a view in a linearlayout. When the view is longpressed the view will be removed from this linearlayout and placed, on the same position of the screen, to a relative layout. On this way a can move the view over the screen with my finger.
it almost works:
i got the longpress event working (remove the view and place the view to the relativelayout). after that i add an ontoucheventlistener so my view stays with my finger, but only for a second. the last time the touchevent is fired i got "MotionEvent.ACTION_CANCEL". When i remove my finger and place my finger again to the view i can go feature with my movement, then it will keep until i remove my finger.
I think that my problem is that the view it removed for a short moment, at that time i get a "MotionEvent.ACTION_CANCEL", however, there are still some unhandled events, they will be fired first. Thats why i got for about 1 second still ontouchevents. (this is just a thought).
someone a idee how i can keep the ontouchevent, or let the ontouchevent fired without replacing my finger?
Edited
My thought is not correct. When i do a longpress the view stays with my finger, however i lost the view as soon as i move about 50 to 100 pixels to any direction.
Edited 2
the longpress code of the view inside the linearlayout
view.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View v) {
_linearLayout.removeView(v);
moveView(v);
return true;
}
});
moveView will be called by the longpress
private void moveView(View v) {
_relativeLayout.addView(v);
v.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_MOVE:
int x = (int) event.getRawX();
int y = (int) event.getRawY();
v.layout(x, y, x + v.getWidth(), y + v.getHeight());
break;
case MotionEvent.ACTION_UP:
_relativeLayout.removeView(v);
v = null;
break;
case MotionEvent.ACTION_CANCEL:
//it comes here when i move my finger more then 100 pixels
break;
}
return true;
}
});
}
of corse, this is the relevant part of the code and not the original code
Have a look at the Experience - Android Drag and Drop List post. There is also a source code that does something very similar to what are you trying to get. Eric, the author of that post, uses a separate temporary ImageView to hold a dragged view image, taken with getDrawingCache(). He also hides the original list item by setVisibility(View.INVISIBLE).
In the DragNDrop project (link above) you can replace drag(0,y) calls by drag(x,y) in DragNDrop.java to see a dragging in all directions.
Just throwing some possibilities in because I can't see the code but MotionEvent.ACTION_CANCEL could be being called as the parent layout is switched and the view is getting redrawn.
You could try overriding the onTouchEvent and at the point the ACTION_CANCEL event is sent try get hold of an equivalent view in the new layout and operate on that but I still think the better idea is to redesign so it all takes place in the same layout.

Categories

Resources