膨胀 CollapsingToolbarLayout 时出错

Posted

技术标签:

【中文标题】膨胀 CollapsingToolbarLayout 时出错【英文标题】:Error Inflating CollapsingToolbarLayout 【发布时间】:2016-09-20 01:34:53 【问题描述】:

我最近将支持设计库更新到最新版本,现在每个具有CollapsingToolbarLayout 的活动都会引发以下异常:

    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)

完整的错误日志如下:

java.lang.RuntimeException: Unable to start activity ComponentInfocom.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)

我似乎无法找到问题所在...

布局文件为:

`

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

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_
        android:layout_
        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_
            android:layout_
            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_
            android:layout_
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    </android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

<RelativeLayout
    android:layout_
    android:layout_
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <com.github.glomadrian.loadingballs.BallView
        android:id="@+id/ballView"
        android:layout_
        android:layout_
        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_
        android:layout_
        android:clipToPadding="false"
        android:visibility="gone"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_
            android:layout_
            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_
                android:layout_
                card_view:cardCornerRadius="0dip"
                card_view:cardElevation="2dip"
                card_view:cardPreventCornerOverlap="true">

                <LinearLayout
                    android:id="@+id/layout"
                    android:layout_
                    android:layout_
                    android:orientation="vertical"
                    android:padding="10dip">

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

                    <TextView
                        android:layout_
                        android:layout_
                        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_
                android:layout_
                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" />

`

活动代码为:

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();
        
    );

【问题讨论】:

首先编辑你的问题。 发布您的布局文件 提供发生此崩溃的 Activity/Fragment。 【参考方案1】:

找到解决方案。只需添加

app:statusBarScrim="@null"

到您的 CollapsingToolbarLayout

【讨论】:

谢谢。上下更改版本让我害怕;这是一个安全的解决方法。 非常感谢这个答案,它对我有用! 在我的 android 设备和使用 webhook 的 ios 设备中完美运行【参考方案2】:

我在这里回复了类似的帖子Error inflating class CollapsingToolbarLayout

我知道已经有一个可接受的答案,但它不起作用(或不再起作用)。

我花了几个小时研究这个错误,我想出的是这个。

首先,由于 Android Nougat 的初始版本也称为 Android 7.0 (API 24),compileSdkVersion 24 现在可用。为此,您必须更新您的 sdk。 Step 1

其次,是更新你的 gradle 文件(需要互联网连接)。 Step 2

同时更新 app.gradle 的这一部分

第三个(可选)清理项目,构建项目(都在构建选项卡下)

我希望这可以帮助那里的人并节省几个小时的研究时间。

干杯/快乐编码

希望对你有帮助。

【讨论】:

更新 SDK (Android Nougat) 并更改 build.gradle 文件,因为设置 API 24 正在工作,因为它从 collapsingtoolbar 布局中删除了“Error inflating class CollapsingToolbarLayout”错误。 很高兴它能帮到你。【参考方案3】:

原来我有另一个依赖项,它有一个冲突的支持库。当我删除依赖项时,项目成功构建并运行。

【讨论】:

你是怎么调试的? @TylerPfaff 我尝试更新我拥有的 v4 支持库的版本,但崩溃日志显示的库版本与我拥有的完全不同。然后,我检查了所有依赖项,看看哪些依赖项还可能包含他们自己的支持库版本并删除了它们。 @TylerPfaff 使用 gradlew app:dependencies 显示一个依赖树,可以帮助找到不一致的版本 哇哦,我认为它有效。这可能是一个大问题,因为依赖关系可能是应用程序的重要组成部分,仅仅为了解决这样的问题而删除它是令人失望的。我认为需要为构建依赖项和发布设置一些标准。人们可以在建立依赖关系方面做得更好,以避免这种冲突情况。【参考方案4】:

尝试将所有支持库更新到 24.0.0-beta1 版本。然后再次cleanrebuildrun 你的项目。这有望解决您的问题。

【讨论】:

我已经更新了,但还是没有变化。错误仍然存​​在。 在什么设备上崩溃了?作为临时修复,您可以尝试按照 question 从 XML 中删除 app:contentScrim="?attr/colorPrimary" 我正在运行 Android 6.0.1 的 Nexus 6 上进行测试。即使我删除它,我仍然无法以编程方式设置它。【参考方案5】:

尝试将com.android.support:design 依赖项更新为与其他支持库相同的版本。 我刚刚在自己的项目中解决了这个问题。我没有在 build.gradle 中明确添加它,因为我使用了一个使用 support-design 库的库。 Gradle task androidDependencies 显示在其他库更新后支持设计仍然有较低的版本,所以我明确添加了它,它就像一个魅力。

【讨论】:

以上是关于膨胀 CollapsingToolbarLayout 时出错的主要内容,如果未能解决你的问题,请参考以下文章

金属相变过程的体积膨胀,金属热膨胀系数,计算公式是怎样的?

钢管的膨胀系数公式

在服务中膨胀视图时膨胀异常,而它在活动中正常膨胀

ansys里的热膨胀系数怎么设置

线膨胀系数是如何计算的

线膨胀系数是如何计算的