[英]RecyclerView OnClick resulting in NullPointerException
我正在使用RecyclerView將片段中的信息顯示為ImageViews和TextViews的列表。 我給了ImageViews一個OnClickListener來獲取位置,並使用它的drawable id在更大的ImageView中顯示圖像。 對於在Fragment開頭顯示的所有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)通過活動將變量提供給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編程還是很陌生,所以我真的不知道可以從哪里開始尋找錯誤,因此,我希望能提示任何可能發生錯誤的地方。
提前致謝。
在您的enlarge
方法中,您嘗試在null引用上調用findViewById
。
這段代碼:
(ImageView)recyclerView.getChildAt(position)
返回null,因此您不能在其上使用findViewById
。
另請參閱以下問題: 什么是NullPointerException,以及如何解決它?
最后一點,您會發現將數據數組移到適配器中而不是每次需要一些數據時都從適配器調用回Fragment的操作變得更加容易管理。
嘗試這個,
@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");
}
});
}
最好在適配器中處理所有這些。 使recyclerview靜態不是一個好的解決方案。 也許您想在其他地方使用片段或活動。
由於recyclerview回收視圖並僅綁定對用戶可見的視圖,因此最好更改List數據並通知適配器某些視圖已更改。
除此之外,您的結構有誤。 您必須將行數據存儲在“列表<Information_List>數據”中,並且不要使用片段中的那些數組列表:(holz_ land_ blatt_ baum_ frucht_)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.