0
votes

I'm trying to find out how can I put extra data when changing fragments on autogenerated navigation drawer activity.

I have created a login activity and when i click a button it opens a new Navigation Drawer Activity (Main Activity) and puts extra the user id. I have 4 fragments (home, about, contact and share) is this navigation drawer. When main activity is opened, it automatically opens the home fragment.

The thing is, i want to put the user id passed from the login activity, in the home fragment, when main activity is opened. How can i do it?

My MainActivity

public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;
    private TextView tv_username_header;
    private TextView tv_email_header;
    private static final String HEADER = "header";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        int userId = getIntent().getIntExtra("user_id", 0);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int userId = getIntent().getIntExtra("user_id", 0);
                Intent intent = new Intent(MainActivity.this, AddTrip.class);
                intent.putExtra("user_id", userId);
                startActivity(intent);
            }
        });
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_about, R.id.nav_contact, R.id.nav_share)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);

//        if(savedInstanceState == null) {
//            Bundle b = new Bundle();
//            //int user_id = getIntent().getIntExtra("user_id", 0);
//            b.putInt("user_id_app", userId);
//            HomeFragment fragment = new HomeFragment();
//            fragment.setArguments(b);
//            Log.v("argument", fragment.getArguments().toString());
//            getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, fragment).commit();
//        }

//        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
//            @Override
//            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
//                switch (item.getItemId()){
//                    case R.id.nav_home:
//                        Bundle b = new Bundle();
//                        int user_id = getIntent().getIntExtra("user_id", 0);
//                        Log.v("id", String.valueOf(user_id));
//                        b.putInt("user_id_app", user_id);
//                        HomeFragment fragment = new HomeFragment();
//                        fragment.setArguments(b);
//                        getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, fragment).commit();
//                        drawer.closeDrawer(GravityCompat.START);
//                        break;
//                }
//                return true;
//            }
//        });

        // SETAM NUMELE SI EMAILUL IN HEADER CU SHARED PREFERENCES

        if(getIntent().hasExtra("user_id")) {
            userId = getIntent().getIntExtra("user_id", 0);
            User user = TripDatabase.getInstance(this).userDao().getById(userId);

            setStringValueInSharedPref(this, "nume", "email", user.getFullName(), user.getEmail());
        }

        View navHeader = navigationView.getHeaderView(0);
        tv_username_header = navHeader.findViewById(R.id.tv_username_header);
        tv_email_header = navHeader.findViewById(R.id.textView_email);

        ArrayList<String> list = getStringValueFromSharedPref(this, "nume", "email");
        tv_username_header.setText(list.get(0));
        tv_email_header.setText(list.get(1));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == R.id.favorite) {
            Intent intent = new Intent(this, FavouriteTrips.class);
            startActivity(intent);
            return true;
        }
        return false;
    }

    public static void setStringValueInSharedPref(Context context, String key1, String key2, String value1, String value2){
        SharedPreferences sharedPreferences = context.getSharedPreferences(HEADER, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key1, value1);
        editor.putString(key2, value2);
        editor.apply();
    }

    public static ArrayList<String> getStringValueFromSharedPref(Context context, String key1, String key2){
        ArrayList<String> list = new ArrayList<>();
        SharedPreferences sharedPreferences = context.getSharedPreferences(HEADER, Context.MODE_PRIVATE);
        list.add(sharedPreferences.getString(key1, ""));
        list.add(sharedPreferences.getString(key2, ""));
        return list;
    }

    @Override
    public void onBackPressed() {
        startActivity(new Intent(MainActivity.this, LoginActivity.class));
    }
}

My Home Fragment

public class HomeFragment extends Fragment {

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

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        TextView tv_fara_trip = view.findViewById(R.id.tv_fara_tripuri);
        RecyclerView rv_trips = view.findViewById(R.id.rv_trips);

        Bundle b = this.getArguments();
//        int user_id = b.getInt("user_id_app", 0);

        if(b == null){
            Toast.makeText(view.getContext(), "null", Toast.LENGTH_LONG).show();
        }

        List<Trip> trips = TripDatabase.getInstance(getContext()).tripDao().getAllTrips();
        Log.v("trips", trips.toString());

        if(trips.size() == 0){
            rv_trips.setVisibility(View.GONE);
        } else {
            tv_fara_trip.setVisibility(View.GONE);
        }


        rv_trips.setLayoutManager(new LinearLayoutManager(this.getContext()));
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(trips, this.getContext());
        rv_trips.setAdapter(adapter);
    }
}

In home fragment when i call int user_id = b.getInt("user_id_app", 0); it crashes with the error java.lang.NullPointerException: Attempt to invoke virtual method 'int android.os.Bundle.getInt(java.lang.String, int)' on a null object reference at com.example.androidfundamentalsproject.HomeFragment.onViewCreated(HomeFragment.java:36)

EDIT 1:

Main Activity

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        int user_id = getIntent().getIntExtra("user_id_app", 0);

        Bundle bundle = new Bundle();
        bundle.putInt("user_id_app", user_id);

        HomeFragment homeFragment = new HomeFragment();
        homeFragment.setArguments(bundle);

        getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, homeFragment, "HomeFragment").commit();


        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int userId = getIntent().getIntExtra("user_id", 0);
                Intent intent = new Intent(MainActivity.this, AddTrip.class);
                intent.putExtra("user_id", userId);
                startActivity(intent);
            }
        });
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_about, R.id.nav_contact, R.id.nav_share)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);

        // SETAM NUMELE SI EMAILUL IN HEADER CU SHARED PREFERENCES

        if(getIntent().hasExtra("user_id_app")) {
            user_id = getIntent().getIntExtra("user_id_app", 0);
            User user = TripDatabase.getInstance(this).userDao().getById(user_id);

            setStringValueInSharedPref(this, "nume", "email", user.getFullName(), user.getEmail());
        }

        View navHeader = navigationView.getHeaderView(0);
        tv_username_header = navHeader.findViewById(R.id.tv_username_header);
        tv_email_header = navHeader.findViewById(R.id.textView_email);

        ArrayList<String> list = getStringValueFromSharedPref(this, "nume", "email");
        tv_username_header.setText(list.get(0));
        tv_email_header.setText(list.get(1));
    }

Home Fragment

@Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        TextView tv_fara_trip = view.findViewById(R.id.tv_fara_tripuri);
        RecyclerView rv_trips = view.findViewById(R.id.rv_trips);

        int user_id = 0;
        Bundle bundle = getArguments();
        if(bundle != null) {
            user_id = bundle.getInt("user_id_app", 0);
        } else {
            Toast.makeText(view.getContext(), "Bundle is null", Toast.LENGTH_LONG).show();
        }

        List<Trip> trips = TripDatabase.getInstance(getContext()).tripDao().getAllTrips();
        Log.v("trips", trips.toString());

        if(trips.size() == 0){
            rv_trips.setVisibility(View.GONE);
        } else {
            tv_fara_trip.setVisibility(View.GONE);
        }


        rv_trips.setLayoutManager(new LinearLayoutManager(this.getContext()));
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(trips, this.getContext());
        rv_trips.setAdapter(adapter);
    }

EDIT 2

I have made an update in main activity in which i keep the bundle but instead of

Bundle bundle = new Bundle();
bundle.putInt("user_id", userId);

HomeFragment homeFragment = new HomeFragment();
homeFragment.setArguments(bundle);

        getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, homeFragment, "HomeFragment").commit();

i put

Bundle bundle = new Bundle();
bundle.putInt("user_id", userId);
navController.navigate(R.id.nav_home, bundle);

which seems to work but when i change fragment to "about" for example and then go back to "home" the bundle is null.

1
Can you please edit your question and add your code. What have you done so far? If you want to get the great answer you need to ask a great question. stackoverflow.com/help/how-to-ask - SlothCoding
Sorry about that. I've now edited my post, i hope it makes more sense. - Marius-Marian Burlacu

1 Answers

0
votes

So, what you need to do. First when your user logs in at LoginActivity use this:

Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra("user_id_app", 200);
startActivity(intent);
finish();

After that, in onCreate in MainActivity use this:

int user_id = getIntent().getIntExtra("user_id_app", 0);

Now you can send that value to HomeFragment like this. Since your HomeFragment is the first fragment shown after the app starts, use this in MainActivity in onCreate just below the above line:

Bundle bundle = new Bundle();
bundle.putInt("user_id_app", user_id);

HomeFragment homeFragment = new HomeFragment();
homeFragment.setArguments(bundle);

getSupportFragmentManager().beginTransaction().replace(R.id.container, homeFragment, "HomeFragment").commit();

Then in your HomeFragment use this in onViewCreated:

int user_id = 0;
Bundle bundle = getArguments();
if(bundle != null) {
      user_id = bundle.getInt("user_id_app", 0);
} else {
      Toast.makeText(view.getContext(), "Bundle is null", Toast.LENGTH_LONG).show();
}

EDIT:

Since you need to save that value for your next activities and fragments you can use SharedPreferences, use it like this. In your LoginActivity save it like this:

SharedPreferences sharedPreferences = getBaseContext().getSharedPreferences("MY_PREF", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("user_id", user_id);
editor.apply();

Then in each activity/fragment you can use this to get the value:

SharedPreferences sharedPreferences = getBaseContext().getSharedPreferences("MY_PREF", Context.MODE_PRIVATE);
int user_id = sharedPreferences.getInt("user_id", 0); //where 0 is default value

This way you can get your user_id in each activity or fragment. Other way to do this is to pass user_id from LoginActivity to MainActivity with Intent.putExtra() like this:

Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra("user_id", user_id);
startActivity(intent);
finish();

and then create global variable inside MainActivity like this:

public static int USER_ID = 0;

Then inside onCreate write something like this:

USER_ID = getIntent().getIntExtra("user_id", 0);

Then from each activity or fragment, you can access this value like this:

MainActivity.USER_ID //this will be value of user_id