使用 PreferenceFragmentCompat 后无法膨胀 android.widget.Toolbar [原因:RtlSpacingHelper]

问题描述 投票:0回答:0

A

FragmentActivity
正确充气
android.widget.Toolbar
在第一次部署
androidx.preference.PreferenceFragmentCompat
后停止这样做。

堆栈跟踪表明失败的根本原因是

android.widget.RtlSpacingHelper
的空实例:

android.view.InflateException: Binary XML file line #18: Binary XML file line #18: Error inflating class <unknown>

Caused by: android.view.InflateException: Binary XML file line #18: Error inflating class <unknown>

Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Constructor.newInstance0(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
    at android.view.LayoutInflater.createView(LayoutInflater.java:652)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:794)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:734)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:496)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:427)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:378)
    at common.WideFrag.onCreateView(WideFrag.java:168)
    at androidx.fragment.app.Fragment.performCreateView(Fragment.java:3104)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:524)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1899)
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1817)
    at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1760)
    at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:547)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6780)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
    
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.RtlSpacingHelper.setDirection(boolean)' on a null object reference
    at android.widget.Toolbar.onRtlPropertiesChanged(Toolbar.java:825)
    at android.view.View.resolvePadding(View.java:16493)
    at android.view.ViewGroup.resolvePadding(ViewGroup.java:7006)
    at android.view.View.initializeScrollbarsInternal(View.java:5740)
    at android.view.View.<init>(View.java:4988)
    at android.view.ViewGroup.<init>(ViewGroup.java:579)
    at android.widget.Toolbar.<init>(Toolbar.java:291)
    at android.widget.Toolbar.<init>(Toolbar.java:287)
    at android.widget.Toolbar.<init>(Toolbar.java:283)
    ... 23 more
    
WideFrag.onCreateView: InflateException for toolbar.xml=2131558714 (0x7f0d013a): android.view.InflateException: Binary XML file line #18: Error inflating class <unknown>

Toolbar('toolbar.xml')如下:

<android.widget.Toolbar android:id="@+id/toolbar"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="@dimen/listItemHeightMenu"
        android:background="@color/khaki_tp"
        android:elevation="6dp"
        android:visibility="gone"
        > <!-- NB: Stacktrace refers to this line -->
    </android.widget.Toolbar>

这里是有问题的 Fragment 的拆解极简版本。它包含自己的实例化器,以方便任何希望重现问题的人。如果您的应用程序使用 android.widget.Toolbar 那么它将在该片段运行后停止工作,但请注意 androidx.appcompat.widget.Toolbar 仍将正常膨胀!

package yourPackage;
import static java.lang.String.format;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.PreferenceFragmentCompat;
import yourPackage.R;

/** Prove bug upsetting Toolbar inflation (1/2) */
public class PrefsBug1 extends PreferenceFragmentCompat {
    public static String TAG = "Buggy-tag1";

    public static void newInstance(FragmentActivity A) {
        PrefsBug1 frag = new PrefsBug1();
        int ctr = R.id.fragment_container;
        FragmentManager fm = A.getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(ctr, frag, TAG);
        ft.addToBackStack(TAG);
        String msg;
        try { ft.commit();
            msg=(format("Added '%s' to container %d [%s] (backstack was %d).", TAG, ctr, "R.id.fragment_container", fm.getBackStackEntryCount()));}
        catch (Exception e) { msg = e.getMessage(); }
        Log.d(TAG, msg);
    }

    @Override
    public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
        setPreferencesFromResource(R.xml.pref_debug, rootKey);
    }
}

这里是示例 PrefScreen('pref_debug.xml'):

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="A PREFERENCE">
        <EditTextPreference
            android:key="pref_fontScale"
            android:title="pref_fontScale_title"
            android:summary="Override default font scale"
            android:inputType="number|numberDecimal"
            android:defaultValue="0.0" />
    </PreferenceCategory>
</PreferenceScreen>

最后,在SDK中,令人失望的是虽然android.widget.RtlSpacingHelper在属于Android API 33,扩展级别3平台android.jar中找不到,但是RtlSpacingHelper.java附带平台源。

但真正的问题是有问题的 Fragment 如何影响 Activity 的所有未来行为,是否可能存在规避?

android android-toolbar android-inflate preferencefragment preferencefragmentcompat
© www.soinside.com 2019 - 2024. All rights reserved.