Error inflating Class ImageView on RecyclerView

2019-06-01 02:08发布

问题:

I build an app with minimum SDK 15 and target 23, and I have different view in my RecyclerView. Apps works well on android version => 5.0 but crashes on android version < 5.0 with the following error message

Binary XML file line #159: Error inflating class ImageView at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) at android.view.LayoutInflater.rInflate(LayoutInflater.java:746) at android.view.LayoutInflater.rInflate(LayoutInflater.java:749) at android.view.LayoutInflater.rInflate(LayoutInflater.java:749) at android.view.LayoutInflater.rInflate(LayoutInflater.java:749) at android.view.LayoutInflater.inflate(LayoutInflater.java:489) at android.view.LayoutInflater.inflate(LayoutInflater.java:396) at com.shixxels.thankgodrichard.spotpopfinal.adapter.RecyclerAdapter.onCreateViewHolder(RecyclerAdapter.java:64) at com.shixxels.thankgodrichard.spotpopfinal.adapter.RecyclerAdapter.onCreateViewHolder(RecyclerAdapter.java:27) at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:5833) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5057) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4967) at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2029) at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1414) at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1377) at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:578) at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3315) at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3124) at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3568) at android.view.View.layout(View.java:14008) at android.view.ViewGroup.layout(ViewGroup.java:4373) at android.widget.FrameLayout.onLayout(FrameLayout.java:448) at android.view.View.layout(View.java:14008) at android.view.ViewGroup.layout(ViewGroup.java:4373) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663) at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1652) at android.widget.LinearLayout.onLayout(LinearLayout.java:1436) at android.view.View.layout(View.java:14008) at android.view.ViewGroup.layout(ViewGroup.java:4373) at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1021) at android.view.View.layout(View.java:14008) at android.view.ViewGroup.layout(ViewGroup.java:4373) at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:131) at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42) at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1364) at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:852) at android.view.View.layout(View.java:14008) at android.view.ViewGroup.layout(ViewGroup.java:4373) at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1197) at android.view.View.layout(View.java:14008) at android.view.ViewGroup.layout(ViewGroup.java:4373) at android.widget.FrameLayout.onLayout(FrameLayout.java:448) at android.view.View.layout(View.java:14008) at android.view.ViewGroup.layout(ViewGroup.java:4373) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521) at android.widget.LinearLayout.onLayout(LinearLayout.java:1434) at android.view.View.layout(View.java:14008) at android.view.ViewGroup.layout(ViewGroup.java:4373) at android.widget.FrameLayout.onLayout(FrameLayout.java:448) at android.view.View.layout(View.java:14008) at android.view.ViewGroup.layout(ViewGroup.java:4373) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521) at android.widget.LinearLayout.onLayout(LinearLayout.java:1434) at android.view.View.layout(View.java:14008) at android.view.ViewGroup.layout(ViewGr

And below is my the code for my RecyclerAdapter:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> { // line 27

    private static final int Image_digit = 1;
    private static final int Map_digit = 2;
    private static final int Text_digit = 3;
    private Context context;




    private List<FeedAdapter> mDataList;
    private LayoutInflater inflater;

    public RecyclerAdapter(Context context, List<FeedAdapter> data) {
        inflater = LayoutInflater.from(context);
        this.mDataList = data;
        this.context = context;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {  // Create the Prime and Non-Prime row Layouts

            case Image_digit:

                ViewGroup imageView = (ViewGroup) inflater.inflate(R.layout.list_item, parent, false);
                MyViewHolder_Images holderPrime = new MyViewHolder_Images(imageView);
                return holderPrime;

            case Map_digit:

                ViewGroup mapView = (ViewGroup) inflater.inflate(R.layout.list_item_map, parent, false);
                MyViewHolder_Map holderNonPrime = new MyViewHolder_Map(mapView);
                return holderNonPrime;

            default:

                ViewGroup defaultRow = (ViewGroup) inflater.inflate(R.layout.list_item_text, parent, false); // line 64
                MyViewHolder_Text holderDefault = new MyViewHolder_Text(defaultRow);
                return holderDefault;
        }
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        FeedAdapter current = mDataList.get(position);

        switch (holder.getItemViewType()) {

            case Image_digit:

                MyViewHolder_Images holder_prime = (MyViewHolder_Images) holder;
                holder_prime.setData(current);

                break;

            case Map_digit:

                MyViewHolder_Map holder_not_prime = (MyViewHolder_Map) holder;
                holder_not_prime.setData(current);

                break;
            default:
                MyViewHolder_Text holder_not_text = (MyViewHolder_Text) holder;
                holder_not_text.setData(current);
                break;
        }
    }

    @Override
    public int getItemCount() {
        return mDataList.size();
    }

    @Override // This will help us to determine ROW TYPE : i.e. the PRIME or NON-PRIME row.
    public int getItemViewType(int position) {

        FeedAdapter feedAdapter = mDataList.get(position);
        if (feedAdapter.getViewInt() == 1)
            return Image_digit;
        else if (feedAdapter.getViewInt() == 2){
            return Map_digit;
        }
        else if (feedAdapter.getViewInt() == 3){
            return Text_digit;
        }
        else {
            return 0;
        }

    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        public MyViewHolder(View itemView) {
            super(itemView);
        }
    }

    // Holder class for Images rows
    public class MyViewHolder_Images extends MyViewHolder implements View.OnClickListener {

        TextView title;
        ImageView imgThumb, imgRowType, menu;

        public MyViewHolder_Images(View itemView) {
            super(itemView);
            title = (TextView) itemView.findViewById(R.id.tvTitle);
            imgThumb = (ImageView) itemView.findViewById(R.id.img_row);
            imgRowType = (ImageView) itemView.findViewById(R.id.img_row2);
            menu   = (ImageView) itemView.findViewById(R.id.img_row_delete);
        }

        public void setData(final FeedAdapter current) {
            this.title.setText(current.getTitle());
            this.imgThumb.setImageResource(current.getImageID());
            this.imgRowType.setImageResource(R.drawable.thumb_1_4);
            this.menu.setOnClickListener(MyViewHolder_Images.this);
            this.imgThumb.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    showImage(current.getImageID());
                }
            });


        }
        @Override
        public void onClick(View v) {
            Log.i("onClick"," i was clicked");
            openDialog();

        }
    }

    // Holder class for maps rows
    public class MyViewHolder_Map extends MyViewHolder implements View.OnClickListener {

        TextView title;
        ImageView imgThumb, imgRowType, menu;

        public MyViewHolder_Map(View itemView) {
            super(itemView);
            title = (TextView) itemView.findViewById(R.id.tvTitle);
            imgThumb = (ImageView) itemView.findViewById(R.id.img_row);
            imgRowType = (ImageView) itemView.findViewById(R.id.img_row2);
            menu   = (ImageView) itemView.findViewById(R.id.img_row_delete);
        }

        public void setData(final FeedAdapter current) {
            this.title.setText(current.getTitle());
            this.imgThumb.setImageResource(current.getImageID());
            this.imgRowType.setImageResource(R.drawable.thumb_1_4);
            this.menu.setOnClickListener(MyViewHolder_Map.this);
            this.imgThumb.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    showImage(current.getImageID());
                }
            });


        }
        @Override
        public void onClick(View v) {
            Log.i("onClick","i was clicked");
            openDialog();





        }
    }
    // Holder class for NON-Text rows
    public class MyViewHolder_Text extends MyViewHolder implements View.OnClickListener {

        TextView title;
        ImageView imgThumb, menu;

        public MyViewHolder_Text(View itemView) {
            super(itemView);
            title = (TextView) itemView.findViewById(R.id.tvTitle);
            imgThumb = (ImageView) itemView.findViewById(R.id.img_row);
            menu   = (ImageView) itemView.findViewById(R.id.img_row_delete);

        }

        public void setData(final FeedAdapter current) {
            this.title.setText(current.getTitle());
            this.imgThumb.setImageResource(current.getImageID());
            this.menu.setOnClickListener(MyViewHolder_Text.this);
            this.imgThumb.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    showImage(current.getImageID());
                }
            });

        }
        @Override
        public void onClick(View v) {
            Log.i("onClick","i was clicked");
            openDialog();



        }}


    public void openDialog() {
        final Dialog dialog = new Dialog(context);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        LinearLayout.LayoutParams dialogParams = new LinearLayout.LayoutParams(
                400, 256);//set height and width here, ie (width,height)

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View dislogView = inflater
                .inflate(R.layout.feed_menu, null);
        dialog.setContentView(dislogView, dialogParams);
        // set the custom dialog components - text, image and button
        TextView text = (TextView) dialog.findViewById(R.id.text);


        TextView dialogButton = (TextView) dialog.findViewById(R.id.report);
        // if button is clicked, close the custom dialog
        dialogButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

        dialog.show();
    }

    public void showImage(int imageUri) {
        Dialog builder = new Dialog(context);
        builder.requestWindowFeature(Window.FEATURE_NO_TITLE);
        builder.getWindow().setBackgroundDrawable(
                new ColorDrawable(android.graphics.Color.TRANSPARENT));
        builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialogInterface) {
                //nothing;
            }
        });

        ImageView imageView = new ImageView(context);
        imageView.setImageResource(imageUri);
        builder.addContentView(imageView, new RelativeLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT));
        builder.show();
    }
}

list_item_text.xml

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:layout_marginTop="5dp"
    card_view:cardCornerRadius="5dp">

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

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/white"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/img_row"
                android:layout_width="55dp"
                android:layout_height="57.3dp"
                android:scaleType="fitXY"
                android:layout_margin="7dp"
                android:src="@drawable/thumb_1_0"/>

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:orientation="vertical">
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:layout_marginTop="4dp">
                    <TextView
                        android:id="@+id/tvTitle"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/title"
                        android:textColor="#000000"
                        android:textSize="12sp"
                        android:textStyle="bold"/>
                    <TextView
                        android:id="@+id/tv_user_tag"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/tag"
                        android:textColor="#616161"
                        android:textSize="9sp"
                        android:layout_marginLeft="5dp" />

                </LinearLayout>

                <TextView
                    android:id="@+id/tvDescription"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/description"
                    android:layout_marginTop="2dp"
                    android:layout_marginBottom="2dp"
                    android:textSize="9sp"
                    android:textStyle="italic"/>
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">

                    <View
                        android:layout_width="1dp"
                        android:layout_height="fill_parent"
                        android:background="#FF0000FF" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="5dp"
                        android:text="@string/lorem"
                        android:maxLines="2"
                        android:ellipsize="end"/>

                </LinearLayout>

            </LinearLayout>

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

                <ImageView
                    android:id="@+id/img_row_delete"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:layout_margin="7dp"
                    android:contentDescription="@string/delete_image"
                    android:src="@drawable/more"
                    android:tint="@color/colorPrimary"
                    android:clickable="true" />

            </LinearLayout>

        </LinearLayout>

        <View
            android:layout_width="fill_parent"
            android:layout_marginTop="5dp"
            android:layout_marginLeft="6.3dp"
            android:layout_marginRight="6.3dp"
            android:layout_height="1dp"
            android:background="@color/colorPrimary" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/time_of_post"
                android:text="about 5 min. ago"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="7dp"/>
            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="45dp"
                android:layout_marginRight="10dp"
                android:layout_marginTop="3dp">

                <ImageView
                    android:layout_width="20dp"
                    android:id="@+id/comment_count_img"
                    android:src="@drawable/comment_count"
                    android:layout_height="20dp"
                    android:layout_marginRight="3dp"
                    android:layout_toLeftOf="@+id/comment_count_no"
                    android:clickable="true" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/comment_count_no"
                    android:text="10"
                    android:layout_toLeftOf="@+id/comment_like_img"
                    android:layout_marginRight="5dp"/>

                <ImageView
                    android:layout_width="20dp"
                    android:id="@+id/comment_like_img"
                    android:src="@drawable/like_count"
                    android:layout_marginLeft="6.7dp"
                    android:layout_height="20dp"
                    android:layout_toLeftOf="@+id/comment_like_no"
                    android:layout_marginRight="3dp"
                    android:clickable="true" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/comment_like_no"
                    android:text="10"
                    android:layout_toLeftOf="@+id/comment_dislike_img"
                    android:layout_marginRight="5dp"/>

                <ImageView
                    android:layout_width="20dp"
                    android:id="@+id/comment_dislike_img"
                    android:src="@drawable/thumbs_down"
                    android:layout_height="20dp"
                    android:layout_marginLeft="6.7dp"
                    android:layout_toLeftOf="@+id/comment_dislike_no"
                    android:layout_marginRight="3dp"
                    android:clickable="true" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/comment_dislike_no"
                    android:text="10"
                    android:layout_alignParentRight="true"/>

            </RelativeLayout>

        </LinearLayout>

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

build.gradle

apply plugin: 'com.android.application'
android {
    compileSdkVersion 24
    buildToolsVersion "24.0.2"

    defaultConfig {
        applicationId "com.shixxels.thankgodrichard.spotpopfinal"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    dexOptions {
        javaMaxHeapSize "4g"
    }
}

回答1:

If you use vectors icon as background in your ImageView and the version of android is below 5.0, the imageview will cause this crash. Try to use <android.support.v7.widget.AppCompatImageView instead of ImageView and don't forget in your java code to declare and cast you imageview with appCompatImageView as well. To set the vector as background use this xml attribute: app:srcCompat for choosing a color use android:tint and finally in your gradle file you must add support to vectors:

android {
    //...
    defaultConfig {
 //...

        vectorDrawables {
            useSupportLibrary = true
        }
    }


回答2:

It doesn't look like you are actually inflating the ImageView.

private List<FeedAdapter> mDataList;
private LayoutInflater inflater;

public RecyclerAdapter(Context context, List<FeedAdapter> data) {
    inflater = LayoutInflater.from(context);
    this.mDataList = data;
    this.context = context;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {  // Create the Prime and Non-Prime row Layouts
    case Image_digit:
    ViewGroup myLayout = (ViewGroup) inflater.inflate(R.layout.list_item, parent, false);
    ImageView myImage = (ImageView) myLayout.findViewById(R.id.my_image_id);
    MyViewHolder_Images holderPrime = new MyViewHolder_Images(myImage);
        return holderPrime;