简体   繁体   中英

Null pointer exception on null object reference

I keep getting a null pointer exception error at the DessertAdapter class starting at the line holder.mName.setText(dessert.getName()); I've tried all methods I know and I'm still getting the same error. Here is the Adapter class

public class DessertAdapter extends RecyclerView.Adapter<DessertAdapter.DessertVh> {
private List<Dessert> desserts = new ArrayList<>();
private static final int VIEW_TYPE_EMPTY_LIST_PLACEHOLDER = 0;
private static final int VIEW_TYPE_OBJECT_VIEW = 1;
private Context context;

@Override
public int getItemViewType(int position) {
    if (desserts.isEmpty()) {
        return VIEW_TYPE_EMPTY_LIST_PLACEHOLDER;
    } else {
        return VIEW_TYPE_OBJECT_VIEW;
    }
}
public DessertAdapter(Context context,List<Dessert> desserts) {
    this.context = context;
    this.desserts = desserts;      
}

// TODO: another placeholder stuff here
@Override
public DessertVh onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = inflater.inflate(R.layout.item_dessert, parent, false);
    return new DessertAdapter.DessertVh(view);
}

@Override
public void onBindViewHolder(DessertVh holder, int position) {
    Dessert dessert = desserts.get(position);
    System.out.println(position);

    holder.mName.setText(dessert.getName());
    holder.mDescription.setText(dessert.getDescription());
    holder.mFirstLetter.setText(String.valueOf(dessert.getFirstLetter()));
    holder.mPrice.setText(String.valueOf(dessert.getAmount()));
}

@Override
public int getItemCount() {
        return desserts == null ? 0 : desserts.size();
}

public static class DessertVh extends RecyclerView.ViewHolder {

    private TextView mName;
    private TextView mPrice;
    private TextView mDescription;
    private TextView mFirstLetter;

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

        mName = (TextView) itemView.findViewById(R.id.txt_name);
        mPrice = (TextView) itemView.findViewById(R.id.txt_price);
        mDescription = (TextView) itemView.findViewById(R.id.txt_desc);
        mFirstLetter = (TextView) itemView.findViewById(R.id.txt_firstletter);
    }
}

Here is the class to save the data to the Dessert object

public class AddGigActivity  extends AppCompatActivity {
private static String TAG = "AddGigActivity";
private ImageButton saveBtn;
private EditText gigName, gigDescrip, gigAmount;
private String userID;
private FirebaseDatabase mFirebaseDatabase;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private DatabaseReference myRef;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_gig);

    gigName = (EditText)findViewById(R.id.gig_name);
    gigDescrip = (EditText)findViewById(R.id.gig_description);
    gigAmount = (EditText) findViewById(R.id.gig_amnt);
    saveBtn = (ImageButton) findViewById(R.id.mybtn_add);
    mAuth = FirebaseAuth.getInstance();
    mFirebaseDatabase = FirebaseDatabase.getInstance();
    myRef =  FirebaseDatabase.getInstance().getReference();
    FirebaseUser user = mAuth.getCurrentUser();
    userID = user.getUid();
    saveBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            AddGig();
        }
    });

}


// real-time adding to the firebase database
private void AddGig(){
    String name = gigName.getText().toString();
    String descrip = gigDescrip.getText().toString();
    String amount = gigAmount.getText().toString();

    if((!TextUtils.isEmpty(name))&&(!TextUtils.isEmpty(descrip) && (!TextUtils.isEmpty(amount))) ){

        FirebaseUser user = mAuth.getCurrentUser();
        userID = user.getUid();
        String id =  myRef.push().getKey();
        Dessert dessert = new Dessert( name, descrip, amount);
       // myRef.child(id).setValue(dessert);
        myRef.child("users").child(userID).child("Gig posts").child(id).setValue(dessert);
        Toast.makeText(this, "Posted! ",Toast.LENGTH_LONG).show();
        finish();

    // you can still sprlit these to check for each text field
    }else{
        Toast.makeText(this, "One or more field(s) missing!",Toast.LENGTH_LONG).show();
    }
}

And here is the main activity code snippet that displays the data from firebase on the recycler view:

  public static class FeedsFragment extends Fragment {
    int color;

    public FeedsFragment() {
    }

    @SuppressLint("ValidFragment")
    public FeedsFragment(int color) {
        this.color = color;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.dummy_fragment, container, false);
        final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
        final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
        frameLayout.setBackgroundColor(color);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setHasFixedSize(true);

        final List<Dessert> dessertList;
        dessertList = new ArrayList<>();
        //dessertList = new Dessert(context,"");


        final String curtUserId = FirebaseAuth.getInstance().getCurrentUser().getUid();

        DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
       // DatabaseReference mDatabaseGig = rootRef.child("users").child(curtUserId).child("Gig posts");
        final String id = rootRef.push().getKey();

        final DessertAdapter adapter = new DessertAdapter(getContext(), dessertList);
        recyclerView.setAdapter(adapter);

        rootRef.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                dessertList.clear();
                for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
                    Dessert dessert = gigSnapshot
                            .child("users")
                            .child(curtUserId)
                            .child("Gig posts")
                            .child(id).getValue(Dessert.class);
                    dessertList.add(dessert);
                    adapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

        // possible to put progress dialogue
        return view;
    }
}

please would you mind taking a look at the code and help me straighten it out? Thank you.

try below Adapter class

    public class DessertAdapter extends RecyclerView.Adapter<DessertAdapter.DessertVh> {
private List<Dessert> desserts;
private static final int VIEW_TYPE_EMPTY_LIST_PLACEHOLDER = 0;
private static final int VIEW_TYPE_OBJECT_VIEW = 1;

private Context context;

// TODO: placeholder stuff here

@Override
public int getItemViewType(int position) {
    if (desserts.isEmpty()) {
        return VIEW_TYPE_EMPTY_LIST_PLACEHOLDER;
    } else {
        return VIEW_TYPE_OBJECT_VIEW;
    }
}

public DessertAdapter(Context context,List<Dessert> desserts) {
    this.context = context;
    this.desserts = desserts;

    // desserts = Dessert.prepareDesserts(
    //       context.getResources().getStringArray(R.array.dessert_names),
    //       context.getResources().getStringArray(R.array.dessert_descriptions),
    //       context.getResources().getStringArray(R.array.dessert_amounts));
}


// TODO: another placeholder stuff here
@Override
public DessertVh onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = inflater.inflate(R.layout.item_dessert, parent, false);
    return new DessertAdapter.DessertVh(view);
}

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


    holder.mName.setText(desserts.get(position).getName());
    holder.mDescription.setText(desserts.get(position).getDescription());
    holder.mFirstLetter.setText(String.valueOf(desserts.get(position).getFirstLetter()));
    holder.mPrice.setText(String.valueOf(desserts.get(position).getAmount()));


}

@Override
public int getItemCount() {
    // if nothing, return null,
    // else return the number of items in the list
    return desserts == null ? 0 : desserts.size();
}

public static class DessertVh extends RecyclerView.ViewHolder {

    private TextView mName;
    private TextView mPrice;
    private TextView mDescription;
    private TextView mFirstLetter;

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

        mName = (TextView) itemView.findViewById(R.id.txt_name);
        mPrice = (TextView) itemView.findViewById(R.id.txt_price);
        mDescription = (TextView) itemView.findViewById(R.id.txt_desc);
        mFirstLetter = (TextView) itemView.findViewById(R.id.txt_firstletter);
    }
}

Ok, so I fixed it! here's the code

 public static class UserFeedFragment extends Fragment {
    int color;

    public UserFeedFragment() {
    }

    @SuppressLint("ValidFragment")
    public UserFeedFragment(int color) {
        this.color = color;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.dummy_fragment, container, false);
        final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
        final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
        frameLayout.setBackgroundColor(color);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setHasFixedSize(true);

        String curtUserId = FirebaseAuth.getInstance().getCurrentUser().getUid();

        DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference()
                .child("users")
                .child(curtUserId)
                .child("Gig posts");

        final List<Dessert> dessertList = new ArrayList<Dessert>();

        final DessertAdapter adapter = new DessertAdapter(getContext(), dessertList);
        recyclerView.setAdapter(adapter);

        rootRef.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                dessertList.clear();
                for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){

                    Dessert dessert = gigSnapshot
                            .getValue(Dessert.class);
                    dessertList.add(dessert);
                    adapter.notifyDataSetChanged();
                }
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

        // possible to put progress dialogue
        return view;
    }
}

All I had to change was here

 DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference()
                .child("users")
                .child(curtUserId)
                .child("Gig posts");

then add an event listener here

rootRef.addValueEventListener(new com.google.firebase.database.ValueEventListener() {

and it worked! I do have a minor problem though. I have two feeds fragment: UserFeed and FeedsFragments. The Userfeed gets the feeds that the current user has posted while the FeedsFragment is meant to get feeds posted by all users. I tried doing this

 DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference()
                .child("users")
               // .child(curtUserId) I commented out the id of the user but nothing happened
                .child("Gig posts");

My question is : is there a way I can "direct" the reference to retrieve posts by all users? Once again, thanks so much in advance for your help!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM