WebViewFragment webView является нулевым после выполнения FragmentTransaction

В настоящее время у меня есть приложение, настроенное сListFragment слева иDetailsFragment справа (аналогично макету на планшете ниже).

На фрагменте подробностей (фрагмент рядом со списком) у меня есть кнопка Перейти к сделке, которая при нажатии должна заменить фрагмент подробностей наWebViewFragment.

Проблема у меня заключается в том, что при попытке загрузить URL-адрес в фрагментеWebView нулевой.

WebViewFragment webViewFragment = new WebViewFragment();

FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.deal_details_fragment, webViewFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

// Set the url
if (webViewFragment.getWebView()==null)
    Log.d("webviewfragment", "is null");
webViewFragment.getWebView().loadUrl("http://www.google.com");

Ниже мой основной макет, в котором определены два оригинальных фрагмента.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/main_activity_layout"

    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

  <fragment
      android:name="com.bencallis.dealpad.DealListFragment"
      android:id="@+id/deal_list_fragment"
      android:layout_weight="1"
      android:layout_width="0px"
      android:layout_height="match_parent" >
      <!-- Preview: [email protected]/deal_list_fragment -->
  </fragment>
  <fragment
      android:name="com.bencallis.dealpad.DealDetailsFragment"
      android:id="@+id/deal_details_fragment"
      android:layout_weight="2"
      android:layout_width="0px"
      android:layout_height="match_parent" >
      <!-- Preview: [email protected]/deal_details_fragment -->
  </fragment>

</LinearLayout>

Похоже, что webViewFragment создается не полностью, так какWebView не был инициализирован. Я посмотрел в Интернете, но очень мало информации оWebViewFragment.

Любые идеи, как обеспечитьWebView инициализируется вWebViewFragment?

 bencallis06 февр. 2012 г., 19:16
@Jonathan - Извините, мой DealWebViewFragment был просто воссозданием WebViewFragment. Я изменил приведенный выше код обратно на WebViewFragment (та же проблема существует).
 Jonathan06 февр. 2012 г., 15:12
Пожалуйста, опубликуйте код для вашего класса DealWebViewFragment.

Ответы на вопрос(4)

асширение (вы можете скопировать / вставить):

public class UrlWebViewFragment extends WebViewFragment{

    private String url;

    public static UrlWebViewFragment newInstance(String url) {
        UrlWebViewFragment fragment = new UrlWebViewFragment();
        fragment.url = url;
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        WebView webView = (WebView) super.onCreateView(inflater, container, savedInstanceState);
        webView.loadUrl(url);
        return webView;
    }         
  }

Звоните, где вам нужно, используя фабричный метод:

WebViewFragment fragment = UrlWebViewFragment.newInstance("http://ur-url.com");
 Ruslan Berozov18 апр. 2018 г., 11:55
Фрагмент с конструктором без расслоения. Это не хороший образец для использования.

Таким образом, я поиграл с этим некоторое время, и кажется, что WVF немного мусор и предназначен для переопределения. Тем не менее, нет никакой документации по этому вопросу вообще! Проблема связана с тем, что вы можете вызвать getWebView () доFragments представление загружено, следовательно, вашNullPointerException, За исключением того, что нет никакого способа определить, когда представление фрагмента было загружено, так что вы застряли!

Вместо этого я переопределил класс, добавляя биты и меняя их, чтобы теперь он работал нормально. Проверьтеэта ссылка для кода. Тогда вместо использования:

WebViewFragment webViewFragment = new WebViewFragment();

чтобы загрузить свой фрагмент, используйте:

ImprovedWebViewFragment wvf = new ImprovedWebViewFragment("www.google.com");

Этот класс также включает удобный метод для загрузки URL, которыйне будет броситьException если нетWebView.

Итак, нет, я не думаю, что есть особенно простой способ использования встроенного WebViewFragment, но довольно легко сделать что-то, что работает вместо этого. Надеюсь, это поможет!

 Alex Curran09 февр. 2012 г., 15:03
вид, см мой отредактированный ответ
 bencallis09 февр. 2012 г., 14:29
Спасибо. У тебя была удача?
 Warpzit29 окт. 2012 г., 09:34
Лучшим подходом было бы предоставить аргументы для запуска фрагментов вместо предоставления параметров для конструктора. Когда вы перегружаете конструктор, вы позже сталкиваетесь с проблемами, когда система восстанавливает ваши фрагменты. Вы должны использовать статический метод экземпляра или пустой конструктор для создания фрагментов.
 bencallis08 февр. 2012 г., 17:34
Я использую встроенный Android WebViewFragment [ссылка]developer.android.com/reference/android/webkit/... , Я могу заняться созданием своего собственного, но, конечно, я должен быть в состоянии встроить один.
 Alex Curran08 февр. 2012 г., 18:56
о да, извините, не понял этого. Я возьму с собой код, который ты написал, и посмотрю, смогу ли я помочь.
Решение Вопроса

тобы ссылки открывались во фрагменте, а не в приложении веб-браузера, я создал простой клиент InnerWebView, который расширяет WebViewClinet.

public class DealWebViewFragment extends Fragment {

    private WebView mWebView;
    private boolean mIsWebViewAvailable;
    private String mUrl = null;

    /**
     * Creates a new fragment which loads the supplied url as soon as it can
     * @param url the url to load once initialised
     */
    public DealWebViewFragment(String url) {
        super();
        mUrl = url;
    }

    /**
     * Called to instantiate the view. Creates and returns the WebView.
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        if (mWebView != null) {
            mWebView.destroy();
        }
        mWebView = new WebView(getActivity());
        mWebView.setOnKeyListener(new OnKeyListener(){


            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                  if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
                        mWebView.goBack();
                        return true;
                    }
                    return false;
            }

        });
        mWebView.setWebViewClient(new InnerWebViewClient()); // forces it to open in app
        mWebView.loadUrl(mUrl);
        mIsWebViewAvailable = true;
        WebSettings settings = mWebView.getSettings();
        settings.setJavaScriptEnabled(true);
        return mWebView;
    }

    /**
     * Convenience method for loading a url. Will fail if {@link View} is not initialised (but won't throw an {@link Exception})
     * @param url
     */
    public void loadUrl(String url) {
        if (mIsWebViewAvailable) getWebView().loadUrl(mUrl = url);
        else Log.w("ImprovedWebViewFragment", "WebView cannot be found. Check the view and fragment have been loaded.");
    }

    /**
     * Called when the fragment is visible to the user and actively running. Resumes the WebView.
     */
    @Override
    public void onPause() {
        super.onPause();
        mWebView.onPause();
    }

    /**
     * Called when the fragment is no longer resumed. Pauses the WebView.
     */
    @Override
    public void onResume() {
        mWebView.onResume();
        super.onResume();
    }

    /**
     * Called when the WebView has been detached from the fragment.
     * The WebView is no longer available after this time.
     */
    @Override
    public void onDestroyView() {
        mIsWebViewAvailable = false;
        super.onDestroyView();
    }

    /**
     * Called when the fragment is no longer in use. Destroys the internal state of the WebView.
     */
    @Override
    public void onDestroy() {
        if (mWebView != null) {
            mWebView.destroy();
            mWebView = null;
        }
        super.onDestroy();
    }

    /**
     * Gets the WebView.
     */
    public WebView getWebView() {
        return mIsWebViewAvailable ? mWebView : null;
    }

    /* To ensure links open within the application */
    private class InnerWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }


    }

Надеюсь, это пригодится кому-то в будущем.

только если они были инициализированы в Java, а не в XML. Я так думаю, у меня была такая же проблема, и она решила ее. Измените свой XML на это:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/main_activity_layout"

    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

  <fragment
      android:name="com.bencallis.dealpad.DealListFragment"
      android:id="@+id/deal_list_fragment"
      android:layout_weight="1"
      android:layout_width="0px"
      android:layout_height="match_parent" >
      <!-- Preview: [email protected]/deal_list_fragment -->
  </fragment>
  <View
      android:id="@+id/my_container"
      android:layout_weight="2"
      android:layout_width="0px"
      android:layout_height="match_parent" >
  </View>

</LinearLayout>

а затем в Java, ваш метод onCreate:

FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.my_container, new DealDetailsFragment());
transaction.commit();

или даже лучше создать целый метод, чтобы просто иметь дело сTransactions.

В настоящее времяTransaction от твоего вопроса должно получиться. :)

 bencallis06 февр. 2012 г., 19:10
Спасибо за помощь. Я изменил свой макет, заменив фрагмент представлением. В своей основной деятельности я добавил следующую транзакцию FragmentTransaction = getFragmentManager (). BeginTransaction (); action.replace (R.id.right_fragment_container, new DealDetailsFragment (), "dealDetailsFragment"); transaction.commit (); К сожалению, это приводит к исключению Java.lang.ClassCastException: android.view.View не может быть приведено к android.view.ViewGroup.
 bencallis06 февр. 2012 г., 19:32
Я отсортировал это исключение приведения, используя LinearLayout, а не View. Приложение теперь запускается, но при нажатии кнопки «Перейти к сделкам» URL-адрес не может быть загружен, поскольку webView по-прежнему равен нулю.

Ваш ответ на вопрос