2017-06-09 8 views
1

Androidビューから継承元を作成して以来、よくエラーBinary XML file line XX: Error inflating classが表示されます。この特殊なケースでは、BottomSheetとなります。バイナリXMLファイルの行XX:Error inflating class BottomSheetを継承するとき

public class MyBottomSheet extends TableLayout { 

    BottomSheetBehavior myBottomSheetBehavior; 
    ImageView testImageView; 

    public MyBottomSheet(Context context, AttributeSet attributeSet) { 
     super(context, attributeSet); 

     testImageView = (ImageView) findViewById(R.id.imageView); // still OK... 

     myBottomSheetBehavior = BottomSheetBehavior.from(this); // crashes Here 
     testImageView.setOnClickListener(onClickListener); // or here if to remove the previous row 

    } 

    // ... 
} 

私のアプリには、個別の断片を持つ複数のタブがあります。 BottomSheetには、そのうちの1つのみが必要ですが、BottomSheetをMainActivityマークアップに含めないと、移動しません。だから、コードは次のとおりです。

activity_main.xml

<?xml version="1.0"encoding="utf-8"?> 
<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/drawer_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fitsSystemWindows="true"> 

    <android.support.design.widget.CoordinatorLayout 
    android:id="@+id/coordinatorLayout" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <!-- ... --> 

     <include layout="@layout/my_bottom_sheet"/> 
    </android.support.design.widget.CoordinatorLayout> 
</android.support.v4.widget.DrawerLayout> 

my_bottom_sheet.xml

<?xml version="1.0" encoding="utf-8"?> 
<com.example.bottomsheettest.widgets.MyBottomSheet 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/myBottomSheet" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:stretchColumns="*" 
    tools:context="com.example.bottomsheettest.MainActivityFragment" 
    tools:showIn="@layout/activity_main"> 

    <TableRow> 
     <ImageView 
      android:id="@+id/imageView" 
      android:src="@mipmap/ic_launcher" 
      android:layout_height="wrap_content" 
      android:layout_width="wrap_content" 
      /> 
    </TableRow> 

</com.example.bottomsheettest.widgets.MyBottomSheet> 

MainActivityFragment.java

public class MainActivityFragment extends Fragment { 

    private static final int LAYOUT = R.layout.fragment_main; 
    private MainViewFAB fab; 
    private MyBottomSheet addNewItemToInboxBottomSheet; 

    public MainActivityFragment() { 

    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

     MainActivity activity = (MainActivity)getActivity(); 
     fab = activity.getMainViewFab(); 

     addNewItemToInboxBottomSheet = (MyBottomSheet) activity.findViewById(R.id.myBottomSheet); 

     return inflater.inflate(LAYOUT, container, false); 

    } 
} 

Android Viewsの継承に関して何か重要なことを忘れたと思います。しかし、この場合は特に奇妙です。 MyBottomSheetクラスでは、BottomSheetからImageViewを取得する際に問題はありません。したがって、それぞれのクラスからのBottomSheetへのアクセスが利用可能である。しかし、BottomSheetに関連するsomethigを操作しようとすると、例外が発生します。いくつかの答えを受け入れる時にアンドロイドStudioで作成


私はsource code(.zipファイル)を共有します。共有アプリにはタブはありませんが、元のアプリに存在するため、フラグメント構造を維持しました。

+0

'ImageView'の' setOnClickListener() '呼び出しは、コンストラクタのカスタム' View'にまだ追加されていないため、クラッシュします。代わりに 'onFinishInflate()'でそれを行うことができます。'BottomSheetBehavior'クラッシュのエラーは何ですか? –

+0

ああ、実際には、あなたのカスタム 'View'のコンストラクタに' LayoutParams'がまだセットされておらず、 'BottomSheetBehavior.from()'が 'IllegalArgumentException'をスローするので、クラッシュすると思います。あなたは 'onFinishInflate()'でもそうすることができます。 –

+0

@Mike M: 'BottomSheetBehavior'と' Listener'の両方でエラーがあります: 'android.view.InflateException:バイナリXMLファイル行#31'(はい、行番号まで同じです)。私は 'LayoutParams'についての理論をチェックし、再び書きます。 –

答えて

1

レイアウトから膨張させることを意味するViewサブクラスを作成すると、実行時にコンストラクタで利用できないことがいくつかあります。

あなたのカスタムのViewはレイアウトで定義されたViewがまだ膨張されていないため、findViewById()で参照を取得しようとするとnullが返されます。代わりに、これはonFinishInflate()より早く終了する必要があります。ImageView初期化をそのメソッドに移動すると、その特定のエラーが解決されます。

また、カスタムView自体はコンストラクタ内に独自のLayoutParamsが設定されていません。これは、BottomSheetBehavior.from()呼び出しの問題を引き起こしています。その方法は、を、Viewのレイアウト属性からの膨張中に構築されたLayoutParamsから単に取得するためです。 onAttachedToWindow()メソッドでは、LayoutParamsが設定されており、そこでBottomSheetBehavior.from()を呼び出すことができます。

最後に、何かがインフレに間違っているときはいつも、InflateExceptionが投げられると言います。失敗の根本的な原因はスタックトレースにさらにリストされますので、そこを参照してより適切な詳細を見つけてください。

+1

説明ありがとうございます!私は深い理解のためにそれが必要でした。 –

関連する問題