androidandroid-appbarlayout

Programmatically set AppBarLayout causes java.lang.IllegalArgumentException requiring Theme.AppCompat (or a descendant)


AppBarLayout causes:

java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant).

I've have already tried:

minSdk - 23, target - 28

Dependencies

implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
implementation 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
implementation 'androidx.transition:transition:1.2.0'
implementation 'androidx.percentlayout:percentlayout:1.0.0'
implementation 'com.google.android.gms:play-services-location:17.0.0'
implementation group: 'com.fasterxml', name: 'jackson-module-json-org', version: '0.9.1'

AndroidManifest.xml

<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/Descendant">
    <activity android:name="com.example.no_xml.MainActivity" android:theme="@style/Descendant">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

styles.xml

<resources>
<style name="AppBaseTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="colorPrimary">@color/stgWhite</item>
</style>
<style name="Descendant" parent="AppBaseTheme">
</style>

MainActivity

public class MainActivity extends AppCompatActivity {

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

private void setUpMainContainer(){
    getWindow().setStatusBarColor(getResources().getColor(R.color.stgTransparent, null));
    stgConstraintLayout mainLayout = new stgConstraintLayout(getApplicationContext());
    mainLayout.setFitsSystemWindows(true);
    setContentView(mainLayout);
    CoordinatorLayout mainCoordinator = new stgCoordinatorLayout(getApplicationContext());
    FrameLayout bottomNaviContainer = new stgFrameLayout(getApplicationContext());
    mainLayout.addView(mainCoordinator, 0);
    mainLayout.addView(bottomNaviContainer, 1);
    ConstraintSet set = new ConstraintSet();
    set.clone(mainLayout);
    set.connect(bottomNaviContainer.getId(), ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM);
    set.connect(bottomNaviContainer.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START);
    set.connect(bottomNaviContainer.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END);
    set.connect(mainCoordinator.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP);
    set.connect(mainCoordinator.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START);
    set.connect(mainCoordinator.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END);
    set.connect(mainCoordinator.getId(), ConstraintSet.BOTTOM, bottomNaviContainer.getId(), ConstraintSet.TOP);
    set.applyTo(mainLayout);
}}

Calling AppBarLayout

public class stgCoordinatorLayout extends CoordinatorLayout {
public stgCoordinatorLayout(@NonNull Context context) {
    super(context);
    setupLayout(context);
}

public stgCoordinatorLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    setupLayout(context);
}

public stgCoordinatorLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    setupLayout(context);
}

private void setupLayout(Context context){
    CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams(
            LayoutParams.MATCH_PARENT,
            0
    );
    params.setBehavior(new AppBarLayout.ScrollingViewBehavior());
    setLayoutParams(params);
    setBackgroundColor(context.getResources().getColor(R.color.stgWhite, null));
    setId(View.generateViewId());

    ViewPager viewPager = new stgViewPager(context);
    addView(viewPager, 0);
    viewPager.requestLayout();
    AppBarLayout appBarLayout = new stgAppBar(context);
    addView(appBarLayout, 1);
}}

AppBarLayout itself

public class stgAppBar extends AppBarLayout {
public stgAppBar(Context context) {
    super(context);
    setupLayout(context);
}

public stgAppBar(Context context, AttributeSet attrs) {
    super(context, attrs);
    setupLayout(context);
}

private void setupLayout(Context context){
    AppBarLayout.LayoutParams params = new AppBarLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            setDP(context, 150)

    );
    setLayoutParams(params);
    setElevation(0);
    setFitsSystemWindows(true);
    setBackgroundColor(context.getResources().getColor(R.color.stgWhite, null));
    setId(View.generateViewId());
}}

Solution

  • You're using getApplicationContext(), which does not have an AppCompat theme (or any theme at all). Use this instead to use your Activity as your Context object.

    stgConstraintLayout mainLayout = new stgConstraintLayout(this);