Error Inflating CollapsingToolbarLayout

Alex Kombo picture Alex Kombo · May 23, 2016 · Viewed 10.6k times · Source

I recently updated the support design library to the latest version and now every activity that has a CollapsingToolbarLayout throws the following exception:

    java.lang.NoSuchMethodError: No static method setLayoutDirection(Landroid/graphics/drawable/Drawable;I)V in class Landroid/support/v4/graphics/drawable/DrawableCompat; or its super classes (declaration of 'android.support.v4.graphics.drawable.DrawableCompat' appears in /data/data/com.radioafrica.music/files/instant-run/dex/slice-com.android.support-support-v4-24.0.0-beta1_f8cf3ba4c70f87f407a745b9fa14a2205d0b587c-classes.dex)

The full error log is as follows:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.radioafrica.music/com.radioafrica.music.activity.PlaylistTracks}: android.view.InflateException: Binary XML file line #31: Binary XML file line #31: Error inflating class android.support.design.widget.CollapsingToolbarLayout at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
    at android.app.ActivityThread.-wrap11(ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NoSuchMethodError: No static method setLayoutDirection(Landroid/graphics/drawable/Drawable;I)V in class Landroid/support/v4/graphics/drawable/DrawableCompat; or its super classes (declaration of 'android.support.v4.graphics.drawable.DrawableCompat' appears in /data/data/com.radioafrica.music/files/instant-run/dex/slice-com.android.support-support-v4-24.0.0-beta1_f8cf3ba4c70f87f407a745b9fa14a2205d0b587c-classes.dex) 
    at android.support.design.widget.CollapsingToolbarLayout.setStatusBarScrim(CollapsingToolbarLayout.java:663) 
    at android.support.design.widget.CollapsingToolbarLayout.<init>(CollapsingToolbarLayout.java:197) 
    at android.support.design.widget.CollapsingToolbarLayout.<init>(CollapsingToolbarLayout.java:132)                                                                         
    at java.lang.reflect.Constructor.newInstance(Native Method)                                                                          
    at android.view.LayoutInflater.createView(LayoutInflater.java:619)                                                                          
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764)                                                                          
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)                                                                          
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)                                                                          
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)                                                                          
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)                                                                          
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)                                                                          
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)                                                                          
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)                                                                          
    at android.view.LayoutInflater.inflate(LayoutInflater.java:515)                                                                         
    at android.view.LayoutInflater.inflate(LayoutInflater.java:423)                                                                          
    at android.view.LayoutInflater.inflate(LayoutInflater.java:374)                                                                          
    at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:280)                                                                          at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)

  I cant seem to find what the problem is...

The layout file is:

`

<android.support.design.widget.AppBarLayout
    android:id="@+id/app_bar_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        app:contentScrim="?attr/colorPrimary"
        app:expandedTitleMarginEnd="64dp"
        app:expandedTitleMarginStart="48dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <ImageView
            android:id="@+id/header"
            android:layout_width="match_parent"
            android:layout_height="280dip"
            android:fitsSystemWindows="true"
            android:scaleType="centerCrop"
            android:src="@drawable/no_cover"
            android:transitionName="avatar"
            app:layout_collapseMode="parallax" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    </android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <com.github.glomadrian.loadingballs.BallView
        android:id="@+id/ballView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center"
        android:layout_marginTop="150dip"
        lib:ball_colors="@array/color"
        lib:balls="5"
        lib:enable_size_animation="true"
        lib:max_ball_size="12dp"
        lib:min_ball_size="5dp"
        lib:movement_cycle_time="1500"
        lib:size_cycle_time="500" />

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/nestedScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:visibility="gone"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:card_view="http://schemas.android.com/apk/res-auto"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                card_view:cardCornerRadius="0dip"
                card_view:cardElevation="2dip"
                card_view:cardPreventCornerOverlap="true">

                <LinearLayout
                    android:id="@+id/layout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:padding="10dip">

                    <TextView
                        android:id="@+id/name"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textAppearance="@style/TextAppearance.AppCompat.Large"
                        android:textColor="#fff"
                        android:layout_marginBottom="10dip"
                        android:textStyle="bold" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:id="@+id/owner"
                        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
                        android:textColor="#e2e2e2" />
                </LinearLayout>

            </android.support.v7.widget.CardView>

            <com.radioafrica.music.view.ExpandableHeightListView
                android:id="@+id/top_tracks"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:divider="#90ffffff"
                android:dividerHeight="1dip"
                android:focusable="false"
                android:footerDividersEnabled="true"
                android:headerDividersEnabled="true" />

        </LinearLayout>

    </android.support.v4.widget.NestedScrollView>

</RelativeLayout>

<android.support.design.widget.FloatingActionButton
    android:id="@+id/floatingPlayButton"
    style="@style/FabStyle"
    app:layout_anchor="@id/app_bar_layout"
    app:layout_anchorGravity="bottom|right|end" />

<include layout="@layout/mini_player" />

`

The code for the activity is:

public class AlbumInfo extends AppCompatActivity implements AdapterView.OnItemClickListener, View.OnClickListener {

public static final String ALBUM = "album";

private ExpandableHeightListView expandableHeightListView;
private NestedScrollView nestedScrollView;
private ImageView header;
private BallView ballView;
private LinearLayout layout;
private LinearLayout miniPlayer;
private TextView title, artistTextView;
private ImageButton playPause;
private ImageView artwork;
private CollapsingToolbarLayout collapsingToolbarLayout;

ImageButton previous;
ImageButton next;
TextView name;
TextView owner;
FloatingActionButton fab;

String songTitle;
String singer;
String art;
boolean playing = false;

private ArrayList<Track> trackList;
private Album album;

@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(UIEvent uiEvent) {
    miniPlayer.setVisibility(View.VISIBLE);
    miniPlayer.setClickable(true);

    songTitle = uiEvent.title;
    singer = uiEvent.artist;
    art = uiEvent.art;
    playing = uiEvent.playing;

    togglePlayButtonState();

    updateViews();
}

private void updateViews() {
    Picasso.with(this).load(art).fit().centerCrop().placeholder(R.drawable.no_cover).error(R.drawable.no_cover).into(artwork);

    if (NakedGroove.getMediaType().equals(NakedGroove.RADIO)) {
        artistTextView.setText(Html.fromHtml(singer));
        title.setText(songTitle);
    } else {
        artistTextView.setText(singer);
        title.setText(songTitle);
    }
}

@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(TracksEvent tracksEvent) {
    trackList = tracksEvent.tracks;

    if (trackList.size() != 0) {
        ArtistTracksAdapter artistTracksAdapter = new ArtistTracksAdapter(AlbumInfo.this, R.layout.album_tracks_layout, trackList);
        expandableHeightListView.setAdapter(artistTracksAdapter);

        if (ballView != null) {
            ballView.setVisibility(View.GONE);
            nestedScrollView.setVisibility(View.VISIBLE);
        }
    }
}

private Target target = new Target() {

    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        header.setImageBitmap(bitmap);
        setColors(bitmap);
    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {
        Picasso.with(AlbumInfo.this).load(album.getAlbumArt()).into(target);
    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.no_cover);
        header.setImageBitmap(bitmap);
        setColors(bitmap);
    }
};

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    initActivityTransitions();
    setStatusBarColor();

    super.onCreate(savedInstanceState);
    setContentView(R.layout.album);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    assert getSupportActionBar() != null;
    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    album = getIntent().getParcelableExtra(ALBUM);

    fetchAlbumTracks(album.getId());

    expandableHeightListView = (ExpandableHeightListView) findViewById(R.id.top_tracks);
    nestedScrollView = (NestedScrollView) findViewById(R.id.nestedScrollView);
    header = (ImageView) findViewById(R.id.header);
    ballView = (BallView) findViewById(R.id.ballView);
    name = (TextView) findViewById(R.id.name);
    owner = (TextView) findViewById(R.id.owner);
    layout = (LinearLayout) findViewById(R.id.layout);
    fab = (FloatingActionButton) findViewById(R.id.floatingPlayButton);
    collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);

    title = (TextView) findViewById(R.id.title);
    artistTextView = (TextView) findViewById(R.id.artist);
    previous = (ImageButton) findViewById(R.id.notification_base_previous);
    playPause = (ImageButton) findViewById(R.id.notification_base_play);
    next = (ImageButton) findViewById(R.id.notification_base_next);
    artwork = (ImageView) findViewById(R.id.notification_base_image);
    miniPlayer = (LinearLayout) findViewById(R.id.mini_player);

    collapsingToolbarLayout.setTitle(album.getTitle());
    collapsingToolbarLayout.setExpandedTitleColor(getResources().getColor(android.R.color.transparent));

    owner.setText(album.getArtist());
    name.setText(album.getTitle());

    fab.setOnClickListener(this);
    fab.setRippleColor(getResources().getColor(R.color.app_theme_dark));

    miniPlayer.setOnClickListener(this);
    previous.setOnClickListener(this);
    next.setOnClickListener(this);
    playPause.setOnClickListener(this);

    expandableHeightListView.setExpanded(true);
    expandableHeightListView.setOnItemClickListener(this);

    if (album.getAlbumArt().length() != 0)
        Picasso.with(this).load(album.getAlbumArt()).into(target);
    else
        Picasso.with(this).load(R.drawable.no_cover).into(target);

    if (NakedGroove.isPlaying() || NakedGroove.isPaused()) {
        miniPlayer.setVisibility(View.VISIBLE);
        togglePlayButtonState();
    } else {
        miniPlayer.setVisibility(View.GONE);
    }
}

private void setStatusBarColor() {
    Window window = getWindow();
    if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21)
        window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    if (Build.VERSION.SDK_INT >= 21)
        getWindow().setStatusBarColor(getResources().getColor(android.R.color.transparent));
}

private void fetchAlbumTracks(String id) {
    startService(new Intent(this, RefresherService.class).setAction(RefresherService.FETCH_ALBUM_TRACKS).putExtra(RefresherService.ALBUM_ID, id));
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            super.onBackPressed();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

@Override
public void onPause() {
    super.onPause();
}

@Override
protected void onResume() {
    super.onResume();

    togglePlayButtonState();

    if (NakedGroove.getMediaType() != null && !NakedGroove.getMediaType().equals(NakedGroove.NOTHING)) {
        updateViews();
    }
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString(ALBUM, album.getTitle());
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    NakedGroove.setCurrentPlaylist(trackList);
    NakedGroove.setCurrentIndex(position);

    if (Build.VERSION.SDK_INT >= 16)
        startService(new Intent(this, PlayerService.class).setAction(PlayerService.ACTION_URL));
    else
        startService(new Intent(this, MusicService.class).setAction(MusicService.ACTION_URL));
}

private void playPauseMusic() {
    if (NakedGroove.isPlaying()) {
        if (Build.VERSION.SDK_INT >= 16)
            startService(new Intent(this, PlayerService.class).setAction(PlayerService.ACTION_PAUSE));
        else
            startService(new Intent(this, MusicService.class).setAction(MusicService.ACTION_PAUSE));
    } else {
        if (Build.VERSION.SDK_INT >= 16)
            startService(new Intent(this, PlayerService.class).setAction(PlayerService.ACTION_PLAY));
        else
            startService(new Intent(this, MusicService.class).setAction(MusicService.ACTION_PLAY));
    }
}

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.mini_player:
            startActivity(new Intent(this, MusicPlayer.class));
            break;
        case R.id.notification_base_play:
            playPauseMusic();
            break;
        case R.id.notification_base_next:
            if (Build.VERSION.SDK_INT >= 16)
                startService(new Intent(this, PlayerService.class).setAction(PlayerService.ACTION_SKIP));
            else
                startService(new Intent(this, MusicService.class).setAction(MusicService.ACTION_SKIP));
            break;
        case R.id.notification_base_previous:
            if (Build.VERSION.SDK_INT >= 16)
                startService(new Intent(this, PlayerService.class).setAction(PlayerService.ACTION_PREVIOUS));
            else
                startService(new Intent(this, MusicService.class).setAction(MusicService.ACTION_PREVIOUS));
            break;
        case R.id.floatingPlayButton:
            if (trackList.size() != 0) {
                NakedGroove.setCurrentPlaylist(trackList);
                NakedGroove.setCurrentIndex(0);

                if (Build.VERSION.SDK_INT >= 16)
                    startService(new Intent(this, PlayerService.class).setAction(PlayerService.ACTION_URL));
                else
                    startService(new Intent(this, MusicService.class).setAction(MusicService.ACTION_URL));
            }
            break;
    }
}

private void togglePlayButtonState() {
    if (playing) {
        playPause.setImageResource(R.drawable.ic_music_pause);
    } else {
        playPause.setImageResource(R.drawable.ic_music_play);
    }
}

private void initActivityTransitions() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        ChangeBounds transition = new ChangeBounds();
        transition.excludeTarget(android.R.id.statusBarBackground, true);
        getWindow().setEnterTransition(transition);
        getWindow().setReturnTransition(transition);
    }
}

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}

@Override
protected void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
protected void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

private void setColors(Bitmap bitmap) {
    Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
        @Override
        public void onGenerated(Palette palette) {
            if (palette.getVibrantSwatch() != null) {
                Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
                float[] vibrant = vibrantSwatch.getHsl();

                nestedScrollView.setBackgroundColor(Color.HSVToColor(vibrant));
                layout.setBackgroundColor(Color.HSVToColor(vibrant));
                collapsingToolbarLayout.setContentScrimColor(Color.HSVToColor(vibrant));
                collapsingToolbarLayout.setStatusBarScrimColor(Color.HSVToColor(vibrant));
            } else if (palette.getDarkVibrantSwatch() != null) {
                Palette.Swatch darkVibrantSwatch = palette.getDarkVibrantSwatch();
                float[] darkVibrant = darkVibrantSwatch.getHsl();

                nestedScrollView.setBackgroundColor(Color.HSVToColor(darkVibrant));
                layout.setBackgroundColor(Color.HSVToColor(darkVibrant));
                collapsingToolbarLayout.setContentScrimColor(Color.HSVToColor(darkVibrant));
                collapsingToolbarLayout.setStatusBarScrimColor(Color.HSVToColor(darkVibrant));
            } else if (palette.getDarkMutedSwatch() != null) {
                Palette.Swatch darkMutedSwatch = palette.getDarkMutedSwatch();
                float[] darkMuted = darkMutedSwatch.getHsl();

                nestedScrollView.setBackgroundColor(Color.HSVToColor(darkMuted));
                layout.setBackgroundColor(Color.HSVToColor(darkMuted));
                collapsingToolbarLayout.setContentScrimColor(Color.HSVToColor(darkMuted));
                collapsingToolbarLayout.setStatusBarScrimColor(Color.HSVToColor(darkMuted));
            } else {
                nestedScrollView.setBackgroundColor(getResources().getColor(R.color.DeepGrey));
                layout.setBackgroundColor(getResources().getColor(R.color.DeepGrey));
                collapsingToolbarLayout.setContentScrimColor(getResources().getColor(R.color.DeepGrey));
                collapsingToolbarLayout.setStatusBarScrimColor(getResources().getColor(R.color.DeepGrey));
            }

            supportStartPostponedEnterTransition();
        }
    });
}

}

Answer

Igor picture Igor · Nov 6, 2016

Found solution. Just add

app:statusBarScrim="@null"

to your CollapsingToolbarLayout