I am using cover flow in my project and while display of cover flow on button click i am showing popup.
(Coverflow in android is the style to display images in line which is scrolled on touch as we generally see in media player and can be selected ;It's based on the Android Gallery widget and is used in the same way, with a ViewAdapter. My main aim when coding this coverflow widget was to create an easily re-usable component using the standard Android 2D libraries
reference :- http://www.inter-fuser.com/2010/01/android-coverflow-widget.html)
s
- now when popup is displayed i don't want my coverflow to
scroll/navigate on touch i.e i want to disable coverflow untill popup
is displayed
i have already tried all the code below but it is not help full to
disable coverflow.
coverFlow.clearFocus();
Popup.setFocusable(true);
coverFlow.setClickable(false);
coverFlow.setFocusable(false);
coverFlow.setEnabled(false);
coverFlow.setSelected(false);
can any one help me out in this matter ?
I don't know what source code of CoverFlow you are using. But you can custom it.
Extend the CoverFlow (which already extends Gallery, i think), override the onTouchEvent and onInterceptTouchEvent methods with return false if you don't want the CoverFlow scroll, and add the method to set this attribute.
The code maybe looks like :
#Override
public boolean onTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onTouchEvent(event);
}
return false;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onInterceptTouchEvent(event);
}
return false;
}
public void setScrollEnabled(boolean enabled) {
this.enabled = enabled;
}
And then you can set the CoverFlow scroll or not by using setScrollEnabled method
Related
I am trying to implement UI like google keep.
In the main layout there is frame layout in which there is a FAM(Floating Actions Menu) and a blackshadow view which is visible when FAM is expanded.
What i want is that when i touch the shadow view it should Collapse the FAM. To do that i have implemented onTouchlistner on shadowview.
shadowview.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(fam.isExpanded()){
fam.collapse();
}
return false;
}
});
But what happens is that when i touch the area with MyCardGridView's card (Which open's another activity) open's another activity. Which should not happen.
You should try to use return true; instead of return false;, because as the documentation says :
Returns:
True if the listener has consumed the event, false otherwise.
Maybe the issue here is caused by return false
I have a ListView. Inside the cells, I have a custom view. (You can draw in it.)
When drawing, I turn off scrolling of the list ..
theListView.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_MOVE)
{
if ( STATE.weAreDrawoning )
{
return true;
// so, do not forward and hence do not scroll the list
}
else
{
return false;
}
}
return false;
}
});
That's fine. But strangely, up-down touching in the custom View, is still passed on to the list and makes it scroll.
public class AmazingCustomView extends View
{
blah
#Override
public boolean onTouchEvent(MotionEvent event)
{
blah
return true;
}
}
notice in the custom view onTouchEvent is returning true (I also tried false! :) )
but the motion events appear to be still passed on .. what gives??
Is there another "on .. something" I'm missing in the custom view? Sorry, new to Android and lame. Thanks!
PS, I tried turning on "clickable" on the xml of the custom view, didn't help :O
--
Worse ...
I've just realised ALL controls in the ListView, say buttons, still "pass on scrolling"
I fear the system I use above for turning off scrolling is just no good. :/
important...
For anyone googling to here. The only real way I've found to turn off scrolling on an android listView ...
danosipov.com/?p=604
(don't forget to separately turn off your pull-to-refresh)
You may need to override onInterceptTouchEvent. Its an odd function, documentation here: http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent%28android.view.MotionEvent%29
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
I call
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
when my app starts to make my app able to display the full screen.
I want my app's UI to pop up when screen is touched, but Activity.onTouchEvent() is not triggered until the screen is touched a second time. At first touch, only the Virtual Keys are shown.
So, I have to trigger my app's UI to pop up on
public void onSystemUiVisibilityChange(int visibility) {
if (visibility == View.SYSTEM_UI_FLAG_VISIBLE) {
// show my APP UI
}
}
but onSystemUiVisibilityChange with View.SYSTEM_UI_FLAG_VISIBLE will be invoked NOT once per touch (3 times on my Galaxy Nexus) by system, especially if the user touches the screen very fast/often.
project lib 4.0 or 4.03.
Samsung galaxy(9250) with 4.03.
Android 4.4 (API Level 19) introduces a new SYSTEM_UI_FLAG_IMMERSIVE flag for setSystemUiVisibility() that lets your app go truly "full screen." This flag, when combined with the SYSTEM_UI_FLAG_HIDE_NAVIGATION and SYSTEM_UI_FLAG_FULLSCREEN flags, hides the navigation and status bars and lets your app capture all touch events on the screen.
This did work for me:
setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
// show my app UI
}
}
});
What I've done is first imported android.view.GestureDetector so I can use it to detect gestures. Android has a number of default gestures that are automatically detected in the GestureDector class. Most of this info is found here, but below is code in a form that I've used in an actual project that works.
First I've made an anonymous class in my Activity (this can be nested wherever, but I tend to make my anonymous classes at the bottom, right before the closing bracket). NOTE: You can also implement OnGestureListener as part of your class, also.
The code below is for using gesture detection to give a simple hide/show.
I've declared and defined my action bar (my UI, which is initially hidden) as an instance variable, so I can access it here, and wherever else, but you can substitute it for a getActionBar().show() and getActionBar().hide() in the case you don't want to declare it as an instance variable. Substitute your UI in the place of the actionBar here:
public class Example extends ActionBarActivity {
// declared in onCreate() method
private android.support.v7.app.ActionBar actionBar;
private GestureDetectorCompat mDetector;
private YourView view1;
private YourView view2;
private YourView view3;
private YourView view4;
// some other code
class GestureListener extends GestureDetector.SimpleOnGestureListener {
private static final String DEBUG_TAG = "Gestures in Example Class";
#Override
public boolean onDoubleTap(MotionEvent event) {
Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());
// if there is a double tap, show the action bar
actionBar.show();
return true;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent event) {
Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());
// if the tap is below the action bar, hide the action bar
if (event.getRawY() > getResources().getDimension(R.dimen.abc_action_bar_default_height)) {
actionBar.hide();
return true;
}
return false;
}
#Override
public boolean onDown(MotionEvent event) {
return true;
}
} // end-of-Example Class
Then in my onCreate() I've declared my GestureDetector and also (optionally) set my GestureListeners:
private GestureDetectorCompat mDetector;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// some code here
mDetector = new GestureDetectorCompat(this, new GestureListener());
// this code is for more advanced view logic not needed for a basic set-up
//setGestureListeners();
} // end-of-method onCreate()
Then in order to actually send gestures to be processed we provide the instructions for doing that, there are two ways I know about, first the simplest:
/**
* This method recognizes a touchEvent and passes it to your custom GestureListener
* class.
*/
#Override
public boolean onTouchEvent(MotionEvent event){
this.mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
The second way is more complex, but if you want to only recognize touch events on certain Views in your layout as in the case where you have overlapping views and can only access the top View, you can create a custom class to pass the event around or up:
class MyOnTouchListener implements View.OnTouchListener {
public boolean onTouch(View v, MotionEvent event) {
if (v.equals(view4)) {
return mDetector.onTouchEvent(event);
} else return false;
}
} // end-of-class MyOnTouchListener
and then use it here:
public void setGestureListeners() {
/* when we return false for any of these onTouch methods
* it means that the the touchEvent is passed onto the next View.
* The order in which touchEvents are sent to are in the order they
* are declared.
*/
view1.setOnTouchListener(new MyOnTouchListener());
view2.setOnTouchListener(new MyOnTouchListener());
view3.setOnTouchListener(new MyOnTouchListener());
view4.setOnTouchListener(new MyOnTouchListener());
} // end-of-method setGestureListeners()
In my setGestureListeners method, I gave them all the same set of commands, that essentially only recognizes touchEvents on view4. Otherwise, it just passes the touchEvent to the next view.
This is code using AppCompat, but if you are not building for older versions, you can use the regular GestureDetector and ActionBar.
Have you tried adding code to only show your UI when the state has changed? You have to maintain the last known visibility and only show your UI when you first come into being visible:
int mLastSystemUiVis;
#Override
public void onSystemUiVisibilityChange(int visibility) {
int diff = mLastSystemUiVis ^ visibility;
mLastSystemUiVis = visibility;
if ((diff&SYSTEM_UI_FLAG_VISIBLE) != 0
&& (visibility&SYSTEM_UI_FLAG_VISIBLE) == 0) {
// DISPLAY YOUR UI
}
}
Code sample adopted from the Android docs
The method Activity.onTouchEvent() gets called at the end of the responder chain (meaning after all other views have had a chance to consume the event). If you tap on a view that is interested in touch (i.e. a Button or EditText) there's a good chance your Activity will never see that event.
If you want to have access to touches before they every get dispatched to your view(s), override Activity.dispatchTouchEvent() instead, which is the method called at the beginning of the event chain:
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
//Check the event and do magic here, such as...
if (event.getAction() == MotionEvent.ACTION_DOWN) {
}
//Be careful not to override the return unless necessary
return super.dispatchTouchEvent(event);
}
Beware not to override the return value of this method unless you purposefully want to steal touches from the rest of the views, an unnecessary return true; in this spot will break other touch handling.
I got this problem too, and I found this http://developer.android.com/reference/android/view/View.html#SYSTEM_UI_FLAG_HIDE_NAVIGATION
So, no way to help. Even the android system packaged Gallery app used SYSTEM_UI_FLAG_LOW_PROFILE instead of SYSTEM_UI_FLAG_HIDE_NAVIGATION in photo page view. This is at least what we can do.
I had a very similar issue with trying to update the UI from an onTouchEvent() requiring two touches to work, and I tried a bunch of elaborate stuff before finally getting it to work on the first click.
In my case, I was showing a previously hidden item, then getting its height, then moving a button down by that height. The problem I ran into is that the height was showing as 0 until after the first touch event finished. I was able to solve this by calling show() during ACTION_UP for the onTouchEvent() instead of its ACTION_DOWN. Maybe it'd work if you did something similar?
Try to use:
getWindow().getDecorView().setSystemUiVisibility(View.GONE);
instead:
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
After that you can use normal activity in fullscreen and if you want nav keys you need to swipe from bottom to up. Working for me at Galaxy Tab 2 with android 4.1.2
(Please note that the behavior described in this question only appeared because of something else seemingly unrelated we were doing. See the accepted answer.)
We have an Android activity with a GridView and a SlidingDrawer inside of a RelativeLayout. The way this activity responds to the trackball (or cursor keys) is rather odd. The focus will move among the items in the GridView, but whenever the cursor moves in a direction "out" of the GridView. (e.g. up when at the top, left when already at the leftmost item) the sliding drawer opens or shut. Notably, the focus stays on the same item in the GridView---it does not move to the sliding drawer.
With a trackball this is particularly horrible, as spinning the trackball past your real destination will cause the sliding drawer to repeatedly open and close.
We've determined that we can turn off the trackball entirely by overriding onTrackballEvent(). We'd prefer to have the trackball and cursor work normally on the GridView but not cause the sliding drawer to open or close. In principle we'd also like the trackball to focus on the various contents of the sliding drawer when it is open.
How?
You may consider creating custom views extending GridView and SlidingDrawer and using custom implementations of onInterceptTouchEvent and onTouchEvent for the GridView and a custom implementation just for onInterceptTouchEvent for the SlidingDrawer. You may not need to implement a custom SlidingDrawer depending on what user interactions may be triggered on the handle
for your custom GridView, give it an interface maybe defined like this:
public interface MyGridViewListener {
public boolean shouldPreventScroll();
}
return if your custom SlidingDrawer is opened. this returned value will be used to determine if actions should be performed(for onInterceptTouchEvent and onTouchEvent methods) on the GridView. So when the SlidingDrawer is opened, actions performed on the GridView will not trigger anything on the SlidingDrawer.
Activity:
MyGridView gridView = (MyGridView) findViewById(R.id.gridView);
gridView.setMyGridViewListener(new MyGridViewListener() {
#Override
public boolean shouldPreventScroll() {
return slidingDrawer.isOpened();
}
});
MyCustomGridView:
shouldIntercept will be called whenever some touch/track event happens on the GridView.
private boolean shouldIntercept() {
boolean shouldIntercept = false;
if(myGridViewListener != null) {
shouldIntercept = myGridViewListener.shouldPreventScroll();
}
return shouldIntercept;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return shouldIntercept() ? true : super.onInterceptTouchEvent(ev);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return shouldIntercept() ? true : super.onTouchEvent(ev);
}
#Override
public boolean onTrackballEvent(MotionEvent event) {
return shouldIntercept() ? true : super.onTrackballEvent(event);
}
public MyGridViewListener getMyGridViewListener() {
return myGridViewListener;
}
public void setMyGridViewListener(
MyGridViewListener myGridViewListener) {
this.myGridViewListener = myGridViewListener;
}
I hope this points you in a right direction or at least helps
While playing around with a custom sliding drawer I set the layout of the handle to some odd value, something like
handle.layout(0, 0,0, 0);
to make the handle disappear but dragging a finger from the side of the screen would still open the sliding drawer, which is what I didn't want, so I set
handle.layout(10000, 10000, 10000, 10000);
which moved it way outside the viewable area and the drawer could no longer be pulled out manually by dragging from the side of the screen. After looking at the source code its teh position of the handle that determines the sliding of the drawer, get rid of the handle and it should solve your problem.
If you need to open/close the drawer call animateOpen()/animateClose()
As it turned out, we caused this problem by an unrelated bit of foolishness. We wanted the MENU key to open and close the SlidingDrawer. We did this by overriding onPrepareOptionsMenu():
public boolean onPrepareOptionsMenu (Menu menu) {
slidingDrawer.animateToggle();
return true;
}
This works fine; but it turns out it can be called when the menu is not about to be opened. In particular, if the Activity uses setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT), then an unhandled key event will end up accessing the menu. This includes trackball motion off the edge of the screen.
The less dumb way to get the desired behavior is
public boolean onKeyUp(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_MENU) {
slidingDrawer.animateToggle();
}
return super.onKeyUp(keyCode,event);
}
Meanwhile, we can get the trackball to move within the SlidingDrawer when it is open by setting up a SlidingDrawer.OnDrawerOpenListener which calls
slidingDrawer.getContent().requestFocus();
Finally it seems like a good idea to call
slidingDrawer.getHandle().setFocusable(false);