i create a system overlay app using this way
but i have a problem .... when i move my button to corner of screen, i can't touch system's view like Call button in the following image
image
how can i disable any touch in my button ? ( ignore my view's touch and touch system's view )
in somewhere i find this code but it isn't work
bl.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
Always visit developer.android.com first, it's really well documented with fundamental concepts.
The onTouch method will pass the event to the layer below it, if it returns false.
If you've extended a default touchable View class, you should use return super.onTouch()
Here's the link you're looking for:
https://developer.android.com/reference/android/view/View.OnTouchListener.html
Related
I had an edit text which I wanted to make scrollable. The problem was that this edit text is located inside a scrollable view.
I searched the internet and found a solution that works fine. Source:How to scroll the edittext inside the scrollview
youredittext.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (youredittext.hasFocus()) {
v.getParent().requestDisallowInterceptTouchEvent(true);
switch (event.getAction() & MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_SCROLL:
v.getParent().requestDisallowInterceptTouchEvent(false);
return true;
}
}
return false;
}
});
The problem is after applying this solution the edit text would only scroll without a "velocity vector." So like you have to hold down your thumb and move it but the moment you remove your thumb it stops scrolling immediately.
While for example, the android scroll view has a velocity vector in which you scroll up fast then you remove your thumb, it would keep scrolling with decreasing speed. Similar to scrolling on Facebook and Instagram.
Any help is appreciated and thanks!
I have created some activity which is transparent when some different app opens my activity starts and opens on top of that activity (Intent.FLAG_ACTIVITY_NEW_TASK).
What i am trying to achieve is what action happens on my activity will reflect to other activity.I mean when i scroll down underlaying view will scroll.
I could NOT do that i have used some flags combinations but it did not work.
I could not pass touch events both activities at the same time. It just works at one view, i need to do what happens on top (transparent) activity , underlaying activity has get to same events.
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
// window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.addFlags(WindowManager.LayoutParams.FLAG_SPLIT_TOUCH);
// window.addFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
//window.addFlags(WindowManager.LayoutParams.TYPE_PHONE);
setContentView(R.layout.trans);
final View v = getWindow().getDecorView().findViewById(android.R.id.content);
v.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
Log.i("TAG", View !!!!!!!!");
return false;
}
});
This is not possible. You can neither inject input events to other apps' Activities nor can you receive their input events (known as tapjacking).
You cannot do that with touch events, I am also not sure why would you want to do so.
That said, you can use local broadcasts or EventBus but it is a really bad idea, catch touch events in one Activity and pass to the other one after that.
I am working on a simple converter between Decimal/Hex/Binary and have run into an issue I can't seem to solve. This is the layout I am more or less aiming for.
What I am here is when one of the buttons is pressed, it stays pressed to indicate which conversion you are currently working with. Now I have looked everywhere and it doesn't seem there is a good way of doing this, or I haven't found it at least.
What would be the best way to go about this? is there someway to just use buttons and have them stay in their "pressed" state when they are clicked? By this I only need the color of the pressed button to show. Or is there a way of doing this with some type of radio group, where the radio buttons have the same style as a regular button?
Try:
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
... do a call to your conversion code here ....
button.setPressed(true);
return true;
}
});
For more info: Android docs and this SO question
I'm very new to Android programming, and trying to understand touch events with nested views. To start, here's a description of my app:
I have a relative layout that I've added via the GUI editor. Everything is default. I've also created a class called ClipGrid that extends ScrollView. Nested inside that, I make a HorizontalScrollView. Inside of that, I make a TableLayout and it's rows. The rows contain buttons.
The end result is a grid of buttons. It displays 4x4 at once, but can scroll either direction to display other buttons.
I call it to the screen from my main activity like this:
ClipGrid clip_grid = new ClipGrid(this);
setContentView(clip_grid);
I did that just for testing purposes, and I think I will have to change it later when I want to add other views to my relativelayout. But I think it might have implications for touch events.
in the end, I want to detect when the grid has been moved and snap the newly viewable 4x4 grid of buttons to the edge of my layout when the user lifts their finger. I'm just not sure how to go about implementing this and any help would be appreciated. Thanks.
The way touch events are handled is kind of a cascading effect that starts from the top view and goes down to the lower nested views. Basically, Android will pass the event to each view until true is returned.
The general way you could implement the onTouchEvent event of a View would be:
#Override
public boolean onTouchEvent(MotionEvent event) {
boolean actionHandled = false;
final int action = event.getAction();
switch(action & MotionEventCompat.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// user first touches view with pointer
break;
case MotionEvent.ACTION_MOVE:
// user is still touching view and moving pointer around
break;
case MotionEvent.ACTION_UP:
// user lifts pointer
break;
}
// if the action was not handled by this touch, send it to other views
if (!actionHandled)
actionHandled |= super.onTouch(v, MotionEvent.event);
return actionHandled;
}
Imagine a layout with 4 buttons
_______________________________
| | |
| A | B |
|______________|________________|
| | |
| C | D |
|______________|________________|
I'd like to detect the fling gesture over the whole layout but when the fling starts over a button is no detected.
I'm using:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gesturedetector= new GestureDetector(this, this);
findViewById(R.id.touchContainer).setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("","TouchEvent");
return gesturedetector.onTouchEvent(event);
}
});
}
It when there is no clickable items but fails if the fling start over a clickable item.
How can I solve that? Offering a bounty of 50 point for a complete working answer
One way I have achieved this is to override the following method:
public boolean onInterceptTouchEvent(MotionEvent event){
super.onInterceptTouchEvent(event);
...
You can override this method in your layout container (e.g. ViewGroup, or whatever you're holding the buttons with) and continue to return false from it in order to 'intercept' touch events that are being consumed by child Views (i.e. your buttons). Within that overridden method you can then call your gesture detector object with the MotionEvents. This method also 'sees' events that target the ViewGroup itself as well, which means - if I remember correctly - you would only need to call your gesture detector from within that method, and in doing so the gesture detector will 'see' all events, no matter whether they'er over the buttons or not. So if you drag your finger starting over a button and then ending at some point on the layout background, the gesture detector should see the entire swipe. You would not need to feed the gesture detector with the events from the layout's own onTouchEvent() because it'll have already seen them.
A second way:
I just looked at my project where I used this, and realised that I switched to a different way of doing it. What I actually did was I designed all of my child Views such that the parent Activity (or the containing ViewGroup) could register the same gesture detector object with all of those child Views (each of my special Views have a method called registerGestureDetector()). Then, in the overridden 'onTouchEvent()' in my child Views, I pass the MotionEvents to the gesture detector that has been registered with that View. In other words, the parent ViewGroup layout and all the child Views simply share the same gesture detector.
I realise that this may sound like a bit of hassle and not necessary considering it could be done using onInterceptTouchEvent(), but my application deals with some pretty complicated rules regarding how my Views need to respond to touch events and gestures, and it allowed me to apply some additional logic that I needed specific for my application. However, both of these methods I've used achieve the same basic objective here: to channel the MotionEvents that targetted various Views to the same gesture detector object.