I have a problem which I am not sure how can I handle.
I started using a library called MenuDrawer on which I have given the following:
mDrawer.setTouchMode(MenuDrawer.TOUCH_MODE_FULLSCREEN);
Which allows it to pop open whenever I drag the screen down, but this actually rises another issue for me, because I use a ListView there that needs to be scrolled also.
I actually have 2 questions, taking in regards that not all may have used this library.
If you have used this library: Is it possible to focus the dragging on just 1 element? For example if I have a TextView there can I drag only that item to open the menu?
If you haven't used this library: How can a child element steal the focus from the parent on touch event? So that when I touch and drag somewhere where the listview is to achieve a successful scrolling up and down.
Right now I can scroll freely only down and when I try to scroll up opens the menu, unless I scroll the listview first down and up without breaking contact with the screen.
I found how to manage that. For me this simple piece of code worked like a charm:
mDrawer.setOnInterceptMoveEventListener(new OnInterceptMoveEventListener(){
#Override
public boolean isViewDraggable(View v, int dx, int x, int y) {
//v.getId();
if(y > 50){
return true;
}
return false;
}});
if anything below Y 50 is pulled it won't trigger the menu drawer.
Related
I implemented a View.OnDragListener for a simple drag and drop feature, and added additional support for scrolling the parent view while dragging the target. This works fine if I release the drag at a valid target view (i.e. if onDragEvent returns false for DragEvent.ACTION_DROP). For example here I start dragging folder L, scroll up and drop it to inside folder A, and the animation is working correctly:
This also works fine if I don't scroll while dragging and nothing handles the drop (i.e. if onDragEvent returns true for DragEvent.ACTION_DROP and the position of the dragged view hasn't changed since starting the drag). For example here I start dragging folder L, drag it up to blank space which isn't a valid drop target, and release. The animation moves it back down to where L's original position, looking good.
But as soon as I scroll the parent view while dragging and nothing handles the drop, the animation becomes completely wrong because Android apparently ignores the fact that the view is now sitting at different coordinates than before. It just sets the coordinates at the point of calling startDragAndDrop and never updates them. For example here I start dragging folder L, scroll up, drag it to blank space which isn't a valid drop target, and release. The animation moves it up because that's where L's original location was relative to the screen, not the scrolling content:
What I need is for L to move down to where it is at the end, not at the start. How can I achieve this? I know the final coordinates, but I don't know how to fix the animation accordingly. I haven't even found any Android SDK code where this release animation is handled (Google seems to handle this magically via SurfaceSession and a system-private IWindowSession.aidl).
The code I use for the drag and drop is very simple, it's just this:
val shadow = View.DragShadowBuilder(v)
#Suppress("DEPRECATION")
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
v.startDrag(null, shadow, item, 0)
else
v.startDragAndDrop(null, shadow, item, 0)
The code to make it support scrolling is a bit more complicated, something like the solutions to this question: Make a scrollView autoscroll with drag and drop in Android.
But that part isn't essential to reproduce it. You basically just need a ScrollView or RecyclerView and scroll it programmatically or manually after starting the drag. Nothing fancy.
Please note that I'm showing examples which might lead to the assumption that ItemTouchHelper would solve my problem. In normal situations ItemTouchHelper would be the go-to solution, but in fact, I'm actually using the drag and drop to move views between RecyclerViews (and across fragments), which is not supported by ItemTouchHelper, so it's not applicable in this case.
I have this problem with Android ListView. My View consists of ListView and two floating buttons on the bottom of it. These two floating buttons overlays the last item of the ListView. On the iOS side by default you can drag last ListView's item to the middle of the View and in this way it's possible to see what item it is. When you release the last item it scrolls back to the bottom of the page. On the Android part by default the last item of ListView doesn't drag to the top so that it would create some space after it. Any ideas how it's possible to achieve this kind of behaviour?
This isn't really the default behaviour you would want on android, however I think it's possible to achieve it using the following method: https://stackoverflow.com/a/12424780/2350917
I have never tried it though, so tell us how you got on.
Edit:
#Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
if(scrollY < 0) {
smoothScrollToPosition(0);
} else if(scrollY > MAX_SCROLL) {
smoothScrollToPosition(getAdapter().getCount());
}
}
Edit 2:
The best method to solve this and to follow android guidelines, would be to show the floating action buttons when you get to the listview screen and then make them disappear as you scroll down. When you scroll up they would appear again. Like this you could see the content on the last item of the listview.
This method would work if it is not essential to show your floating action buttons ALL the time.
OK, I have an app that needs access to basic swipe gestures. I've implemented a GestureDetector using code scraped from StackOverflow and then modified (to make it work at all). For it to work, it needs to steal Touch events.
Originally, I was detecting onScroll events and such and trying to pass them on to elements that needed to scroll, but this was really jumpy and never scrolled by the amount I wanted, so I started to simply pass the touch events on to the super-class after reading them. This caused really strange behavior and some elements never scrolled at all (no idea why), so I started passing events in a 3 way split ... some to the super-class, some to the gesture-detector, and some to the on-screen view that needed to scroll! Yeah, a mess, but everything is finally working smoothly. Except ...
If you touch the bottom of an EditText (it's full-screen except for the AppBar), then as the keyboard appears and scrolls the EditText up, the appbar scrolls off the screen (right under the statusbar icons ... looks weird because they overlay each other) and I can't make it scroll back. Also means I can't get to my Menu or the Cut/Copy icons. Hitting the menu key when it has scrolled off crashes the app.
Any idea how to stop the AppBar from scrolling off the screen?
#Override
public boolean dispatchTouchEvent(MotionEvent me) {
int top = dm.heightPixels - myEditText.getMeasuredHeight();
MotionEvent mod = MotionEvent.obtain(me.getDownTime(), me.getEventTime(),
me.getAction(), me.getX(), me.getY()-top, me.getMetaState());
if (me.getY() <= top)
return super.dispatchTouchEvent(me);
myEditText.onTouchEvent(mod);
return this.detector.onTouchEvent(me);
}
OK, this seems to fix it! In the activity manifest ...
android:windowSoftInputMode="adjustResize"
Bamn! No more problems!
It's my understanding that Android event propagation goes from parent to child, that is to say, it starts with the outermost element and inwards from there. My question is, why is it that when I try to scroll vertically a listview that is inside a viewpager that is wrapped on a scrollview, the listview moves, and not the viewpager.
Okay, let me rephrase that:
I'm trying to create a menu that appears when the user pulls down the view pager, let me make that even clearer:
Scrollview
My custom Menu
ViewPager (with three fragments, all of them have a lisview)
ListView
I understand that what I'm trying to do is a bit odd, but bear with me just for this time. :)
What can I do to "disable" momentarily the list views scrolling.
Thanks
It seems you have to override the scrolling event. A good webpage is Disable scrolling in Android ListView .
Mainly look at dispatchTouchEvent. Snippet of it:
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK;
if (actionMasked == MotionEvent.ACTION_MOVE) {
// Ignore move events
return true;
}
Personally I wish it is simpler than this like disabling scroll method.
Hello I am trying to make a terminal type app that is wider than the actual android screen. A listview is great except that I don't want the text to wrap. If the text is wider than the screen I want it to print the full text and then the user can scroll over horizontally if they want to see what was printed off the screen. Just FYI this is for ascii type tables. I have followed this example:
http://nan-technicalblog.blogspot.com/2008/12/android-how-to-use-horizontal-scrolling.html
It works great as far as horizontal text goes it does exactly what I want but I am unable to get the ListView inside the custom LinearLayout to actually scroll veritcally. I have tried passing the Y coordinates from the onScroll method to mListView such as:
mListView.scrollBy(0, distanceY);
but that seems to move the custom LinearLayout window instead of just scrolling the ListView. I can tell that the ListView is not scrolling because the window moves without the vertical scroll bar of the ListView moving. Everything just slides around. Any help would be much appreciated.
Okay this one also took me about a week in my spare time to figure out. I had to change the supplied code for dispatchTouchEvent to this:
public boolean dispatchTouchEvent(MotionEvent ev){
mGestureDetector.onTouchEvent(ev);
mListView.onTouchEvent(ev);
return true;
}
Also changed onScroll to return false just for good measure.