android.view.InflateException:二进制 XML 文件第 8 行:膨胀 class <unknown> 时出错

android.view.InflateException: Binary XML file line #8: Error inflating class <unknown>

首先,我知道有很多问题和我一样。我已经阅读了所有这些,但还没有找到适合我情况的答案。

我的情况

我正在尝试像 Gmail 一样实现 LetterAvatarView。我使用了 SocketIO's sample project,并通过添加 LetterAvatarView 修改了它的 item_message.xml。下面是结果。

这里是item_message.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center_vertical"
    android:paddingTop="@dimen/spacing">

    <com.github.nkzawa.socketio.androidchat.LetterAvatarView <--- error occur
        android:id="@+id/la_avatar"
        android:layout_width="50dp"
        android:layout_height="50dp" />

    <TextView
        android:id="@+id/username"
        style="?android:textAppearanceMedium"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:textColor="?android:textColorPrimary"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/message"
        style="?android:textAppearanceMedium"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="@dimen/spacing"
        android:paddingRight="@dimen/spacing"
        android:singleLine="true"
        android:textColor="?android:textColorPrimary" />

</LinearLayout>

我的LetterAvatarViewclass:

public class LetterAvatarView extends View {

    private Paint mTextPaint;
    private Paint mBackgroundPaint;
    private String[] colors = new String[]{
        "#e7e7e7", "#b6cff5", "#98d7e4", "#e3d7ff", "#fbd3e0", "#f2b2a8", "#c2c2c2", "4986e7",
            "#2da2bb", "#b99aff", "#f691b2", "#fb4c2f", "#ffc8af", "#ffdeb5", "#fbe983", "#fdedc1",
            "#b3efd3", "#a2dcc1", "#ff7537", "#ffad46", "#ebdbde", "#cca6ac", "#42d692", "#16a765"
    };
    private int radius;
    private int centerX;
    private int centerY;
    private String firstCharacter = "";

    public LetterAvatarView(Context context) {
        super(context);
        init();
    }

    public LetterAvatarView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public LetterAvatarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(centerX, centerY, radius, mBackgroundPaint);
        drawTextCentred(canvas, firstCharacter, centerX, centerY, mTextPaint);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        radius = w / 2;
        centerX = w / 2;
        centerY = h / 2;
        mTextPaint.setTextSize(radius);
    }

    private void init(){
        mTextPaint = new Paint();
        mBackgroundPaint = new Paint();
        Random random = new Random();
        int backgroundColor = Color.parseColor(colors[random.nextInt(colors.length)]);
        mBackgroundPaint.setColor(backgroundColor);
        mBackgroundPaint.setStyle(Paint.Style.FILL);
        mBackgroundPaint.setAntiAlias(true);
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
    }

    public void setText(String text){
        if(!TextUtils.isEmpty(text)) {
            firstCharacter = text.substring(0, 1);
            firstCharacter = firstCharacter.toUpperCase();
        }
    }

    public void drawTextCentred(Canvas canvas, String text, float cx, float cy, Paint paint){
        Rect textBounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), textBounds);
        canvas.drawText(text, cx, cy - textBounds.exactCenterY(), paint);
    }
}

更新 1 这是我的适配器 class

public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder> {

private List<Message> mMessages;
private int[] mUsernameColors;

public MessageAdapter(Context context, List<Message> messages) {
    mMessages = messages;
    mUsernameColors = context.getResources().getIntArray(R.array.username_colors);
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    int layout = -1;
    switch (viewType) {
    case Message.TYPE_MESSAGE:
        layout = R.layout.item_message;
        break;
    case Message.TYPE_LOG:
        layout = R.layout.item_log;
        break;
    case Message.TYPE_ACTION:
        layout = R.layout.item_action;
        break;
    }
    View v = LayoutInflater
            .from(parent.getContext())
            .inflate(layout, parent, false);
    return new ViewHolder(v);
}

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
    Message message = mMessages.get(position);
    viewHolder.setMessage(message.getMessage());
    viewHolder.setUsername(message.getUsername());
}

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

@Override
public int getItemViewType(int position) {
    return mMessages.get(position).getType();
}

public class ViewHolder extends RecyclerView.ViewHolder {
    private TextView mUsernameView;
    private TextView mMessageView;
    private LetterAvatarView mAvatarView;

    public ViewHolder(View itemView) {
        super(itemView);

        mUsernameView = (TextView) itemView.findViewById(R.id.username);
        mMessageView = (TextView) itemView.findViewById(R.id.message);
        mAvatarView = (LetterAvatarView) itemView.findViewById(R.id.la_avatar);
    }

    public void setUsername(String username) {
        if (null == mUsernameView) return;
        mUsernameView.setText(username);
        mUsernameView.setTextColor(getUsernameColor(username));
        if(mAvatarView != null) mAvatarView.setText(username);
    }

    public void setMessage(String message) {
        if (null == mMessageView) return;
        mMessageView.setText(message);
    }

    private int getUsernameColor(String username) {
        int hash = 7;
        for (int i = 0, len = username.length(); i < len; i++) {
            hash = username.codePointAt(i) + (hash << 5) - hash;
        }
        int index = Math.abs(hash % mUsernameColors.length);
        return mUsernameColors[index];
    }
}
}

更新 2 Message class

public class Message {

public static final int TYPE_MESSAGE = 0;
public static final int TYPE_LOG = 1;
public static final int TYPE_ACTION = 2;

private int mType;
private String mMessage;
private String mUsername;

private Message() {}

public int getType() {
    return mType;
};

public String getMessage() {
    return mMessage;
};

public String getUsername() {
    return mUsername;
};


public static class Builder {
    private final int mType;
    private String mUsername;
    private String mMessage;

    public Builder(int type) {
        mType = type;
    }

    public Builder username(String username) {
        mUsername = username;
        return this;
    }

    public Builder message(String message) {
        mMessage = message;
        return this;
    }

    public Message build() {
        Message message = new Message();
        message.mType = mType;
        message.mUsername = mUsername;
        message.mMessage = mMessage;
        return message;
    }
}
}

问题 我的代码有时工作。但有时它崩溃了:

android.view.InflateException: Binary XML file line #8: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:620)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at com.github.nkzawa.socketio.androidchat.MessageAdapter.onCreateViewHolder(MessageAdapter.java:39)
at com.github.nkzawa.socketio.androidchat.MessageAdapter.onCreateViewHolder(MessageAdapter.java:13)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:4121)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:3431)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:3340)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1810)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1306)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1269)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:508)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:1988)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2237)
at android.view.View.layout(View.java:14289)
at android.view.ViewGroup.layout(ViewGroup.java:4562)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
at android.view.View.layout(View.java:14289)
at android.view.ViewGroup.layout(ViewGroup.java:4562)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:14289)
at android.view.ViewGroup.layout(ViewGroup.java:4562)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:14289)
at android.view.ViewGroup.layout(ViewGroup.java:4562)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:14289)
at android.view.ViewGroup.layout(ViewGroup.java:4562)
at android.support.v7.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:502)
at android.view.View.layout(View.java:14289)
at android.view.ViewGroup.layout(ViewGroup.java:4562)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:14289)
at android.view.ViewGroup.layout(ViewGroup.java:4562)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
at android.view.View.layout(View.java:14289)
at android.view.ViewGroup.layout(ViewGroup.java:4562)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:14289)
at android.view.ViewGroup.layout(ViewGroup.java:4562)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1976)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1730)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
at android.view.Choreographer.doCallbacks(Choreographer.java:562)
at android.view.Choreographer.doFrame(Choreographer.java:532)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)

我该如何解决?

尝试用硬编码颜色替换 "android:textColor="?android:textColorPrimary" "; 'i.e:"#212121',在您所有的单个列表项中让我们看看结果。也可以尝试删除 "style="?android:textAppearanceMedium""...让我们看看是否可以解决问题。我也遇到过这样的问题。

好的,我们可以在这里有不同的错误。

第一个想到的是

@Override
public int getItemViewType(int position) {
    return mMessages.get(position).getType();
}

将是 return 0。现在不完全是你的 Message 对象。但是当 Message.TYPE_MESSAGEMessage.TYPE_LOGMessage.TYPE_ACTION 不是 0 时,您将在 onCreateViewHolder().

中膨胀一个未知的布局

一些关于如何创建 List<Messages> 对象的代码会很棒。

另一个问题是你有(可能)不同的布局 Views 它。 你的 R.layout.item_logR.layout.item_action 看起来怎么样?当它们不包含 R.id.usernameR.id.messageR.id.la_avater 时,它也会崩溃。 但我认为这是另一个错误,而不是真正的崩溃。

更新

我已经克隆了源代码,MessageAdapter 中的第 39 行正好是:

  View v = LayoutInflater
                .from(parent.getContext())
                .inflate(layout, parent, false); <-- line 39

我还没有发现它是怎么回事。因为类型是通过 Message#Builder 对象设置的。 但是,是的,这就是问题所在...

发生异常是因为 LetterAvatarView 中的 colors 属性包含无效的 rgb 值。

private String[] colors = new String[]{"#e7e7e7", "#b6cff5", "#98d7e4", "#e3d7ff", "#fbd3e0", "#f2b2a8", "#c2c2c2" , "4986e7", "#2da2bb", "#b99aff", "#f691b2", "#fb4c2f", "#ffc8af", "#ffdeb5", "#fbe983", "#fdedc1", "#b3efd3", "#a2dcc1", "#ff7537", "#ffad46", "#ebdbde", "#cca6ac", "#42d692", "#16a765"};

private void init(){
        mTextPaint = new Paint();
        mBackgroundPaint = new Paint();
        Random random = new Random();
        int backgroundColor = Color.parseColor(colors[random.nextInt(colors.length)]);
        mBackgroundPaint.setColor(backgroundColor);
        mBackgroundPaint.setStyle(Paint.Style.FILL);
        mBackgroundPaint.setAntiAlias(true);
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
    }

Color.parseColor(..) 抛出带有一些 rng

的 IllegalArgumentException

当您使用 mipmap 而不是 drawable 时,有时会发生这种情况。请正确检查错误并更正 activity xml 文件

我遇到了上述错误,我将 mipmap 更正为可绘制,它对我有用。