I have a flipper:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/ParentLayout"
xmlns:android="http://schemas.android.com/apk/res/android" style="#style/MainLayout" >
<LinearLayout android:id="#+id/FlipperLayout" style="#style/FlipperLayout">
<ViewFlipper android:id="#+id/viewflipper" style="#style/ViewFlipper">
<!--adding views to ViewFlipper-->
<include layout="#layout/home1" android:layout_gravity="center_horizontal" />
<include layout="#layout/home2" android:layout_gravity="center_horizontal" />
</ViewFlipper>
</LinearLayout>
</LinearLayout>
The first layout,home1, consists of a scroll view.
What should I do to distinguish between the flipping gesture and the scrolling?
Presently:
if I remove the scroll view, I can swipe across
if I add the scroll view, I can only scroll.
I saw a suggestion that I should override onInterceptTouchEvent(MotionEvent), but I do not know how to do this. My code, at this moment, looks like this:
public class HomeActivity extends Activity {
-- declares
#Override
public void onCreate(Bundle savedInstanceState) {
-- declares & preliminary actions
LinearLayout layout = (LinearLayout) findViewById(R.id.ParentLayout);
layout.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
return false;
}});
#Override
public boolean onTouchEvent(MotionEvent event) {
gestureDetector.onTouchEvent(event);
return true;
}
class MyGestureDetector extends SimpleOnGestureListener {
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// http://www.codeshogun.com/blog/2009/04/16/how-to-implement-swipe-action-in-android/
}
}
}
Can anybody please guide me in the right direction?
Thank you.
The view flipper only displays one view at a time as explained here. It is a kind of switch that is very useful when the developer wants to give the user a choice as to how to view the data (list, thumbnails, ect). therefore, the reason why you cant scroll and fling at the same time is because one view only scrolls and the other view only flings and only one is open at a time.
If you want your display to both scroll and fling, you will have to design a layout that is capable of both and override the needed methods. The first step towards that would be to remove your ViewFLipper and use something else.
Hope this was helpful!
Basically, if you have a ScrollView in a ViewFlipper, all you have to do is attach onTouchListener to the ScrollView:
ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
scrollView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event){
if (myGestureDetector.onTouchEvent(event)){
return true;
}
else{
return false;
}
}
});
I try this way to make it works:
#Override
public boolean onTouchEvent(MotionEvent event)
{
scrollView.onTouchEvent(event);
return super.onTouchEvent(event);
}
#Override
public boolean dispatchTouchEvent(MotionEvent e)
{
gestureDetector.onTouchEvent(e);
return super.dispatchTouchEvent(e);
}
Related
It should look something like this:
http://i.imgur.com/iMFm7GW.png
I'm thinking that I may need to have it on the Activity controlled by the ViewPager. Is there a better way?
EDIT: So I've made a version with a HorizontalScrollView in front of the ViewPager, but this has the problem of capturing scrolls. Code:
void initOverlayAnimator() {
ViewTreeObserver observer = mViewPager.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
mOverlayAnimator.setScreenWidth(mViewPager.getWidth());
mViewPager.getViewTreeObserver().removeOnGlobalLayoutListener(
this);
}
});
scrollImg.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
scrollImg.setOnDragListener(new View.OnDragListener() {
#Override
public boolean onDrag(View v, DragEvent event) {
return false;
}
});
scrollImg.setFocusableInTouchMode(false);
mOverlayAnimator.addView(imgIntroArrow, 3, 2);
}
Also tried to bypass from XML, no luck:
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/scrollImg"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:scrollbars="none"
android:contextClickable="false"
android:longClickable="false">
So the question remains, is there a better way, or what can I do about the scroll not passing the touch event?
What you want to do is set a back-view for the view pager's container frame, and have it set a as an image and move that image left or right when the view pager is scrolled
While spending a copious amount of time googling for a relatively simple solution to my problem I found this as a solution for two-dimensional scrolling. I have a a horizontalscrollview nested in a scrollview. I fiddled with this in a few ways and was unsuccessful in making anything functional. Does anyone have any ideas on how to make a concept like this work?
Scrollview scrollY = (ScrollView)findViewById(R.id.scrollY);
LinearLayout scrollYChild = (LinearLayout)findViewById(R.id.scrollYChild);
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
scrollYChild.dispatchTouchEvent(event);
scrollY.onTouchEvent(event);
return true;
}
I have also found this: http://blog.gorges.us/2010/06/android-two-dimensional-scrollview/ but I'm don't understand at all how to implement such a long piece of code properly.
It doesn't make much sense to me that two-dimensional scrolling is inherent in a webview but nonexistent elsewhere... Any and all help is appreciated.
Edit: How exactly does this work when zoomed in on an image in the gallery. Surely there has to be a way to implement that same functionality here.
Im not sure about the blog you have posted, this was my solution:
/**
* This class disables Y-motion on touch event.
* It should only be used as parent class of HorizontalScrollView
*/
public class ParentScrollView extends ScrollView {
private GestureDetector mGestureDetector;
View.OnTouchListener mGestureListener;
#SuppressWarnings("deprecation")
public ParentScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(new YScrollDetector());
setFadingEdgeLength(0);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if( mGestureDetector.onTouchEvent(ev)&super.onInterceptTouchEvent(ev)){
return true;
}else{
return false;
}
}
// Return false if we're scrolling in the x direction
class YScrollDetector extends SimpleOnGestureListener {
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if(Math.abs(distanceY) > Math.abs(distanceX)) {
return true;
}
return false;
}
}
}
XML:
<com.example.Views.ParentScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<HorizontalScrollView
android:id="#+id/tlDBtable"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</HorizontalScrollView>
</com.example.Views.ParentScrollView>
Basically the parent scrollview which only scrolls veritcal will be disabled because you will use a new custom class. Then you put a HScrollview within the scroll view. The Parentscroll view will pass the touch even if its not vertical to the horiszontalscroll view which makes it 2D scrolling effect.
There is a list view. I wrote this to stop the scroll when the user touches the screen while scrolling:
public class OnTouchListner implements OnTouchListener{
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN)
{
businessResultListView.smoothScrollBy(0, 0);
return true;
}
return false;
}
}
When i scroll the list down and when I touch the screen, the list view stops scrolling. But if I again try to scroll down / up, without lifting my finger from the scroll view, i am unable to scroll it.
If I take off my finger, then touch the list and then try to scroll, then I can do so.
How can I make my list scrollable after touch ?
Any help is greatly appreciated...
Give the Scroll id like scroll_home
ScrollView scroll_home;
scroll_home = (ScrollView) findViewById(R.id.scroll_event);
and on touch listview row add this function ...
this working well
v.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
scroll_home.requestDisallowInterceptTouchEvent(true);
return false;
}
});
Suppose that I have 100 item in my listView. When I scroll up and down, and I try to touch to stop the scrolling. But it's not work. It scroll until it reach the item of the first scroll touch.
Is it the phone problem or my app missing some implementing ?
public class OnTouchListner implements OnTouchListener{
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN)
{
businessResultListView.smoothScrollBy(0, 0);
return true;
}
return false;
}
}
and call it:
businessResultListView.setOnTouchListener(new OnTouchListner());
In my viewFlipper some TextViews are loaded dynamically. The size may differ which means that under the viewFlipper there could be some space left (see the green part in the screenshot)
screenshot
I want the onFling method to be called not only when swiping on the grey part (which is the viewflipper) but also when swiping on the green part
my layout looks like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="#+id/root">
<ViewFlipper android:id="#+id/viewFlipper"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</ViewFlipper>
</RelativeLayout>
In my onCreate i do this:
this.viewFlipper = (ViewFlipper) this.findViewById(R.id.viewFlipper);
this.gestureDetector = new GestureDetector(new MyGestureDetector());
RelativeLayout root = (RelativeLayout) this.findViewById(R.id.root);
root.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
Log.d("root", "true");
return false;
} else {
Log.d("root", "false");
return false;
}
}
});
So far I tried to return false even if I get true, so that the event does not get consumed and gets passed down to the viewFlipper even if the swipe has been made outside the viewflipper.
Note that the viewFlipper does not need any explicit onTouchListener. It works with or without one ( I dont really understand why..)
Does anyone know what to do?
Try adding android:clickable="true" to your RelativeLayout and you should be able to do it.
If that doesn't work you might need to implement these two methods also (if you haven't allready):
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
//TouchEvent dispatcher.
if (gestureDetector != null) {
if (gestureDetector.onTouchEvent(ev))
//If the gestureDetector handles the event, a swipe has been executed and no more needs to be done.
return true;
}
return super.dispatchTouchEvent(ev);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}