尝试从字段 'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView' 中读取

Posted

技术标签:

【中文标题】尝试从字段 \'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView\' 中读取【英文标题】:Attempt to read from field 'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView'尝试从字段 'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView' 中读取 【发布时间】:2017-06-13 05:21:24 【问题描述】:

我正在尝试延迟随机选择recyclerview项目。我需要在片段加载后启动随机选择方法而无需任何用户交互,但出现以下错误。之后我把它放在 ImageView 点击检查,但我再次遇到同样的异常。这里有人会告诉我我在哪里犯了错误,或者还有什么更好的方法来实现这一点。下面是我的代码

    package com.apponative.bjja.fragments;

import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.apponative.bjja.R;
import com.apponative.bjja.adapters.AttackGridAdapter;

import java.util.Random;

public class Fragment_AttackGrid extends Fragment 

    View v;
    RecyclerView grid_attack;
    AttackGridAdapter attackGridAdapter;
    Bundle b;
    int itemCount;
    Handler randomHandler;
    Runnable randomRunnable;
    Random rand;
    int randomNum = 0;
    long emptyTime;

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

        v = inflater.inflate(R.layout.fragment_attack_grid, container, false);

        setUpViews();

        return v;
    

    void setUpViews() 

        b = getArguments();
        itemCount = b.getInt(getString(R.string.item_count));
        rand = new Random();
        randomHandler = new Handler();

        grid_attack = (RecyclerView) v.findViewById(R.id.attack_grid);
        RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 4);

        grid_attack.setLayoutManager(layoutManager);
        attackGridAdapter = new AttackGridAdapter(getActivity(), itemCount);
        grid_attack.setAdapter(attackGridAdapter);

        v.findViewById(R.id.belt_black).setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                selectRandomly();
            
        );
    

    void selectRandomly() 

        for (int i = 0; i < itemCount; i++) 
            emptyTime = emptyTime+1000;
            randomRunnable = new Runnable() 
                @Override
                public void run() 
                    grid_attack.findViewHolderForAdapterPosition(randomNum).itemView.setSelected(false);
                    randomNum = rand.nextInt((itemCount - 0) + 1) + 0;
                    grid_attack.findViewHolderForAdapterPosition(randomNum).itemView.setSelected(true);
                
            ;
            randomHandler.postDelayed(randomRunnable, emptyTime);

        
        emptyTime = emptyTime+2000;
        randomRunnable = new Runnable() 
            @Override
            public void run() 
                grid_attack.findViewHolderForAdapterPosition(randomNum).itemView.performClick();
            
        ;
        randomHandler.postDelayed(randomRunnable, emptyTime);
    

    @Override
    public void onResume() 
        super.onResume();
        //   selectRandomly();
    

一开始我放了

随机选择()

onResume()

方法,我得到一个异常:

01-27 18:28:44.969 19041-19041/com.apponative.bjja E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.apponative.bjja, PID: 19041
java.lang.NullPointerException: Attempt to read from field 'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView' on a null object reference                                                                                      at com.apponative.bjja.fragments.Fragment_AttackGrid$2.run(Fragment_AttackGrid.java:77)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:155)
    at android.app.ActivityThread.main(ActivityThread.java:5696)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)

根据片段生命周期Fragment LifeCycle onResume() 和 onStart() 方法在视图创建后被调用。我也试过把我的方法放在那里,但没有成功。

【问题讨论】:

【参考方案1】:

如果您的 onCreateViewHolder 方法返回 null,则可能会发生这种情况

【讨论】:

这样一个简单的错误,但有点难以追踪,因为堆栈没有指示空指针异常发生的位置。谢谢! @pradiptilala 是的,onCreateViewHolder 正在返回 null。我不记得具体细节,但这确实为我解决了问题。【参考方案2】:

视图可能仍未加载,这就是它返回空异常的原因。

当片段加载并且对用户可见时调用此函数可能很有用:

// create boolean for checking if view is seen
private boolean isViewShown = false;

@Override
public void setUserVisibleHint(boolean isVisibleToUser) 
    super.setUserVisibleHint(isVisibleToUser);
    if (getView() != null) 
        isViewShown = true;
        // call your function
     else 
        isViewShown = false;
    
 

【讨论】:

我正在使用 FragmentTransaction 调用我的片段,据我所知 setUserVisibleHint(boolean isVisibleToUser) 方法,它在 viewpager 的情况下是有效的。【参考方案3】:

这个问题也发生在我身上,就我而言,这是因为 onCreateViewHolder 返回 null。

public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
    return null;

将其更改为:

public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 

    View view = LayoutInflater.from(parent.getContext())
                              .inflate(R.layout.category_recylcer_view, parent, false);
    ViewHolder holder = new ViewHolder(view);
    return holder;

【讨论】:

【参考方案4】:

在你的 onCreateView() 方法中设置它

grid_attack = (RecyclerView) v.findViewById(R.id.attack_grid);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 4);

grid_attack.setLayoutManager(layoutManager);

【讨论】:

onCreateViewHolder 返回的 null 只能导致此问题。最好确保它返回一个 ViewHolder,如果您为一个 RecyclerView 使用多个 ViewHolder,可能检查 getViewType。

以上是关于尝试从字段 'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView' 中读取的主要内容,如果未能解决你的问题,请参考以下文章

尝试从空对象引用上的字段“android.view.View androidx.recyclerview.widget.RecyclerView$ViewHolder.itemView”读取

尝试从空对象引用上的字段“android.view.View androidx.recyclerview.widget.RecyclerView$b0.a”读取

受保护的字段对子类不可见

尝试调用虚拟方法 'void android.widget.Button.setOnClickListener(android.view.View$onClickListener)'

Android Studio:尝试在空对象引用上调用虚拟方法“void android.view.View.setOnClickListener”

从 ListView 获取孩子会导致 android.view.View android.view.View.findViewById(int) 在空对象引用上