I try to do a CRUD in Android (java), the project is based on a navigation drawer as a menu and an Activity that works as a container for the fragments I use in the project for this crud. I have a single fragment in which I want to implement the registration and data modification functions. Then the main activity where the navigability of the main menu is given as the toolbar menu (upper right button)
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
public int origen;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order);
//OMITO TODO EL CODIGO AUTOGENERADO PARA CONTROLES TOOLBAR Y NAVIGACION
//incio fragment ptincipal
Fragment fgmCatalogo = new CatalogoFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.content_main,fgmCatalogo).addToBackStack(null).commit();
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.order, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
//Dado que el programa tiene muchos CRUD y todos tiene la misma estructura llamo al fragment detalle desde un mismo boton en ese menu
Fragment fragment = new Fragment();
switch (origen)
{
case 1:
break;
case 2:
break;
case 3:
//Aqui abro el fragmento de detalle para crear un nuevo cliente
fragment = new ClienteDetalleFragment();
break;
case 4:
break;
case 5:
break;
default:
break;
}
Bundle arg = new Bundle();
arg.putInt("accion",0);
fragment.setArguments(arg);
getSupportFragmentManager().beginTransaction().replace(R.id.content_main,fragment).addToBackStack(null).commit();
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
if (item.getItemId() == R.id.nav_close)
{
new LoginResponse().borrarDatos();
Intent actHome = new Intent(this, HomeActivity.class);
startActivity(actHome);
}
else
{
Fragment fragment = null;
switch(item.getItemId()){
case R.id.nav_vender:
origen = 1;
fragment = new CatalogoFragment();
break;
case R.id.nav_inventario:
origen = 2;
fragment = new menuInventario();
break;
case R.id.nav_clientes:
origen = 3;
fragment = new ClienteFragment();
break;
case R.id.nav_ventas:
origen = 4;
fragment = new Venta();
break;
case R.id.nav_reportes:
origen = 5;
break;
default://empresa
origen = 6;
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.content_main,fragment).addToBackStack(null).commit();
getSupportActionBar().setTitle(item.getTitle());
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
}
return true;
}
}
Now I have two fragments ClienteFragment where the list of records is loaded
public class ClienteFragment extends Fragment {
RecyclerView recicler;
Cliente[] clientes;
Cliente clienteSel;
private menuInventario.OnFragmentInteractionListener mListener;
public ClienteFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View fragment = inflater.inflate(R.layout.fragment_cliente, container, false);
confView(fragment);
return fragment;
}
public void confView(View view){
recicler = view.findViewById(R.id.lstvClientes);
recicler.setLayoutManager(new LinearLayoutManager(App.getAppContext()));//,LinearLayout.VERTICAL,false));
//recicler.setLayoutManager(new GridLayoutManager(App.getAppContext(),2));
mostrarDatos();
}
public void mostrarDatos(){
new Api().solicitud(Api.getService().getClientes(new LoginResponse().leerDatos().getIdNegocio()), new RespuestaListener() {
@Override
public void onData(JsonElement data) {
clientes = new Gson().fromJson(data, Cliente[].class);
SubtitleAdapter adapter = new SubtitleAdapter(clientes);
adapter.setOnClickListener(new ItemSelected());
recicler.setAdapter(adapter);
}
});
}
class ItemSelected implements View.OnClickListener{
@Override
public void onClick(View v) {
//Abro fragment de detalles para modificar datos
clienteSel = clientes[recicler.getChildAdapterPosition(v)];
Bundle arg = new Bundle();
arg.putSerializable("clienteSel",clienteSel);
arg.putInt("accion",1); //1 es indicador de modificacion
Fragment detalles = new ClienteDetalleFragment();
detalles.setArguments(arg);
getFragmentManager().beginTransaction().replace(R.id.content_main,detalles).addToBackStack(null).commit();
}
}
}
and ClientDeleteFragment where the update and create actions are generated
public class ClienteDetalleFragment extends Fragment implements View.OnClickListener {
private OnFragmentInteractionListener mListener;
private Cliente cliente;
private int accion;
EditText txtNombres, txtCedula, txtCelular, txtDireccion;
Button btnRegistar;
public ClienteDetalleFragment() {}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_cliente_detalle, container, false);
confView(view);
return view;
}
private void confView(View v) {
txtNombres = v.findViewById(R.id.txtNombreCliente);
txtCedula = v.findViewById(R.id.txtIdentificacionCliente);
txtCelular = v.findViewById(R.id.txtCelularCliente);
txtDireccion = v.findViewById(R.id.txtDireccionSolo);
btnRegistar = v.findViewById(R.id.btnRegistrarCliente);
btnRegistar.setOnClickListener(this);
Bundle arg = getArguments();
accion = arg.getInt("accion");
if (accion == 1) {
cliente = (Cliente) arg.getSerializable("clienteSel");
mostrarDatos();
}
}
private void mostrarDatos() {
txtNombres.setText(cliente.getNombres());
txtCedula.setText(cliente.getIdentificacion());
txtCelular.setText(cliente.getCelular());
txtDireccion.setText(cliente.getDireccion());
}
private boolean validarCampos(){
boolean resp = false;
if (txtNombres.getText().length() == 0){
Mensaje.simple("Nombre es requerido", 0);
}
else if (txtCedula.getText().length() == 0){
Mensaje.simple("Cedula/Pasaporte es requerido", 0);
}
else if (txtCelular.getText().length() == 0){
Mensaje.simple("Celular es requerido", 0);
}
else if (txtDireccion.getText().length() == 0){
Mensaje.simple("Correo es requerido", 0);
}
else {
cliente.setIdentificacion(txtCedula.getText().toString());
cliente.setCelular(txtCelular.getText().toString());
cliente.setDireccion(txtDireccion.getText().toString());
cliente.setNombres(txtNombres.getText().toString());
cliente.setIdNegocio(new LoginResponse().leerDatos().getIdNegocio());
resp = true;
}
return resp;
}
@Override
public void onClick(View v) {
if (validarCampos()) {
if (accion == 0) {
new Api().solicitud(Api.getService().postCliente(cliente), new RespuestaListener() {
@Override
public void onData(JsonElement data) {
getActivity().getFragmentManager().popBackStack();
}
});
} else {
new Api().solicitud(Api.getService().putCliente(cliente.getId(), cliente), new RespuestaListener() {
@Override
public void onData(JsonElement data) {
getActivity().getSupportFragmentManager().popBackStack();// getActivity().getFragmentManager().popBackStack();
}
});
}
}
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
}
Now, when I want to modify data, calling the fragment of detail from the fragment client, reading data from the screen is successful and the modification does not generate errors, but when I call the same fragment of details from the main activity to create a client record, the data reading fails and I get an error.
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.kevtho.crud.Model.Cliente.setIdentificacion(java.lang.String)' on a null object reference
at com.kevtho.crud.Controller.Cliente.ClienteDetalleFragment.onClick(ClienteDetalleFragment.java:87)
at android.view.View.performClick(View.java:5610)
Line 87: client.setIdentification (txtCedula.getText (). toString ());
Thank you very much in advance