SharedPreferences传递数据至导航抽屉TextView不显示问题求助
问题分析与解决方案
看起来你遇到的问题主要是两个核心错误导致的,我帮你拆解一下:
1. SharedPreferences 名称不匹配
你在注册页面(Register)写入数据时用的是"SharedPref"作为SharedPreferences的名称,但在导航页面(Navigation)读取时用的是"myPrefs"——这两个名称必须完全一致才能读写到同一个存储文件,不然就会出现"写了但读不到"的情况。
2. 错误获取导航头部的TextView
你的TextView是放在nav_header.xml里的,这个布局是NavigationView的子布局,直接在Activity里调用findViewById是找不到这些控件的,必须先获取NavigationView的头部View,再从里面查找控件。
修正后的代码示例
第一步:修正Register页面的SharedPreferences写入代码
把SharedPreferences的名称统一,同时推荐用apply()代替commit()(异步写入更高效,不会阻塞主线程):
buttonRegister.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (validate()) { String Email = editTextEmail.getText().toString(); String SID = editTextSID.getText().toString(); String Password = editTextPassword.getText().toString(); progressBar.setVisibility(View.VISIBLE); if (!sqliteHelper.ifUserRegistered(SID) && sqliteHelper.ifUserExists(SID) && !sqliteHelper.isEmailExists(Email)) { sqliteHelper.registerUser(new User(null, Email, SID, Password)); Snackbar.make(buttonRegister, "User created successfully! Please Login ", Snackbar.LENGTH_LONG).show(); String name = sqliteHelper.getUserNameFromSID(SID); String course = sqliteHelper.getUserCourseFromSID(SID); // 统一SharedPreferences名称为"UserPrefs" SharedPreferences myPrefs = getSharedPreferences("UserPrefs", MODE_PRIVATE); SharedPreferences.Editor editor = myPrefs.edit(); editor.putString("name", name); editor.putString("course", course); editor.putString("sid", SID); editor.putString("email", Email); editor.apply(); // 用apply()替代commit() new Handler().postDelayed(new Runnable() { @Override public void run() { finish(); } }, Snackbar.LENGTH_LONG); } } } });
第二步:修正Navigation页面的控件获取与SharedPreferences读取代码
先获取NavigationView的头部View,再从中查找TextView,同时统一SharedPreferences名称:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_navigation); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.addDrawerListener(toggle); toggle.syncState(); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); // 关键:先获取NavigationView的头部布局(索引0是第一个头部) View headerView = navigationView.getHeaderView(0); // 从头部View中查找对应的TextView txtName = headerView.findViewById(R.id.n); txtsid = headerView.findViewById(R.id.s); txtcourse = headerView.findViewById(R.id.c); txtemail = headerView.findViewById(R.id.e); // 用统一的名称读取SharedPreferences SharedPreferences myPrefs = getSharedPreferences("UserPrefs", MODE_PRIVATE); String name = myPrefs.getString("name", "未获取到姓名"); String course = myPrefs.getString("course", "未获取到课程"); String sid = myPrefs.getString("sid", "未获取到学号"); String email = myPrefs.getString("email", "未获取到邮箱"); // 直接设置文本即可,getString已经提供了默认值,无需额外判断contains txtName.setText(name); txtcourse.setText(course); txtsid.setText(sid); txtemail.setText(email); }
额外调试建议
- 在Register页面写入SharedPreferences前,打印
name和course的值,确认数据库方法getUserNameFromSID和getUserCourseFromSID确实返回了正确的数据:Log.d("DB_CHECK", "name: " + name + ", course: " + course); - 在Navigation页面读取后,也打印一下获取到的值,确认SharedPreferences读取正常:
Log.d("PREF_CHECK", "name: " + name + ", course: " + course + ", sid: " + sid + ", email: " + email);
这样修改后,你的导航抽屉里的文本应该就能正常显示了!
内容的提问来源于stack exchange,提问作者Prince Persia
相关产品推荐
相关产品推荐

