二进制 XML 文件行 #8:二进制 XML 文件行 #8:错误膨胀 class <unknown>

Binary XML file line #8: Binary XML file line #8: Error inflating class <unknown>

我在尝试打开警告对话框时遇到以下错误;

android.view.InflateException: Binary XML file line #8: Binary XML file line #8: Error inflating class <unknown>
    Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class <unknown>
    Caused by: java.lang.reflect.InvocationTargetException

这都是以前的工作,我将 android:textColor="?attr/colorText" 添加到 TextView 以方便主题偏好。我将它与我最后知道的工作版本进行了比较,xml 是相同的。

06-22 13:25:36.391 637-637/ca.rvogl.tpbcui E/AndroidRuntime: FATAL EXCEPTION: main
    Process: ca.rvogl.tpbcui, PID: 637
    android.view.InflateException: Binary XML file line #8: Binary XML file line #8: Error inflating class <unknown>
    Caused by: android.view.InflateException: Binary XML file line #8: 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:645)
        at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
        at android.view.LayoutInflater.onCreateView(LayoutInflater.java:717)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:785)
        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.inflate(LayoutInflater.java:518)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:377)
        at ca.rvogl.tpbcui.views.MainActivity.showLeagueDialog(MainActivity.java:202)
        at ca.rvogl.tpbcui.views.MainActivity.access[=15=]0(MainActivity.java:35)
        at ca.rvogl.tpbcui.views.MainActivity.onClick(MainActivity.java:95)
        at android.view.View.performClick(View.java:5637)
        at android.view.View$PerformClick.run(View.java:22429)
        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:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
     Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 5: TypedValue{t=0x2/d=0x7f030062 a=-1}
        at android.content.res.TypedArray.getColorStateList(TypedArray.java:528)
        at android.widget.TextView.<init>(TextView.java:1076)
        at android.widget.TextView.<init>(TextView.java:704)
        at android.widget.TextView.<init>(TextView.java:700)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:430) 
        at android.view.LayoutInflater.createView(LayoutInflater.java:645) 
        at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58) 
        at android.view.LayoutInflater.onCreateView(LayoutInflater.java:717) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:785) 
        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.inflate(LayoutInflater.java:518) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:426) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:377) 
        at ca.rvogl.tpbcui.views.MainActivity.showLeagueDialog(MainActivity.java:202) 
        at ca.rvogl.tpbcui.views.MainActivity.access[=15=]0(MainActivity.java:35) 
        at ca.rvogl.tpbcui.views.MainActivity.onClick(MainActivity.java:95) 
        at android.view.View.performClick(View.java:5637) 
        at android.view.View$PerformClick.run(View.java:22429) 
        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:6119) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

我在下面附上了我的 MainActivity 的代码;

public class MainActivity extends AppCompatActivity {

    private LeagueAdapter mAdapter;
    private List<League> leaguesList = new ArrayList<>();
    private CoordinatorLayout coordinatorLayout;
    private RecyclerView recyclerView;
    private TextView noLeaguesView;

    private static final String PREFS_NAME = "prefs";
    private static final String PREF_BLUE_THEME = "blue_theme";
    private static final String PREF_GREEN_THEME = "green_theme";
    private static final String PREF_ORANGE_THEME = "purple_theme";
    private static final String PREF_RED_THEME = "red_theme";
    private static final String PREF_YELLOW_THEME = "yellow_theme";

    private DatabaseHelper db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //Use Chosen Theme
        SharedPreferences preferences = getSharedPreferences( PREFS_NAME, MODE_PRIVATE );
        boolean useBlueTheme = preferences.getBoolean( PREF_BLUE_THEME, false );
        if (useBlueTheme) {
            setTheme( R.style.AppTheme_Blue_NoActionBar );
        }
        boolean useGreenTheme = preferences.getBoolean( PREF_GREEN_THEME, false );
        if (useGreenTheme) {
            setTheme( R.style.AppTheme_Green_NoActionBar );
        }
        boolean useOrangeTheme = preferences.getBoolean( PREF_ORANGE_THEME, false );
        if (useOrangeTheme) {
            setTheme( R.style.AppTheme_Orange_NoActionBar );
        }
        boolean useRedTheme = preferences.getBoolean( PREF_RED_THEME, false );
        if (useRedTheme) {
            setTheme( R.style.AppTheme_Red_NoActionBar );
        }
        boolean useYellowTheme = preferences.getBoolean( PREF_YELLOW_THEME, false );
        if (useYellowTheme) {
            setTheme( R.style.AppTheme_Yellow_NoActionBar );
        }

        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        coordinatorLayout = findViewById(R.id.coordinator_layout);
        recyclerView = findViewById(R.id.recycler_view);
        noLeaguesView = findViewById(R.id.empty_leagues_view);

        db = new DatabaseHelper(this);

        leaguesList.addAll(db.getAllLeagues());

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.add_league_fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showLeagueDialog(false, null, -1);
            }
        });

        mAdapter = new LeagueAdapter(this, leaguesList);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL, 16));
        recyclerView.setAdapter(mAdapter);

        toggleEmptyLeagues();

        //On Long Click On The RecyclerView Item An Alert Dialog Is Opened With The Option To Choose Edit/Delete
        recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this,
                recyclerView, new RecyclerTouchListener.ClickListener() {
            @Override
            public void onClick(View view, final int position) {

                int leagueId = leaguesList.get(position).getId();
                Intent myIntent = new Intent(MainActivity.this, BowlerActivity.class);
                myIntent.putExtra("leagueId", leagueId);
                startActivity(myIntent);
             }

            @Override
            public void onLongClick(View view, int position) {
                showActionsDialog(position);
            }
        }));
    }

    //Inserting New League In The Database And Refreshing The List
    private void createLeague(String league) {

        //Inserting League In Database And Getting Newly Inserted League Id
        long id = db.insertLeague(league);

        //Get The Newly Inserted League From The Database
        League n = db.getLeague(id);

        if (n != null) {
            //Adding New League To The Array List At Position 0
            leaguesList.add(0, n);

            //Refreshing The List
            mAdapter.notifyDataSetChanged();

            toggleEmptyLeagues();
        }
    }

    //Updating League In The Database And Updating The Item In The List By Its Position
    private void updateLeague(String name, int position) {
        League n = leaguesList.get(position);

        //Updating League Text
        n.setName(name);

        //Updating The League In The Database
        db.updateLeague(n);

        //Refreshing The List
        leaguesList.set(position, n);
        mAdapter.notifyItemChanged(position);

        toggleEmptyLeagues();
    }

    //Deleting League From SQLite Database And Removing The League Item From The List By Its Position
    private void deleteLeague(int position) {

        //Deleting The League From The Database
        db.deleteLeague(leaguesList.get(position));

        //Removing League From The List
        leaguesList.remove(position);
        mAdapter.notifyItemRemoved(position);

        toggleEmptyLeagues();
    }

    //Opens Dialog With Edit/Delete Options
    //Edit - 0
    //Delete - 0
    private void showActionsDialog(final int position) {
        CharSequence colors[] = new CharSequence[]{"Edit", "Delete"};

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Choose option");
        builder.setItems(colors, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (which == 0) {
                    showLeagueDialog(true, leaguesList.get(position), position);
                } else {
                    deleteLeague(position);
                }
            }
        });
        builder.show();
    }

    //Show Alert Dialog With EditText Options to Enter/Edit A League
    //When shouldUpdate = true, It Will Automatically Display Old League Name And Change The Button Text To UPDATE
    private void showLeagueDialog(final boolean shouldUpdate, final League league, final int position) {
        LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
        View view = layoutInflaterAndroid.inflate(R.layout.dialog_league, null);

        AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(MainActivity.this);
        alertDialogBuilderUserInput.setView(view);

        final EditText inputLeague = view.findViewById(R.id.etLeagueNameInput);
        TextView dialogTitle = view.findViewById(R.id.dialog_title);
        dialogTitle.setText(!shouldUpdate ? getString(R.string.lbl_new_league_title) : getString(R.string.lbl_edit_league_title));

        if (shouldUpdate && league != null) {
            inputLeague.setText(league.getName());
        }
        alertDialogBuilderUserInput
                .setCancelable(false)
                .setPositiveButton(shouldUpdate ? "update" : "save", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialogBox, int id) {

                    }
                })
                .setNegativeButton("cancel",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialogBox, int id) {
                                dialogBox.cancel();
                            }
                        });

        final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
        alertDialog.show();

        alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //Show Toast Message When No Text Is Entered
                if (TextUtils.isEmpty(inputLeague.getText().toString())) {
                    Toast.makeText(MainActivity.this, "Enter League!", Toast.LENGTH_SHORT).show();
                    return;
                } else {
                    alertDialog.dismiss();
                }

                //Check If User Is Updating League
                if (shouldUpdate && league != null) {
                    // update note by it's id
                    updateLeague(inputLeague.getText().toString(), position);
                } else {
                    // create new note
                    createLeague(inputLeague.getText().toString());

                }
            }
        });
    }

    //Toggling List And Empty League View
    private void toggleEmptyLeagues() {
        // you can check notesList.size() > 0

        if (db.getLeaguesCount() > 0) {
            noLeaguesView.setVisibility( View.GONE);
        } else {
            noLeaguesView.setVisibility( View.VISIBLE);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate( R.menu.menu_main, menu );
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            Intent intent = new Intent(this, SettingsActivity.class);
            startActivity(intent);
            return true;
        }
        return super.onOptionsItemSelected( item );
    }
}

这是对话框的 xml 布局;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:padding="10dp">

    <TextView
        android:id="@+id/dialog_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="sans-serif-medium"
        android:lineSpacingExtra="8sp"
        android:text="@string/lbl_new_league_title"
        android:textColor="?attr/colorText" />
    <TextView
        android:id="@+id/tvLeagueMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/new_league_message"
        android:textColor="?attr/colorText"
        android:textSize="14sp" />
    <EditText
        android:id="@+id/etLeagueNameInput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/league_hint"
        android:textColor="?attr/colorText"
        android:inputType="text"
        android:textSize="14sp">
    </EditText>

</LinearLayout>

我不知道是什么原因造成的。似乎没有任何格式错误 xml。非常感谢任何追踪此错误的帮助。

如果有人有类似的问题,我可以在下面的庄园中解决这个问题。

我正试图用以下代码扩充我的对话框: View view = layoutInflaterAndroid.inflate(R.layout.dialog_league, null) 在我添加主题首选项代码之前效果很好。

而不是使用:layoutInflaterAndroid.inflate(R.layout.dialog_league, null);

我用过:View.inflate(this, R.layout.dialog_league, null)

这一代码更改解决了我几天来遇到的一个问题。

我只是通过以下 post 才明白这一点; android.view.InflateException: Binary XML file line #12: Error inflating class <unknown>

我遇到了同样的问题。 getApplicationContext() 使用它代替 {activityname}.this