简体   繁体   中英

Call fragment from fragment java.lang.NullPointerException

I am calling fragment2 from my current fragment1 when Cardview on click and I am getting this error. I want to change fragment but i get a 'java.util.ArrayList' NullPointerException from a method in another class.

java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.ArrayList com.example.uspherejda.DB.SatFromHelper.getAllData(android.database.sqlite.SQLiteDatabase)' on a null object reference

Fragment1 where i am trying to change fragment to fragment2

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_home, container, false);
         dbHelper = new SatFromHelper(getContext());
         db = dbHelper.getWritableDatabase();
        //Card views.
        satList = (CardView) view.findViewById(R.id.crdList);
        addSat = (CardView) view.findViewById(R.id.crdForm);
        satType = (CardView) view.findViewById(R.id.crdSatTypes);
        satCountries = (CardView) view.findViewById(R.id.crdCountries);
        aboutMe = (CardView) view.findViewById(R.id.crdAboutMe);
        goCrazy = (CardView) view.findViewById(R.id.crdGoCrayCraaaaay);

        satList.setOnClickListener(this::onClick);
        //addSat.setOnClickListener(this);
        //satType.setOnClickListener(this);
        //satCountries.setOnClickListener(this);
        //aboutMe.setOnClickListener(this);
        //goCrazy.setOnClickListener(this);
        return view;
    }
    @Override
    public void onClick(View v){
        switch (v.getId()){
            case R.id.crdList: getParentFragmentManager().beginTransaction().replace(R.id.homeFragment, new ListFragment(dbHelper, db)).commit();
                break;
        }
    }
}

Fragment 2 onCreateView method

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View listView = inflater.inflate(R.layout.fragment_list, container, false);
        dbHelper = new SatFromHelper(getContext());
        db = dbHelper.getWritableDatabase();
        RecyclerView recyclerView = listView.findViewById(R.id.recyclerView);
        Button deleteEntries = listView.findViewById(R.id.btnDeleteEntries);
        ArrayList<SatelliteForm> arraySatelite = dbHelper.getAllData(db); //CURRENT ERROR HERE
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(arraySatelite);
        //Auxiliar ItemTouchHelper
        ItemTouchHelper.SimpleCallback itemTouchHelperCallBack1 = null;
        //Swipe on delete, it can be either right or left
        ItemTouchHelper.Callback itemTouchHelperCallback = itemTouchHelper(itemTouchHelperCallBack1, arraySatelite, dbHelper,
                                                            db, adapter);
        new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager((getContext())));
        //recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
        //need to add toast for confirmation
        deleteEntries.setOnClickListener(e -> showAlert("Delete", "Are you sure you want to delete all the current entries?", arraySatelite, db));
        return listView;
    }
    //this method deletes all the current entries
    public void deleteEntries(ArrayList<?> arraySatelite, SQLiteDatabase db) {
        if (arraySatelite != null && db != null) { //first checks if the list and the are not empty
            dbHelper.onDelete(db);
            arraySatelite = new ArrayList<>();
        }
        //After deleting the current entries refresh the current activity calling the same fragment
        getParentFragmentManager().beginTransaction().replace(R.id.fragment_container, new ListFragment(dbHelper, db)).commit();
    }
    //this method will remove a specific satellite when swiped
    public ItemTouchHelper.SimpleCallback itemTouchHelper(ItemTouchHelper.SimpleCallback itemTouchHelperCallBack,
                                                          ArrayList<SatelliteForm> arraySatelite, SatFromHelper dbHelper,
                                                          SQLiteDatabase db,
                                                          RecyclerViewAdapter adapter){
        itemTouchHelperCallBack =
                new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT) {
                    @Override
                    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
                        return false;
                    }
                    @Override
                    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
                        int deletedObject = viewHolder.getAdapterPosition();
                        Log.i("removeob", "" + deletedObject);
                        Log.i("removeob", "" + arraySatelite.get(deletedObject).getId());
                        dbHelper.removeSatelite(db, arraySatelite.get(deletedObject).getId());
                        arraySatelite.remove(deletedObject);//remove swiped item
                        adapter.notifyDataSetChanged();
                    }
                };
        return itemTouchHelperCallBack;
    }
    //this method will alert with a dialog when the delte button is pressed
    public void showAlert(String title, String message, ArrayList<?> arraySatelite, SQLiteDatabase db){
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setTitle(title);
        builder.setMessage(message)
                .setNegativeButton("No", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                //KO METHOD
            }
        }).setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        deleteEntries(arraySatelite, db);
                    }
                });
        AlertDialog dialog = builder.create();
        dialog.show();

    }

Class where i call getAllData() method

public class SatFromHelper extends SQLiteOpenHelper {
    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "contacts.db";

    //private static final String SQL_DROP_ENTRIES = "DELETE * TABLE " + SatFormContracts.ContactsEntry.TABLE_NAME + ";";
    private static final String SQL_CREATE_ENTRIES = "CREATE TABLE " + SatFormContracts.ContactsEntry.TABLE_NAME +
            " (" + SatFormContracts.ContactsEntry.ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            SatFormContracts.ContactsEntry.COLUMN_NAME_TITLE + " VARCHAR(10)," +
            SatFormContracts.ContactsEntry.COLUMN_COUNTRY_TITLE + " VARCHAR(10)," +
            SatFormContracts.ContactsEntry.COLUMN_CATEGORY_TITLE + " VARCHAR(10));";


    public SatFromHelper(Context context){
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL(SQL_CREATE_ENTRIES);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
    public void onDelete(SQLiteDatabase db){
        db.execSQL("delete from " + SatFormContracts.ContactsEntry.TABLE_NAME);
    }
    public void insertContact(SQLiteDatabase db, SatelliteForm sf){
        //Check the bd is open
        if (db.isOpen()){
            //Creation of the register for insert object with the content values
            ContentValues values = new ContentValues();
            //Insert the incidence getting all values
            Log.i("sqlitelog", sf.getName() + " " + sf.getCategory() + " " + sf.getCountry());
            values.put(SatFormContracts.ContactsEntry.COLUMN_NAME_TITLE, sf.getName());
            values.put(SatFormContracts.ContactsEntry.COLUMN_COUNTRY_TITLE, sf.getCountry());
            values.put(SatFormContracts.ContactsEntry.COLUMN_CATEGORY_TITLE, sf.getCategory());
            //inserts the values above
            db.insert(SatFormContracts.ContactsEntry.TABLE_NAME, null, values);
        }else{
            Log.i("sql","Database is closed");
        }
    }
    //this method removes a specific item from the  db
    public void removeSatelite(SQLiteDatabase sqLiteDatabase, int pos){
        sqLiteDatabase.execSQL("delete from form where id=" + pos);
    }
    //reads from and stores the selected items from the db
    public ArrayList<SatelliteForm> getAllData(SQLiteDatabase sqLiteDatabase) {
        ArrayList<SatelliteForm> arraySatelite = new ArrayList<>();
        sqLiteDatabase = this.getWritableDatabase();
        String SELECT_QUERY = "select id, name, country, category from " + SatFormContracts.ContactsEntry.TABLE_NAME + ";";
        //this cursor will navigate through the db
        Cursor c = sqLiteDatabase.rawQuery(SELECT_QUERY, null);
        Log.i("nameSQL", "" + c.getCount());
        if(c.moveToFirst()) {
            do{
                SatelliteForm form = new SatelliteForm();
                form.setId(c.getInt(0));
                form.setName(c.getString(1));
                form.setCountry(c.getString(2));
                form.setCategory(c.getString(3));
                Log.i("nameSQL", c.getInt(0) + "" + c.getString(1) + "" + c.getString(2) + "" + c.getString(3));
                arraySatelite.add(form);
            }while (c.moveToNext());
        }
        c.close();
        return arraySatelite;
    }

HomeScreen Activity where i control my fragments

public class HomeScreen extends AppCompatActivity {
    //SQL
    private SatFromHelper dbHelper;
    private SQLiteDatabase db;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home_screen);
        dbHelper = new SatFromHelper(this);
        db = dbHelper.getWritableDatabase();
        //call the Home fragment
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new HomeFragment()).commit();
        //Set up a custom bar using a custom
        ActionBar actionBar = getSupportActionBar();
        getSupportActionBar().setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.start_dark_blue)));
        actionBar.setDisplayShowCustomEnabled(true);
        LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = layoutInflater.inflate(R.layout.custom_bar_image, null);
        actionBar.setCustomView(view);


        //Bottom Navigation
        BottomNavigationView bottomNav = findViewById(R.id.nav_menu);
        //Item listener when one of hte items below from the nav_bar is selected
        bottomNav.setOnItemSelectedListener(item -> {
            Fragment selectedFragment = null;
            switch(item.getItemId()){
                case R.id.nav_home:
                    selectedFragment = new HomeFragment(dbHelper, db);
                    break;
                case R.id.nav_list:
                    selectedFragment = new ListFragment(dbHelper, db);
                    break;
                case R.id.nav_add:
                    selectedFragment = new AddFragment(dbHelper, db);
                    break;
            }
            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, selectedFragment).commit();
            return true;
        });
    }
    //Close the db when the activity onDestroy
    @Override
    public void onDestroy() {
        super.onDestroy();
        dbHelper.close();
        db.close();
    }
}

Now when I change fragment it adds the fragment2 below my current fragment, such as: 在此处输入图片说明

The solution for this dumb question is...

Initialise the db in each fragment:

db = dbHelper.getWritableDatabase();

And for the fragment change mess:

@Override
public void onClick(View v){
    switch (v.getId()){
        case R.id.crdList: getParentFragmentManager().beginTransaction().replace(R.id.fragment_container, new ListFragment(dbHelper, db)).commit();
            break;
    }
}

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