将额外内容放入导航抽屉 Activity Android

Putting extra in Navigation Drawer Activity Android

我正在尝试了解如何在自动生成的导航抽屉上更改片段时添加额外数据 activity。

我创建了一个登录名 activity,当我单击一个按钮时,它会打开一个新的导航抽屉 Activity(主 Activity)并添加额外的用户 ID。我有 4 个片段(主页、关于、联系和分享)是这个导航抽屉。当mainactivity打开时,会自动打开home fragment.

问题是,我想在主 activity 打开时,将登录 activity 传递的用户 ID 放在主页片段中。我该怎么做?

我的主要Activity

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));
    }
}

我的家片段

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);
    }
}

当我调用 int user_id = b.getInt("user_id_app", 0); 时在主页片段中 它因错误 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)

而崩溃

编辑 1:

主要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));
    }

首页片段

@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);
    }

编辑 2

我在主 activity 中进行了更新,我在其中保留了捆绑包,而不是

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();

我把

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

这似乎有效,但是当我将片段更改为“about”,然后返回“home”时,捆绑包为空。

所以,你需要做什么。首先,当您的用户在 LoginActivity 登录时使用:

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

之后,在 onCreateMainActivity 中使用:

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

现在您可以像这样将该值发送到 HomeFragment。由于您的 HomeFragment 是应用程序启动后显示的第一个片段,因此请在 onCreate 中的 MainActivity 中使用它,就在上面一行的正下方:

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();

然后在你的 HomeFragment 中使用 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();
}

编辑:

由于您需要为下一个活动和片段保存该值,您可以使用 SharedPreferences,像这样使用它。在您的 LoginActivity 中将其保存为:

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

然后在每个 activity/fragment 中你可以使用它来获取值:

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

这样你就可以在每个 activity 或片段中得到你的 user_id。另一种方法是将 user_id 从 LoginActivity 传递到 MainActivityIntent.putExtra(),如下所示:

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

然后在 MainActivity 中创建全局变量,如下所示:

public static int USER_ID = 0;

然后在onCreate里面这样写:

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

然后从每个 activity 或片段中,您可以像这样访问此值:

MainActivity.USER_ID //this will be value of user_id