Прокрутка webview горизонтально внутри ViewPager

Я поместил WebView, загружая изображение внутри ViewPager. Когда я пытаюсь прокрутить изображение по горизонтали, я перехожу к следующему виду вместо прокрутки изображения.

Можно ли прокручивать его до конца изображения, прежде чем переходить к следующему виду?

@Override
public Object instantiateItem(View view, int i) {

    WebView webview = new WebView(view.getContext());
    webview.setHorizontalScrollBarEnabled(true);
    webview.loadUrl("http://www.site.with.an/image.gif");
    ((ViewPager) view).addView(webview, 0);

    return webview;
}

Ответ 1

Ниже приведено реальное рабочее решение, которое будет прокручивать WebView при горизонтальном прокрутке, если оно может прокручиваться. Если WebView не может прокручиваться, следующий горизонтальный саблей будет использоваться ViewPager для переключения страницы.

Расширение WebView

С API-уровнем 14 (ICS) был введен метод View canScrollHorizontally(), который нам необходимо решить. Если вы разрабатываете только ICS или выше, вы можете напрямую использовать этот метод и перейти к следующему разделу. В противном случае нам нужно реализовать этот метод самостоятельно, чтобы решение также работало на pre-ICS.

Для этого просто выведите свой собственный класс из WebView:

public class ExtendedWebView extends WebView {
    public ExtendedWebView(Context context) {
        super(context);
    }

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

    public boolean canScrollHor(int direction) {
        final int offset = computeHorizontalScrollOffset();
        final int range = computeHorizontalScrollRange() - computeHorizontalScrollExtent();
        if (range == 0) return false;
        if (direction < 0) {
            return offset > 0;
        } else {
            return offset < range - 1;
        }
    }
}

Важно: Не забудьте указать ExtendedWebView в своем файле макета вместо стандартного WebView.

Расширение ViewPager

Теперь вам нужно расширить ViewPager, чтобы правильно обрабатывать горизонтальные стрелки. Это необходимо сделать в любом случае - независимо от того, используете ли вы ICS или нет:

public class WebViewPager extends ViewPager {
    public WebViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
        if (v instanceof ExtendedWebView) {
            return ((ExtendedWebView) v).canScrollHor(-dx);
        } else {
            return super.canScroll(v, checkV, dx, x, y);
        }
    }
}

Важно: Не забудьте указать свой WebViewPager внутри вашего файла макета вместо стандартного ViewPager.

Что это!

Обновление 2012/07/08: Недавно я заметил, что показания, показанные выше, больше не нужны при использовании "текущей" реализации ViewPager. "Текущая" реализация, похоже, правильно проверяет подчиненные представления, прежде чем захватывать событие прокрутки на ней (см. canScroll метод ViewPager здесь). Не знаю точно, когда реализация была изменена, чтобы справиться с этим правильно - мне все еще нужен код выше на Android Gingerbread (2.3.x) и раньше.

Ответ 2

Хотя Sven упоминается для файла макета, я хочу добавить детали. После расширения классов Webview и ViewPager

Внутри вашей деятельности вы будете отбрасывать свой расширенный класс следующим образом:

web = (MyWebView) findViewById(R.id.webview);

Внутри вашего файла макета:

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