Фрагмент не привязан к FragmentManager - PullRequest
1 голос
/ 08 октября 2019

Я пытаюсь показать свою позицию на карте Google, которая отображается во фрагмент. Код макета фрагмента:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/window_background_color"
android:clickable="false">

<!-- Toolbar  -->

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="45dp"
    android:background="@color/primary_color"
    android:elevation="1dp"
    android:minHeight="?attr/actionBarSize"
    android:titleTextAppearance="@style/TextAppearance.AppCompat.Body1"
    app:popupTheme="@style/Theme.AppCompat">

    <TextView
        android:id="@+id/toolbar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:maxLines="1"
        android:text="@string/toolbar"
        android:textColor="@android:color/white"
        android:textSize="24sp" />
</androidx.appcompat.widget.Toolbar>

<RelativeLayout
    android:id="@+id/test"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:layout_alignParentStart="true"
    android:layout_below="@+id/toolbar"
    android:background="#1c3049"
    android:orientation="horizontal">

    <Button
        android:id="@+id/help"
        android:layout_width="45dp"
        android:layout_height="wrap_content"
        android:background="?attr/colorAccent"
        android:text="@string/help" />

    <Spinner
        android:id="@+id/spnCategory"
        android:layout_width="44dp"
        android:layout_height="match_parent"
        android:layout_alignParentEnd="true"
        android:layout_centerVertical="true"
        android:gravity="end" />

    <TextView
        android:id="@+id/mymess"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true"
        android:layout_marginStart="95dp"
        android:gravity="center_vertical|center_horizontal"
        android:textColor="@android:color/white"
        android:textSize="14sp" />
</RelativeLayout>

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/test"
    android:orientation="vertical" />

Фрагмент отображается из mainActivity:

FragmentTransaction mTransaction = getSupportFragmentManager().beginTransaction();
ActivityMap mFragment = new ActivityMap();
mTransaction.add(R.id.fragment, mFragment);
mTransaction.commit();

Я вызываю getUserPosition из:

@Override
public void onLocationChanged(Location location) {
    mCurrentLocation = location;
    getUserPosition(location.getLatitude(), location.getLongitude());
}

имой код getUserPosition:

  public void getUserPosition(double latitude, double longitude) {

    mCurrentLatitude = latitude;
    mCurrentLongitude = longitude;

    if (mIsMapVisible && isNetworkAvailable()) {
        TextView mytext = Objects.requireNonNull(getActivity()).findViewById(R.id.mymess));

        Geocoder geocoder = new Geocoder(getActivity(), Locale.ENGLISH);
        List<Address> addresses;
        try {
            addresses = geocoder.getFromLocation(mCurrentLatitude, mCurrentLongitude, 1);
            if ((addresses.size()>0)) {
                String str = addresses.get(0).getAddressLine(0);
                if(str.contains(",")) {
                    mytext.setText(str.substring(0, str.indexOf(",")));
                } else {
                    mytext.setText(str);
                }
            } else {
                mytext.setText(R.string.no_adr);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.printStackTrace();
            String temp = mCurrentLatitude + "," + mCurrentLongitude;
            mytext.setText(temp);
        }
    }

    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
            new LatLng(mCurrentLatitude, mCurrentLongitude),
            Utils.ARG_DEFAULT_MAP_ZOOM_LEVEL);

    mMap.animateCamera(cameraUpdate);

}

Наконец, это проблемная часть:

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager
            = (ConnectivityManager) getLayoutInflater().getContext().getSystemService(CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager != null ? connectivityManager.getActiveNetworkInfo() : null;
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

Здесь я получаю следующее сообщение об ошибке: E / UncaughtException: java.lang.IllegalStateException: onGetLayoutInflater () не можетвыполняться до тех пор, пока фрагмент не будет присоединен к FragmentManager.

Первый раз, когда я запускаю приложение, работает отлично. Второй раз получаю ошибку. И так до тех пор, пока мое устройство не спросит, хотите ли вы закрыть приложение, потому что остановка продолжается. Я принимаю и в следующий раз работаю отлично. Тогда ... снова проблемный спам.

Любой совет?

1 Ответ

1 голос
/ 08 октября 2019

Fragments имеют свой жизненный цикл. При работе с фрагментами вы всегда должны учитывать, что они могут быть отсоединены, скрыты или их состояние уже сохранено.

Возможно, проблема возникает из-за того, что вы слишком рано слушаете события изменения местоположения. Тем не менее, даже если вы изменяете при регистрации прослушивателя местоположения, рекомендуется получить Context (или Activity) безопасным способом (поскольку при отсоединении Context / Actvity будет нулевым).

Итак, я рекомендую:

private boolean isNetworkAvailable() {
    boolean result = false;
    Context context = getContext();
    if(context != null) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager != null ? connectivityManager.getActiveNetworkInfo() : null;
        result = activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }
    return result;
}

Fragment имеет метод getContext(). Таким образом, вы можете заменить getLayoutInflater() на getContext()

...