I have currently coded an app that uses the newer AndroidX library, which runs perfectly fine on an emulator running an SDK version of 29 and higher, however, when I try to run the same app on an emulator running SDK version 28 and lower, I get the following error message:
android.view.InflateException: Binary XML file line #17: Binary XML file line #17: Error inflating class androidx.appcompat.widget.Toolbar
Does this mean that by going to AndroidX I have closed off my chances of allowing this app to run on older devices? Or is this error showing up for different reasons? If is it because of the library change, is there by any chance I can get some advice as to how I could make my app compatible with some of the older SDKs. I'll gladly post any required code to give further clarity.
Edit
I added whatever I though could reproduce the error, as well as removed some of the database related code (you'll see the imports but not the code). It seems to have a problem for when it reaches the line setContentView(R.layout.activity_main) in the MainActivity.java. Essentially all I have provided is a basic NavigationDrawer setup.
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.fabricanddecor">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:configChanges="orientation|screenSize"
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java
package com.example.fabricanddecor;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.drawerlayout.widget.DrawerLayout;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import com.example.fabricanddecor.inventory.category.InventoryCategoryFragment;
import com.example.fabricanddecor.model.Sale;
import com.example.fabricanddecor.profile.ProfileMainFragment;
import com.example.fabricanddecor.reports.ReportMainFragment;
import com.example.fabricanddecor.sale.category.SaleCategoryFragment;
import com.example.fabricanddecor.suppliers.SupplierMainFragment;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.navigation.NavigationView;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreSettings;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import com.google.gson.Gson;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
private ImageView profilePicture;
private NavigationView navigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
profilePicture = findViewById(R.id.profile_picture);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = findViewById(R.id.drawer_layout);
navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId())
{
case R.id.nav_sale:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SaleCategoryFragment()).addToBackStack("SaleCategory").commit();
break;
case R.id.nav_inventory:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new InventoryCategoryFragment()).addToBackStack("InventoryCategory").commit();
break;
case R.id.nav_report:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ReportMainFragment()).addToBackStack("ReportMain").commit();
break;
case R.id.nav_suppliers:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SupplierMainFragment()).addToBackStack("SupplierMain").commit();
break;
}
drawer.close();
return true;
}
@Override
public void onBackPressed()
{
if (drawer.isOpen())
{
drawer.close();
}
else
{
super.onBackPressed();
}
}
public void profileClick(View view)
{
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileMainFragment()).addToBackStack("ProfileMain").commit();
drawer.close();
}
MainActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity"
tools:openDrawer="start">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/secondary_text_dark"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_drawer_header"
app:menu="@menu/nav_drawer_menu" />
</androidx.drawerlayout.widget.DrawerLayout>
Gradle (app)
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.example.fabricanddecor"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.hbb20:ccp:2.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.drawerlayout:drawerlayout:1.1.1'
implementation 'com.google.android.material:material:1.2.1'
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation 'com.google.firebase:firebase-firestore:21.6.0'
implementation 'com.google.firebase:firebase-storage:19.2.0'
implementation 'com.google.firebase:firebase-auth:19.4.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}