Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The Activity's LayoutInflater already has a Factory installed so we can not install AppCompat's

I'm using AppCompat library (com.android.support:appcompat-v7:22.1.0) in my app. I created an ActionBar in a fragment. When I click in a menu item it shows an Alert Dialog. Here is my code:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
        case R.id.action_new:
            showFilterDialog();
            return true;
        case R.id.action_send:
            new sendInventoryTask().execute();
            return true;           
        default:
            return super.onOptionsItemSelected(item);
    }
}

And my showInventoryDialog method:

private void showFilterInventoryDialog() {
    AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());

    LayoutInflater inflater= getActivity().getLayoutInflater();

    View v = inflater.inflate(R.layout.dialog_filter_inventory,null);
    alert.setView(v);
    alert.setTitle(getResources().getString(R.string.filters));
    alert.setPositiveButton(getResources().getString(R.string.filter), new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            // TODO
        }

    });

    alert.setNegativeButton(getResources().getString(R.string.cancel), null);
    alert.show();
}

Everything works fine, but when I click on menu item, the logcat shows me an error:

I/AppCompatDelegate﹕ The Activity's LayoutInflater already has a Factory installed so we can not install AppCompat's

How to solve this?

like image 404
aseolin Avatar asked Jul 28 '15 13:07

aseolin


2 Answers

From what I can tell, appcompat 23.1.1 calls installViewFactory() in AppCompatDelegateImplV7 every time you show a dialog created by AlertDialog.Builder.

Call Stack:

at android.support.v7.app.AppCompatDelegateImplV7.installViewFactory(AppCompatDelegateImplV7.java:970) at android.support.v7.app.AppCompatDialog.onCreate(AppCompatDialog.java:58) at android.support.v7.app.AlertDialog.onCreate(AlertDialog.java:239) at android.app.Dialog.dispatchOnCreate(Dialog.java:361) at android.app.Dialog.show(Dialog.java:262) at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:902)

    @Override
    public void installViewFactory() {
        LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        if (layoutInflater.getFactory() == null) {
            LayoutInflaterCompat.setFactory(layoutInflater, this);
        } else {
            Log.i(TAG, "The Activity's LayoutInflater already has a Factory installed"
                    + " so we can not install AppCompat's");
        }
    }

As you can see, once the factory is already set it just logs the informational message. It seems pretty safe to ignore, but it can get annoying when it fills up your logs.

like image 171
Hugh Jeffner Avatar answered Nov 04 '22 23:11

Hugh Jeffner


You are required to use the themed context in this case, i.e. instead of

new AlertDialog.Builder(getActivity());

you have to do

new AlertDialog.Builder(getSupportActionBar().getThemedContext());

Besides, you also need to follow the parent theme and windowActionBar tip given here - support.v7.app.AlertDialog throws NullPointerException on dismiss

like image 6
Shan Avatar answered Nov 05 '22 01:11

Shan