Предварительно загрузить WebView фрагмента в PagerAdapter

Я использую FragmentStatePagerAdapter для перечисления моих Fragmets в ViewPager. Каждый фрагмент содержит только WebView. Все работает нормально, я просто хочу использовать механизм предварительной загрузки PagerAdapter, который заранее загружает 1 Fragment. Это упрощенный код для моего Fragment:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
    View view = inflater.inflate(R.layout.ecard_fragment, container, false);
    webview = (WebView) view;
    webview.loadDataWithBaseURL("", HTML, "text/html", "utf-8", "");
    Toast.makeText(getActivity(), "fragment: " + NAME, Toast.LENGTH_SHORT).show();
    return view;
}

Я уверен, что следующий Fragment сгенерирован заранее, потому что Toast показывается заранее. Но WebView загружается позже - сразу после того, как Fragment сфокусирован. Как заставить WebView загружаться?


person peter.bartos    schedule 29.04.2013    source источник
comment
Вы пробовали adapter.setOffscreenPageLimit(3)?   -  person Artem Zelinskiy    schedule 29.05.2013
comment
я подозреваю, что это, вероятно, связано с проблемой, которая у меня была, когда у меня был установлен WebView на WRAP_CONTENT, который изначально имел размер 0x0, а после отображения момент изменил свой размер, чтобы соответствовать его содержимому. я так и не нашел способа заставить WebView предварительно загрузить себя или даже определить, когда загрузка была выполнена. я не думаю, что есть хороший ответ на проблему предварительной подготовки WebView.   -  person j__m    schedule 30.05.2013


Ответы (3)


Создайте свой веб-просмотр в методе OnCreate() и раздуйте этот веб-просмотр позже в своем методе OnCreateView().

Ваш WebView загружается позже, потому что метод onCreateView() вызывается только в том случае, если фрагменту необходимо загрузить пользовательский интерфейс для пользователя.

OnCreate(), с другой стороны, вызывается перед OnCreateView() и может создавать экземпляры основных элементов вашего фрагмента.

person DuKes0mE    schedule 23.05.2013
comment
Спасибо за ваш ответ. Итак, вы предлагаете раздувать WebView в OnCreate, а в OnCreateView просто возвращать предварительно раздутый макет? Я попробовал войти прямо сейчас, но поведение такое же. - person peter.bartos; 27.05.2013
comment
Эм, да, это был мой план. Другим вариантом может быть использование вашей активности для предварительной загрузки вашего WebView, и всякий раз, когда вы меняете фрагменты, он должен подталкивать следующий желаемый контент к активности, и вы сможете получить его предварительно загруженным из своей активности. Вы знаете, к чему я клоню? - person DuKes0mE; 27.05.2013
comment
Я подозреваю, что WebView может быть медленным элементом, который не будет загружать контент, пока не будет запрошен макет. - person peter.bartos; 27.05.2013
comment
Хотя это должно быть возможно. Некоторые люди используют, например, 2 веб-просмотра (один невидимый, один видимый) и переключаются между этими двумя для предварительной загрузки материала. - person DuKes0mE; 27.05.2013
comment
Я не выбираю это как ответ, потому что это не решило проблему. Но спасибо за указание на разницу между OnCreate и OnCreateView. - person peter.bartos; 30.05.2013

Я написал простой демонстрационный проект, и для меня он отлично работает. Представления окрестностей предварительно сгенерированы. Это мой код:

public class DrawActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle arg0) {
    setContentView(R.layout.pager);
    ((ViewPager) findViewById(R.id.pager)).setAdapter(new ScreenSlidePagerAdapter(getSupportFragmentManager()));
    super.onCreate(arg0);
}

private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {

    public ScreenSlidePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return new WebViewFragment(position);
    }

    @Override
    public int getCount() {
        return 3;
    }
}

@SuppressLint("ValidFragment")
private class WebViewFragment extends Fragment {

    private WebView mWebView;
    private int pos;

    public WebViewFragment(int pos) {
        this.pos = pos;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mWebView = new WebView(getApplicationContext());
        mWebView.loadDataWithBaseURL("", "<h1> ----------------TEST----------------- " + pos + "</h1>", "text/html", "utf-8", "");
        Toast.makeText(getActivity(), "fragment: " + this.toString(), Toast.LENGTH_SHORT).show();
        return mWebView;
    }

}
}

и XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

And result:

введите здесь описание изображения

person Roman Nazarevych    schedule 29.05.2013
comment
Я думаю, что это именно то, что у меня было в моей первой попытке (до оптимизации с помощью onCreate вместо onCreateView). Используя новейший Android API, загрузка выглядит намного быстрее, а пустое веб-представление видно всего на несколько миллисекунд. Ваш веб-просмотр намного проще, поэтому я думаю, что он генерируется сразу. - person peter.bartos; 29.05.2013

Я столкнулся с той же проблемой и исправил ее, отключив аппаратное ускорение для WebView:

webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

через WebViews в ViewPager не загружаются/рендерятся до тех пор, пока страница показана

person Sergii    schedule 05.03.2015
comment
В моем случае не помогло, просто очень сильно замедлило просмотр в Интернете... - person user754730; 28.04.2020