RecyclerView OnClick导致NullPointerException

时间:2016-04-14 14:15:57

标签: java android nullpointerexception onclick android-recyclerview

我正在使用RecyclerView将片段中的信息显示为带有ImageViews和TextViews的列表。我给ImageViews一个OnClickListener来获取位置,并使用drawable id在更大的ImageView中显示图像。这对于片段开头显示的所有RecyclerView行都可以正常工作,但是当我从一行中单击一个ImageView时,我需要滚动到它,我得到一个带按摩的NullPointerException:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference

显示的信息会根据预览片段中的微调器而变化。使用fragmentManager.region(d)通过Activity将变量赋予Fragment。

infromationFragment的代码如下:

public class Info_Material extends Fragment implements View.OnClickListener {

Button button_back;
Communicator communicator;
static ImageView image_large;


static private RecyclerView recyclerView;
private Information_List_Adapter adapter;

static ArrayList<String> holz_;
static ArrayList<String> land_;
static ArrayList<Integer> blatt_;
static ArrayList<Integer> baum_;
static ArrayList<Integer> frucht_;

String region_;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_info_material, container, false);

    holz_ = new ArrayList<>();
    land_ = new ArrayList<>();
    blatt_ = new ArrayList<>();
    baum_ = new ArrayList<>();
    frucht_ = new ArrayList<>();

    holz_.add(getString(R.string.));
    land_.add("");
    blatt_.add(R.drawable.);
    baum_.add(R.drawable.);
    frucht_.add(R.drawable.);

    if (region_wahl.equals(getString(a))){
        holz_.addAll(Arrays.asList());
        land_.addAll(Arrays.asList());
        blatt_.addAll(Arrays.asList());
        baum_.addAll(Arrays.asList());
        frucht_.addAll(Arrays.asList());
    }
    if (region_wahl.equals(getString(b))){
        holz_.addAll(Arrays.asList());
        land_.addAll(Arrays.asList());
        blatt_.addAll(Arrays.asList());
        baum_.addAll(Arrays.asList());
        frucht_.addAll(Arrays.asList());
    }

    recyclerView= (RecyclerView) view.findViewById(R.id.materialInfoList);
    adapter = new Information_List_Adapter(getActivity(),getData());
    recyclerView.setAdapter(adapter);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    button_back = (Button) view.findViewById(R.id.back_I_M);
    button_back.setOnClickListener(this);

    image_large= (ImageView) view.findViewById(R.id.image_large);
    image_large.setOnClickListener(this);

    return view;
}

public static List<Information_List> getData() {
    List<Information_List> data = new ArrayList<>();

    for(int i=0;i<holz_.size() && i<blatt_.size() && i<baum_.size() && i<frucht_.size();i++) {
        Information_List current = new Information_List();
        current.blattID=blatt_.get(i);
        current.baumID=baum_.get(i);
        current.fruchtID=frucht_.get(i);
        current.holz=holz_.get(i);
        data.add(current);
    }
    return data;
}



@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

}

public void setCommunicator (Communicator communicator) {
    this.communicator = communicator;
}

@Override
public void onClick(View view) {
    if(view.getId()==R.id.back_I_M){
        String d;
        d = "back";
        communicator.finish_I_M(d);
    }
    if(view.getId()==R.id.image_large){
        image_large.setImageDrawable(null);
    }
}


public void region (String d) {

    region_ = d;

}

static void enlarge (int position,String data){
    ImageView imageView=null;
    if(data.equals("blatt")){
        imageView = (ImageView)recyclerView.getChildAt(position).findViewById(R.id.info_list_blatt);
    }
    if(data.equals("baum")){
        imageView = (ImageView)recyclerView.getChildAt(position).findViewById(R.id.info_list_baum);
    }
    if(data.equals("frucht")){
        imageView = (ImageView)recyclerView.getChildAt(position).findViewById(R.id.info_list_frucht);
    }

    BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();

    image_large.setImageDrawable(drawable);
}

public interface Communicator {

    void finish_I_M (String data);

}

}

AdapterClass:

public class Information_List_Adapter extends RecyclerView.Adapter <Information_List_Adapter.MyViewHolder> {

private Context context;
private LayoutInflater inflater;
List<Information_List> data = Collections.emptyList();

public Information_List_Adapter(Context context, List<Information_List> data) {
    this.context=context;
    inflater= LayoutInflater.from(context);
    this.data=data;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate (R.layout.custom_info_material_row,parent,false);
    MyViewHolder holder = new MyViewHolder(view);

    return holder;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

    holder.holz.setText(Info_Material.holz_.get(position));
    holder.land.setText(Info_Material.land_.get(position));
    holder.blattID.setImageResource(Info_Material.blatt_.get(position));
    holder.baumID.setImageResource(Info_Material.baum_.get(position));
    holder.fruchtID.setImageResource(Info_Material.frucht_.get(position));

}

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

class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    TextView holz;
    TextView land;
    ImageView blattID;
    ImageView baumID;
    ImageView fruchtID;

    public MyViewHolder(View itemView) {
        super(itemView);
        holz= (TextView) itemView.findViewById(R.id.info_list_holz);
        land = (TextView) itemView.findViewById(R.id.info_list_land);
        blattID = (ImageView) itemView.findViewById(R.id.info_list_blatt);
        baumID = (ImageView) itemView.findViewById(R.id.info_list_baum);
        fruchtID = (ImageView) itemView.findViewById(R.id.info_list_frucht);

        blattID.setOnClickListener(this);
        baumID.setOnClickListener(this);
        fruchtID.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if(v.getId()==R.id.info_list_blatt){
            Info_Material.enlarge(getAdapterPosition(),"blatt");
        }
        if(v.getId()==R.id.info_list_baum){
            Info_Material.enlarge(getAdapterPosition(),"baum");
        }
        if(v.getId()==R.id.info_list_frucht){
            Info_Material.enlarge(getAdapterPosition(),"frucht");
        }
    }
}

}

如上所述,这个方法在启动Fragment时对所有最初创建的行都可以正常工作,但是很快,当一个新创建的行(最初没有显示在屏幕上)被点击时,应用程序崩溃并显示NullPointerException。

由于我仍然是Java编程的新手,我真的不知道我可以从哪里开始寻找错误,所以我希望能有关于错误发生位置的任何提示。

提前致谢。

3 个答案:

答案 0 :(得分:0)

enlarge方法中,您尝试在空引用上调用findViewById

此代码:

(ImageView)recyclerView.getChildAt(position)

返回null,因此您无法使用findViewById

另请参阅此问题:What is a NullPointerException, and how do I fix it?

作为最后一点,您会发现将数据阵列移动到适配器中更加易于管理,而不是每次需要某些数据时都从适配器调用回Fragment。

答案 1 :(得分:0)

试试这个,

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

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

    holder.holz.setText(Info_Material.holz_.get(position));
    holder.land.setText(Info_Material.land_.get(position));
    holder.blattID.setImageResource(Info_Material.blatt_.get(position));
    holder.baumID.setImageResource(Info_Material.baum_.get(position));
    holder.fruchtID.setImageResource(Info_Material.frucht_.get(position));

 holder.blattID.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                Info_Material.enlarge(position,"blatt");

                }
            });

}

答案 2 :(得分:0)

最好在适配器中处理所有这些。使recyclerview静态不是很好的解决方案。也许你想在其他地方使用片段或活动。

由于recyclerview会回收视图并仅绑定对用户可见的视图,因此最好更改列表数据并通知适配器您的某些视图已被更改。

How to update RecyclerView Adapter Data?

除此之外你有错误的结构。您必须将行数据存储在“List&lt; Information_List&gt; data”中,并且不要使用片段中的那些数组列表:(holz_land_ blatt_ baum_ frucht_)