two directional scroll view

2019-01-17 17:26发布

I would like to have a linearlayout with a header section on top and a webview below. The header will be short and the webview may be longer and wider than the screen.

What is the best way to get horizontal and vertical scrolling? Is a ScrollView nested inside a HorizontalScrollView a good idea?

9条回答
Emotional °昔
2楼-- · 2019-01-17 17:54

I know you have accepted your answer but may be this could give you some idea.

<?xml version="1.0" encoding="utf-8"?>

<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>

<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<HorizontalScrollView
    android:layout_alignParentBottom="true"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
<ImageView

android:src="@drawable/device_wall"
android:scaleType="center"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</HorizontalScrollView>
</RelativeLayout>
</LinearLayout>
</ScrollView>
查看更多
欢心
3楼-- · 2019-01-17 17:56

there is another way. moddified HorizontalScrollView as a wrapper for ScrollView. normal HorizontalScrollView when catch touch events don't forward them to ScrollView and you only can scroll one way at time. here is solution:

package your.package;

import android.widget.HorizontalScrollView;
import android.widget.ScrollView;
import android.view.MotionEvent;
import android.content.Context;
import android.util.AttributeSet;

public class WScrollView extends HorizontalScrollView
{
    public ScrollView sv;
    public WScrollView(Context context)
    {
        super(context);
    }

    public WScrollView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public WScrollView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override public boolean onTouchEvent(MotionEvent event)
    {
        boolean ret = super.onTouchEvent(event);
        ret = ret | sv.onTouchEvent(event);
        return ret;
  }

    @Override public boolean onInterceptTouchEvent(MotionEvent event)
    {
        boolean ret = super.onInterceptTouchEvent(event);
        ret = ret | sv.onInterceptTouchEvent(event);
        return ret;
    }
}

using:

    @Override public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

/*BIDIRECTIONAL SCROLLVIEW*/
        ScrollView sv = new ScrollView(this);
        WScrollView hsv = new WScrollView(this);
        hsv.sv = sv;
/*END OF BIDIRECTIONAL SCROLLVIEW*/

        RelativeLayout rl = new RelativeLayout(this);
        rl.setBackgroundColor(0xFF0000FF);
        sv.addView(rl, new LayoutParams(500, 500));
        hsv.addView(sv, new LayoutParams(WRAP_CONTENT, MATCH_PARENT /*or FILL_PARENT if API < 8*/));
        setContentView(hsv);
    }
查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-17 18:01

I searched really long to make this work and finally found this thread here. wasikuss' answer came quite close to the solution, but still it did not work properly. Here is how it works very well (at least for me (Android 2.3.7)). I hope, it works on any other Android version as well.

Create a class called VScrollView:

package your.package.name;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;
import android.widget.ScrollView;


public class VScrollView extends ScrollView {
    public HorizontalScrollView sv;

    public VScrollView(Context context) {
        super(context);
    }

    public VScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public VScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        sv.dispatchTouchEvent(event);
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        super.onInterceptTouchEvent(event);
        sv.onInterceptTouchEvent(event);
        return true;
    }
}

Your layout should look like:

<your.package.name.VScrollView
    android:id="@+id/scrollVertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <HorizontalScrollView
        android:id="@+id/scrollHorizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <TableLayout
            android:id="@+id/table"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="false"
            android:stretchColumns="*" >
        </TableLayout>
    </HorizontalScrollView>
</your.package.name.VScrollView>

In your activity, you should do something like:

hScroll = (HorizontalScrollView) findViewById(R.id.scrollHorizontal);
vScroll = (VScrollView) findViewById(R.id.scrollVertical);
vScroll.sv = hScroll;

... and that's how it works. At least for me.

查看更多
登录 后发表回答