android – 如何在onActivityResult方法收到Intent结果后设置Observer以更新导航抽屉
作者:互联网
在我的应用程序中,我想在用户登录后用用户名的昵称和电子邮件更新导航抽屉.
在我的MainActivity中,我使用startActivityForResult(intent,PICK_ACCOUNT_REQUEST)启动LoginActivity;方法
让用户注册或登录.
在LoginActivity将Intent数据结果(他的NAME和EMAIL)返回给MainActivity之后,调用onActivityResult()方法,并尝试使用新接收的数据更新类的全局变量NAME和EMAIL,但没有成功:每次注册或记录两个字段都不会在导航抽屉中显示.这是我的代码:
在MainActivity类的开头,我分配了两个变量:
String NAME = "Sign in", EMAIL = "";
这两个值将插入我的导航抽屉中.从LoginActivity收到结果后,我想在onActivityResult()方法中更新这两个字段.这条路:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
// Check which request we're responding to
if (requestCode == PICK_ACCOUNT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
String usr = data.getStringExtra("username");
String mal = data.getStringExtra("email");
this.NAME = usr;this.EMAIL=mal;
}
}
}
没有成功,事实上在完成LoginActivity之后,我仍然可以看到导航抽屉中的旧值,因为我无法从MainActivity访问保存用户名和密码的2 EditText.实际上,2个EditText在RecyclerView.ViewHolder中进行管理.
如何设置Observer或类似的东西以dinamically更新我的Navigation Drawer的RecyclerView.Adapter?
更多细节如下
*编辑*
PS.我的导航抽屉是用RecyclerView实现的,因此我在适配器内部有一个RecyclerView.Adapter类和一个RecyclerView.ViewHolder类.在MainActivity中我有这样的代码:
public class MainActivity extends ActionBarActivity{
ArrayList<DrawerItem> dataList;
RecyclerView mRecyclerView; // Declaring RecyclerView
RecyclerView.Adapter mAdapter; // Declaring Adapter For Recycler View
RecyclerView.LayoutManager mLayoutManager; // Declaring Layout Manager as a linear layout manager
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mTitle, mDrawerTitle;
Toolbar toolbar;
String NAME, EMAIL; int AVATARresID; //TODO update Navigation Drawer fields
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Assigning the toolbar object to the view
and setting the the Action bar to our toolbar */
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// enable ActionBar app icon to behave as action to toggle nav drawer
getSupportActionBar().setDisplayHomeAsUpEnabled(true); //pulsante drawer
getSupportActionBar().setHomeButtonEnabled(true); //pulsante dietro
//Initializing
mTitle = mDrawerTitle = getTitle();
AVATARresID = R.mipmap.aka;
// Add Drawer Item to dataList
dataList = new ArrayList<>();
dataList.add(new DrawerItem(NAME,EMAIL,AVATARresID));
dataList.add(new DrawerItem("Account", R.mipmap.ic_account));
dataList.add(new DrawerItem("Tuoi Tour", R.mipmap.ic_events));
dataList.add(new DrawerItem("Prenota Tour", R.mipmap.ic_action_search));
// dataList.add(new DrawerItem("My Favorites")); // adding a header to the list
dataList.add(new DrawerItem("Others")); // adding a header to the list
dataList.add(new DrawerItem("Contatti", R.mipmap.ic_about));
dataList.add(new DrawerItem("Tutorial", R.mipmap.ic_help));
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView);
mRecyclerView.setHasFixedSize(true);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mAdapter = new MyAdapter(dataList, mSelectedPositions);
mRecyclerView.setAdapter(mAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout,toolbar,
R.string.drawer_open, R.string.drawer_close){
@Override
public void onDrawerOpened(View drawerView) {...}
@Override
public void onDrawerClosed(View drawerView) {...}
};
// Drawer Listener set to the Drawer toggle
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
mRecyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(this, mRecyclerView, new RecyclerItemClickListener.OnItemClickListener() {...});
}
}
解决方法:
我已经解决了!
我的解决方案有两个:我在用户登录后动态更新dataList dataStructure,然后使用SharedPreferences使此更新持久化.
以下说明不起作用的原因:
String usr = data.getStringExtra("username");
String mal = data.getStringExtra("email");
this.NAME = usr; this.EMAIL=mal;
是因为RecyclerView.Adapter mAdapter(持有我的数据的对象)没有任何方法知道发生了某些变化,因此它没有更新其数据.
为了知道实际发生了某种变化,首先我必须修改ArrayList< DrawerItems> dataList,其次我必须使用方法mAdapter.notifyItemChanged(0)通知适配器更改(类似于Observer-Observable模式的情况).这样,导航抽屉立即使用新的dataList进行更新.
这不是全部.动态更新dataList是一个易变的解决方案,因为每次用户更改活动然后返回MainActivity时,NavigationDrawer会再次使用旧数据进行初始化(在过去的状态中丢失任何获取的信息,因此加载空的NAME和EMAIL变量).因此,为了使帐户信息持久化,必须将它们保存到SharedPreferences中.
这是onActivityResult()的代码,它可以动态更新导航抽屉,并将帐户信息持久保存到SharedPreferences中:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
// Check which request we're responding to
if (requestCode == PICK_ACCOUNT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
String usr = data.getStringExtra("username");
String mail = data.getStringExtra("email");
SharedPreferences usrData = getSharedPreferences(usr_loggedin, MODE_PRIVATE);
SharedPreferences.Editor editor = usrData.edit();
editor.clear();
editor.putBoolean("usraccount",true).commit();
editor.putString("username",usr).commit();
editor.putString("email",mail).commit();
dataList.remove(0);
dataList.add(0,new DrawerItem(usr,mail,AVATARresID));
mAdapter.notifyItemChanged(0);
}
}
}
这是在MainActivity中检查用户是否登录的位置,如果是,则从SharedPreferences加载帐户信息:
//...
String NAME,EMAIL; int AVATARresID;
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
//Initializing
SharedPreferences usrData = getSharedPreferences(usr_loggedin, MODE_PRIVATE);
AVATARresID = R.mipmap.aka;
// Add Drawer Item to dataList
dataList = new ArrayList<>();
dataList = prepareDatalist(dataList, NAME, EMAIL, AVATARresID);
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView);
mRecyclerView.setHasFixedSize(true);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mAdapter = new MyAdapter(dataList, mSelectedPositions);
if(usrData.contains("usraccount")){
String usr,mail;
usr = usrData.getString("username",usr_loggedin);
mail = usrData.getString("email",usr_loggedin);
dataList.remove(0);
dataList.add(0,new DrawerItem(usr,mail,AVATARresID));
mAdapter.notifyItemChanged(0);
}
mRecyclerView.setAdapter(mAdapter);
//... ...
}
作为一个方面,为了解决我的问题,我必须注意(通过大量的调试),在onActivityResult()方法完成后,MainActivity的onCreate()不再被调用,并且类的执行以onActivityResult()的结尾.
因此,我不能仅依赖SharedPreferences来更新用户的信息.实际上即使SharedPreferences通过在项目中的所有位置提供所有需要的信息来完成他们的工作,当第二次不调用onCreate方法时,也无法使用新信息更新RecyclerView.Adapter.没有额外的代码,使SharedPreferences变得毫无意义.
出于这些原因,如果没有mAdapter.notifyItemChanged(0),即可快速完成工作,则无法更新MainActivity的帐户字段.
话虽如此,在MainActivity中对onCreate()方法的任何后续调用都会从SharedPreferences()加载帐户信息,直到用户不会在其他地方注销.
标签:android,android-studio,navigation-drawer,android-recyclerview,observer-pattern 来源: https://codeday.me/bug/20190609/1205145.html