Search code examples
androidandroid-fragmentsnononsense-filepicker

#90: Error inflating class ImageButton


I am using NoNonsense-FilePicker for filtering the sd card for pdf files by extending the FilePickerActivity and creating a FilteredFilePickerFragment instance through it but i get an error related to an Image button in it's resources.

this is the File Picker Fragment Extender:

public class FilePickerFragmentExtender extends FilePickerActivity {

public FilePickerFragmentExtender() {
    super();
}

@Override
protected AbstractFilePickerFragment<File> getFragment(@Nullable String startPath, int mode, boolean allowMultiple, boolean allowCreateDir, boolean allowExistingFile, boolean singleClick) {
    AbstractFilePickerFragment<File> fragment = new FilteredFilePickerFragment();
    // startPath is allowed to be null. In that case, default folder should be SD-card and not "/"
    fragment.setArgs(startPath != null ? startPath : Environment.getExternalStorageDirectory().getPath(),
            mode, allowMultiple, allowCreateDir, allowExistingFile, singleClick);
    return fragment;
  }
}

and this is the Filtered File Picker Fragment:

public class FilteredFilePickerFragment extends FilePickerFragment {
private static final String TAG = "FilteredFilePickerFragm";
// File extension to filter on
private static final String EXTENSION = ".pdf";

public FilteredFilePickerFragment() {
    super();
}

/**
 * @param file
 * @return The file extension. If file has no extension, it returns null.
 */
private String getExtension(@NonNull File file) {
    String path = file.getPath();
    int i = path.lastIndexOf(".");
    if (i < 0) {
        return null;
    } else {
        return path.substring(i);
    }
}

@Override
protected boolean isItemVisible(final File file) {
    boolean ret = super.isItemVisible(file);
    if (ret && !isDir(file) && (mode == MODE_FILE || mode == MODE_FILE_AND_DIR)) {
        String ext = getExtension(file);
        return ext != null && EXTENSION.equalsIgnoreCase(ext);
    }
    return ret;
  }
}

the error:

FATAL EXCEPTION: main
                                                  Process: com.pdfviewer.debug, PID: 15693
                                                  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pdfviewer.debug/com.pdfviewer.FilePickerFragmentExtender}: android.view.InflateException: Binary XML file line #90: Binary XML file line #90: Error inflating class ImageButton
                                                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2684)
                                                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2751)
                                                      at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1496)
                                                      at android.os.Handler.dispatchMessage(Handler.java:102)
                                                      at android.os.Looper.loop(Looper.java:154)
                                                      at android.app.ActivityThread.main(ActivityThread.java:6186)
                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
                                                   Caused by: android.view.InflateException: Binary XML file line #90: Binary XML file line #90: Error inflating class ImageButton
                                                   Caused by: android.view.InflateException: Binary XML file line #90: Error inflating class ImageButton
                                                   Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 5: TypedValue{t=0x2/d=0x7f010031 a=-1}
                                                      at android.content.res.TypedArray.getColorStateList(TypedArray.java:528)
                                                      at android.widget.ImageView.<init>(ImageView.java:180)
                                                      at android.widget.ImageButton.<init>(ImageButton.java:84)
                                                      at android.widget.ImageButton.<init>(ImageButton.java:80)
                                                      at android.support.v7.widget.AppCompatImageButton.<init>(AppCompatImageButton.java:60)
                                                      at android.support.v7.widget.AppCompatImageButton.<init>(AppCompatImageButton.java:56)
                                                      at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:118)
                                                      at android.support.v7.app.AppCompatDelegateImplV9.createView(AppCompatDelegateImplV9.java:1026)
                                                      at android.support.v7.app.AppCompatDelegateImplV9.onCreateView(AppCompatDelegateImplV9.java:1083)
                                                      at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:192)
                                                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:769)
                                                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
                                                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
                                                      at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
                                                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
                                                      at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
                                                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
                                                      at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
                                                      at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
                                                      at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
                                                      at com.nononsenseapps.filepicker.AbstractFilePickerFragment.inflateRootView(AbstractFilePickerFragment.java:239)
                                                      at com.nononsenseapps.filepicker.AbstractFilePickerFragment.onCreateView(AbstractFilePickerFragment.java:165)
                                                      at android.support.v4.app.Fragment.performCreateView(Fragment.java:2239)
                                                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1332)
                                                      at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1574)
                                                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1641)
                                                      at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:794)
                                                      at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2415)
                                                      at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2200)
                                                      at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2153)
                                                      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2063)
                                                      at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388)
com.pdfviewer.debug E/AndroidRuntime:     at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:554)
                                                      at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
                                                      at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1249)
                                                      at android.app.Activity.performStart(Activity.java:6701)
                                                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2647)
                                                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2751)
                                                      at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1496)
                                                      at android.os.Handler.dispatchMessage(Handler.java:102)
                                                      at android.os.Looper.loop(Looper.java:154)
                                                      at android.app.ActivityThread.main(ActivityThread.java:6186)
                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)

I searched and found that it's related to the theme of the file-picker but also i didn't find anything wrong in the theme:

<style name="FilePickerTheme" parent="NNF_BaseTheme">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

    <!-- Setting a divider is entirely optional -->
    <item name="nnf_list_item_divider">?android:attr/listDivider</item>

    <!-- Need to set this also to style create folder dialog -->
    <item name="alertDialogTheme">@style/FilePickerAlertDialogTheme</item>
</style>

<style name="FilePickerAlertDialogTheme" parent="Theme.AppCompat.Dialog.Alert">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

colorss.xml:

<color name="colorPrimary">#3f51b5</color>
<color name="colorPrimaryDark">#303f9f</color>
<color name="colorAccent">#5495fd</color>

Solution

  • The problem was actually related to the theme I am applying to the parent activity of this fragment android:theme="@style/AppTheme" was causing the app to crash because the layout wasn't finding it's appropriate attributes and debugging xml is kinda tricky.

    The ImageButton in the resources:

    <ImageButton
                android:id="@+id/nnf_button_ok_newfile"
                // this style line is the cause
                style="?attr/borderlessButtonStyle"
                android:layout_width="48dp"
                android:layout_height="48dp"
                android:hint="@android:string/ok"
                app:srcCompat="@drawable/nnf_ic_save_black_24dp"
                android:tint="?attr/nnf_save_icon_color"/>
    

    and the solution to this problem was to either change your Activity theme in the manifest to android:theme="@style/FilePickerTheme" which is bad for user experience to user different themes between activities, or the other solution which is to Override the onCreate method and set the theme before the creation of the activity happens as follows: FilteredFilePickerFragment

    @Override
    public void onCreate(Bundle savedInstanceState) {
        getActivity().setTheme(R.style.FilePickerTheme);
        super.onCreate(savedInstanceState);
    }