OnOverListener doesn't work - android

I'm trying to use the new event onHover. I look the sample, the documentation...and nothing works. The onHover event should be done by a mouse pointer.
I create a simple xml file containing 1 LinearLayout and 2 buttons inside.
My java code is following
findViewById(R.id.linearLayout1).setOnHoverListener(new OnHoverListener() {
#Override
public boolean onHover(View v, MotionEvent event) {
Log.e("tag", "tag");
return false;
}
});
LinearLayout1 is my linearlayout containing button. onHover is never called.
I tried a lot of stuff without success.
Let me know if you have an idea.

In a View that contains sub views, the subViews callbacks get called first.
if you have a button in your LinearLayout, all events are being called on the button and all the other views first, and only if all the sub views return false, only then, the event will be called on the parent view.
you should return false from all other subviews first before activating the onHover

Related

How does one disable/ re-enable touch events in Android?

Quick, probably simple, question. I have a view whose background is animating, and during that time, I want to disable the user from interacting with the view. My view is a FrameLayout, and I'm capturing touch events with onTouchEvent(). Solutions I've tried:
1) First setOnTouchListener(null), then setOnTouchListener(this). Problem is, my view only calls onTouchEvent(MotionEvent), and not onTouch(View, MotionEvent), so I can't pump through the Events there.
2) First setEnabled(false), then setEnabled(true). The source code says: A disabled view that is clickable still consumes the touch events, it just doesn't respond to them. Problem is, MotionEvents still get pumped through in onTouchEvent().
3) requestDisallowInterceptTouchEvent(false), then (true). This only handles touch events from the parent.
The solution I have working is using a boolean variable isAnimating, and checking the value of that in onTouchEvent(). I'd rather not do this, because it looks ugly to me and I'd rather use the API for it than reinvent the wheel, sooo... anyone got any ideas? Thanks.
Try:
setFocusable() and setFocusableInTouchMode()
Try:
#Override
public boolean onTouchEvent(MotionEvent event) {
//Check if event is on your view
if(event.getY()>view.getTop()&&event.getY()<view.getBottom()&&event.getX()>view.getLeft()&&event.getX()<view.getRight()){
//event occured inside your view
}
//here return super or as your logic prefer
return super.onTouchEvent(event);
}

onTouchEvent for whole app, without an activity

I am developing an android app which tracks touch events for the whole application. For that purpose, I want to override onTouchEvent() without an activity; i.e., inside a simple Java class, I don't whether it's possible. Any ideas are welcome.
No, you cannot arbitrarily override onTouchEvent, particularly in a "simple Java class", i.e. one that does not extend a View.
Solution 1
If you want to capture all touches to your app, override onInterceptTouchEvent() in your main layout. So, if your main layout is a LinearLayout, do something like:
public class MyTouchLayout extends LinearLayout {
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Do whatever with your touch event
return false; // Do not prevent the rest of the layout from being touched
}
}
Then, in your XML, you'd use:
<com.example.MyTouchLayout
...
>
<!-- The rest of your layout -->
</com.example.MyTouchLayout>
Solution 2
This is by far the simpler solution, though I've had varying luck with it in the past and would never suggest that you reply upon it.
You can simply get the View that contains all your content (the root View, a LinearLayout above), then give it a listener.
View v = findViewById(android.R.id.content); // Find the root View; you may have to give it your own ID in the XML, and use that
v.setOnTouchListener(new OnTouchListener {
// ...
}

How to process all TouchEvents at the ViewGroup level (ie Bubble all events up to containing viewgroup)

I would like to process all touch events at the container level. In other words, I want all touch events to reach the container level. Right now I am finding that TouchEvents only reach the containing ViewGroup if the location of the touch does not land on a UI Component that is contained by the view group. The contained UI Element processes the TouchEvent and it does not bubble up to the container. Does anyone know how to guarantee that all touch events reach the top level container?
Just to be clear, picture an activity with several buttons, several edit texts, and several check boxes. A typical form. Normally I am seeing that each UI component will catch the TouchEvent that lands on it and the container is none the wiser. So I want to know how the container/viewgroup could be informed of all touches that land anywhere within its region whether or not that region is occupied with a button, empty space or an edit text.
This is how I interpret your question:
You have View tree like this
ViewGroup G
View A
View B
...
and you want G to handle the MotionEvent created on touch even if it was consumed by any of A, B, ...
How to:
I'll give you two options. Depending on if you want to ignore consumption by
every child
only selected children
use one of the following templates:
Override dispatchTouchEvent() in G
// In G
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
super.dispatchTouchEvent(event);
// Handle event here instead of using an OnTouchListener
return true;
}
Override dispatchTouchEvent() in every child whose consumption should be ignored
Ignore some children
// In every child whose consumption should be ignored
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
super.dispatchTouchEvent(ev);
return false; // false means "I did not consume the event"
}
Don't forget to setup your listener
// In G, before touch should be recognized
setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// Handle event here
return true; // true means "I did consume the event"
}
});
Measured in lines of code, option 1 is a lot simpler. Option 2 is there just in case you need special treatment for some of A, B ...
I know it is late, but I think future readers might want to look at ViewGroups.onInterceptTouchEvent().

Android GridView setting certain item to nonClickable

I'm implementing a custom calendar using a GridView.
For this Calendar I have 3 view types, {DAY, TITLE, BLANK}
Is there a way to make certain items in a GridView not clickable?
What I'm trying to avoid is the press state animations for the items that aren't clickable. It ok it the user presses them, I can recognize that it's not the valid view in my onItemClickListener(). This is purely for UI purposes.
I found the solution. Don't know why I didn't search for ListViews in the first place.
You need to override the isEnabled() Function
Returning false will make it non-clickable. True will keep is clickable.
#Override
public boolean isEnabled(int position) {
switch(getItemViewType(position)) {
case CellTypes.BLANK:
case CellTypes.TITLE:
default :
return false;
case CellTypes.DAY:
return true;
}
}
In the adapter for your GridView, implement one of the get() method to return a reference to the object being clicked. I'm assuming that your adapter wraps a list of your "Calendar" objects.
In the onItemClickListener for your GridView, call get(index) or get(id) on the adapter to get a reference to the object being clicked. Check its type to see if it is one that you do not wish to be clickable, and return before executing the logic that is usually called when a clickable item is clicked.
In XML: android:clickable="false" and in code: setClickable(false);

apply general onkeylistener

New to programming, now to android. So I hope I dont annoy you to much.
How would I go about setting an onkeylistener at the top level of the app that captured the keyevent no matter what.
Basically what i have is a linear layout with dynamically added edittexts.
I want to capture the Enter key event and have it get the current edittext, perform some tests then create a new edittext and add it to the layout.
I know I can (and have) implement an onkeylistener to individual child views, but not being a programmer, the logic seems weird to create an edittext that listens for input to create another edittext that listens for input to create another.... (you see where this goes)
Can anyone point me in the right direction?
I have lots more info about what Im trying to do, I just dont know what is pertinent and what is not, so let me know if you need more.
Thanks for your time in advance,
Chris
Take a look at http://developer.android.com/reference/android/app/Activity.html#dispatchKeyEvent%28android.view.KeyEvent%29
What you want is to intercept all the events before they are processed by any View in the window. Return true if the event was handled or false if you want the childs to process the event further.
Like Ben said your activity can implement OnKeyListener then for each EditText you create, set the OnKeyListener to be the activity.
editText1.setOnKeyListener(this);
And then in your implementation of onKey you can handle the key press event.
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(v == editText1) {
// do something
} else if( v == editText2 ) {
// do something
}
return true; // return true if you handled the keypress
}
Your activity can implement OnKeyListener.

Categories

Resources