如何设置观察员更新导航抽屉后onActivityResult方法的收到了意向的结果 [英] How to set an Observer to Update Navigation Drawer after onActivityResult method's received an Intent result
问题描述
在我的应用程序,我想与用户名的昵称和电子邮件更新导航抽屉后,他登录。
这是我的 MainActivity
我开始一个 LoginActivity
与 startActivityForResult(意向,PICK_ACCOUNT_REQUEST );
方法
让用户注册或登录。
在 LoginActivity
返回意图数据
的结果(他的名称
和 EMAIL
)返回 MainActivity
,该方法 onActivityResult()
被调用,并在那里我尝试更新类的全局变量名称
和 EMAIL
与新接收数据,没有成功:每个注册后或登录这两个字段从不显示在导航抽屉里。这是我的code:
在 MainActivity
类的开头我给两个变量:
字符串名称=登录,EMAIL =;
这两个数值都插在我的抽屉式导航。当我收到 LoginActivity
的结果,我想以更新 onActivityResult()
法这两个领域。通过这种方式:
@覆盖
保护无效onActivityResult(INT申请code,INT结果code,意图数据){
//检查它要求我们应对
如果(要求code == PICK_ACCOUNT_REQUEST){
//确保申请成功
如果(结果code == RESULT_OK){
//用户选择了一个联系人。
字符串USR = data.getStringExtra(用户名);
字符串MAL = data.getStringExtra(电子邮件);
this.NAME = USR; this.EMAIL =发作;
}
}
}
没有成功,其实完成后 LoginActivity
我还是可视化的导航抽屉内的旧值,因为我不能够访问2的EditText控股的用户名和密码由 MainActivity
。事实上,2的EditText在里面 RecyclerView.ViewHolder
管理。
如何设置观察员或类似dinamically更新我的导航抽屉的RecyclerView.Adapter什么?
更多细节如下
*编辑*
诗。我的导航抽屉与RecyclerView实现的,因此,我有一个 RecyclerView.Adapter
类和 RecyclerView.ViewHolder
类内部的适配器。在 MainActivity
我有这个code:
公共类MainActivity扩展ActionBarActivity {
ArrayList的< DrawerItem>数据列表;
RecyclerView mRecyclerView; //声明RecyclerView
RecyclerView.Adapter mAdapter; //声明适配器对于回收站查看
RecyclerView.LayoutManager mLayoutManager; //声明布局管理器为线性布局管理器
私人DrawerLayout mDrawerLayout;
私人ActionBarDrawerToggle mDrawerToggle;
私人的CharSequence mTitle,mDrawerTitle;
工具条工具栏;
字符串名称,EMAIL; INT AVATARresID; // TODO更新导航抽屉领域
@覆盖
保护无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.activity_main);
/ *分配工具栏物体向视图
和操作栏设置为我们的工具栏* /
工具栏=(栏)findViewById(R.id.tool_bar);
setSupportActionBar(工具栏);
//使动作条的应用程序图标,表现为动作切换导航抽屉
getSupportActionBar()setDisplayHomeAsUpEnabled(真)。 // pulsante抽屉
getSupportActionBar()setHomeButtonEnabled(真)。 // pulsante dietro
//初始化
mTitle = mDrawerTitle =的getTitle();
AVATARresID = R.mipmap.aka;
//添加抽屉项目DataList控件
DataList控件=新的ArrayList<>();
dataList.add(新DrawerItem(姓名,电子邮件,AVATARresID));
dataList.add(新DrawerItem(账户,R.mipmap.ic_account));
dataList.add(新DrawerItem(Tuoi之旅,R.mipmap.ic_events));
dataList.add(新DrawerItem(prenota之旅,R.mipmap.ic_action_search));
// dataList.add(新DrawerItem(我的收藏)); //添加头部列表
dataList.add(新DrawerItem(其他)); //添加头部列表
dataList.add(新DrawerItem(Contatti,R.mipmap.ic_about));
dataList.add(新DrawerItem(教程,R.mipmap.ic_help));
mRecyclerView =(RecyclerView)findViewById(R.id.RecyclerView);
mRecyclerView.setHasFixedSize(真正的);
mDrawerLayout =(DrawerLayout)findViewById(R.id.drawer_layout);
mAdapter =新MyAdapter(DataList控件,mSelectedPositions);
mRecyclerView.setAdapter(mAdapter);
mLayoutManager =新LinearLayoutManager(本);
mRecyclerView.setLayoutManager(mLayoutManager);
mDrawerToggle =新ActionBarDrawerToggle(这一点,mDrawerLayout,工具栏,
R.string.drawer_open,R.string.drawer_close){
@覆盖
公共无效onDrawerOpened(查看drawerView){...}
@覆盖
公共无效onDrawerClosed(查看drawerView){...}
};
//抽屉监听器设置为抽屉切换
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
mRecyclerView.addOnItemTouchListener(
新RecyclerItemClickListener(此,mRecyclerView,新RecyclerItemClickListener.OnItemClickListener(){...});
}
}
我已经解决了!
我的解决办法是双重的:我都更新 DataList控件
数据结构在用户登录后飞,然后使这个更新执着与共享preferences
。
为什么下面的说明是不工作的原因:
字符串USR = data.getStringExtra(用户名);
字符串MAL = data.getStringExtra(电子邮件);
this.NAME = USR; this.EMAIL =发作;
是因为 RecyclerView.Adapter mAdapter
(对象握着我的数据)没有任何办法知道某一个变化发生,因此它没有更新其数据。
有关它知道,某种变化已经实际发生的,首先我不得不修改的ArrayList< DrawerItems> DataList控件
,其次我必须通知适配器
与方法的改变 mAdapter.notifyItemChanged(0)
(类似于它与观察者可观察的模式如何发生的)。这样,抽屉式导航栏会立即更新为新的 DataList控件
。
这还不是全部。只需更新 DataList控件
上飞是一个动荡的解决方案,因为每个用户更改活动,然后回到时间 MainActivity
,系统中NavigationDrawer再次与旧的数据初始化(在过去的状态丢失任何获取的信息,因此装载空的姓名和电子邮件变量)。因此,为了使帐户信息持续有必要将它们保存到共享preferences
。
这是 onActivityResult的code()
更新导航抽屉上飞,也坚持储蓄帐户的信息转换成共享preferences
:
@覆盖
保护无效onActivityResult(INT申请code,INT结果code,意图数据){
//检查它要求我们应对
如果(要求code == PICK_ACCOUNT_REQUEST){
//确保申请成功
如果(结果code == RESULT_OK){
//用户选择了一个联系人。
字符串USR = data.getStringExtra(用户名);
字符串的邮件= data.getStringExtra(电子邮件);
共享preferences usrData = getShared preferences(usr_loggedin,MODE_PRIVATE);
共享preferences.Editor编辑器= usrData.edit();
editor.clear();
editor.putBoolean(usraccount,真).commit();
editor.putString(用户名,USR).commit();
editor.putString(邮件,邮件).commit();
dataList.remove(0);
dataList.add(0,新DrawerItem(USR,邮件,AVATARresID));
mAdapter.notifyItemChanged(0);
}
}
}
这就是在 MainActivity
我检查,如果用户登录,如果是这样的帐户信息是从共享preferences装:
// ...
字符串名称,EMAIL; INT AVATARresID;
@覆盖
保护无效的onCreate(包savedInstanceState){
// ...
//初始化
共享preferences usrData = getShared preferences(usr_loggedin,MODE_PRIVATE);
AVATARresID = R.mipmap.aka;
//添加抽屉项目DataList控件
DataList控件=新的ArrayList<>();
DataList控件= prepareDatalist(DataList控件,姓名,电子邮件,AVATARresID);
mRecyclerView =(RecyclerView)findViewById(R.id.RecyclerView);
mRecyclerView.setHasFixedSize(真正的);
mDrawerLayout =(DrawerLayout)findViewById(R.id.drawer_layout);
mAdapter =新MyAdapter(DataList控件,mSelectedPositions);
如果(usrData.contains(usraccount)){
字符串USR,邮件;
USR = usrData.getString(用户名,usr_loggedin);
邮件= usrData.getString(电子邮件,usr_loggedin);
dataList.remove(0);
dataList.add(0,新DrawerItem(USR,邮件,AVATARresID));
mAdapter.notifyItemChanged(0);
}
mRecyclerView.setAdapter(mAdapter);
// ......
}
作为一个侧面没有,解决我的问题,我不得不通知(具有很大的调试),该方法在 onActivityResult()
完成后,MainActivity的的onCreate()
不叫第二次和类的执行与 onActivityResult月底结束()
。
由于这个原因,我不能只依赖于共享preferences
更新用户的信息。事实上,即使共享preferences
做好他们的工作通过提供所有需要的信息无处不在的项目,当的onCreate
方法不叫第二次,就没有办法更新 RecyclerView.Adapter
与新的信息,也没有额外的code,使得共享preferences
变得毫无意义。
由于这些原因,更新 MainActivity
的帐户域是不可能没有的 mAdapter.notifyItemChanged(0)
,是说上飞工作。
说了这么多,在 MainActivity
的任何后续调用的onCreate()
方法将加载从帐户信息共享preferences()
,直到用户将不能注销别的地方。
In my app I want to update the Navigation Drawer with the username's nickname and email after he's logged in.
From my MainActivity
I am starting a LoginActivity
with the startActivityForResult(intent, PICK_ACCOUNT_REQUEST);
method
to get the users registered or logged in.
After the LoginActivity
returns the Intent data
result (his NAME
and EMAIL
) back to MainActivity
, the method onActivityResult()
is called and there I try to update the class' global variables NAME
and EMAIL
with the newly received data, with no success: after every registration or log the two fields never show in the navigation drawer. Here's my code:
In the beginning of the MainActivity
class I assign two variables:
String NAME = "Sign in", EMAIL = "";
These two values are inserted in my navigation drawer. After I receive the result from LoginActivity
I want to update these two fields in the onActivityResult()
method. This way:
@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;
}
}
}
with no success, in fact after completion of LoginActivity
I still visualize the old values within the Navigation Drawer because I'm not able to access the 2 EditText holding Username and Password from MainActivity
. In fact the 2 EditText are managed inside RecyclerView.ViewHolder
.
How can I set an Observer or something similar to dinamically update my Navigation Drawer's RecyclerView.Adapter?
More details below
* EDIT *
Ps. My Navigation Drawer is implemented with RecyclerView, I therefore have a RecyclerView.Adapter
class and a RecyclerView.ViewHolder
class inside the adapter. In MainActivity
I have this code:
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() {...});
}
}
I've solved it!
My solution is twofold: I both update the dataList
dataStructure on the fly after the user's login, and then make this update persistent with SharedPreferences
.
The reason why the following instructions were not working:
String usr = data.getStringExtra("username");
String mal = data.getStringExtra("email");
this.NAME = usr; this.EMAIL=mal;
was because the RecyclerView.Adapter mAdapter
(the object holding my data) did not have any way to know that a certain change took place, and it therefore didn't update its data.
For it to know that a certain change had actually occurred, first of all I had to modify the ArrayList<DrawerItems> dataList
, and secondly I had to notify the Adapter
of the change with the method mAdapter.notifyItemChanged(0)
(similarly to how it happens with the Observer-Observable pattern). This way the Navigation Drawer is immediately updated with the new dataList
.
This wasn't all. Simply updating the dataList
on the fly was a volatile solution, since every time the user changes activity and then goes back to the MainActivity
, the NavigationDrawer is initialized again with the old data (losing any acquired information during past states, and therefore loading empty NAME and EMAIL variables). Thus, in order to make the account information persistent was necessary to save them into SharedPreferences
.
This is the code of onActivityResult()
updating the navigation drawer on the fly and also saving the account's information persistently into 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);
}
}
}
This is where in MainActivity
I check if the user is logged in, and if so the account information are loaded from 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);
//... ...
}
As a side not, to solve my problems I had to notice (with a great deal of debugging) that after the method onActivityResult()
has finished, the MainActivity's onCreate()
is not called a second time and the execution of the class ends with the end of onActivityResult()
.
For this reason I couldn't rely only on SharedPreferences
to update the user's information. In fact even though the SharedPreferences
do their job well by making all the needed information available everywhere in the project, when the onCreate
method isn't called a second time, there would be no way of update the RecyclerView.Adapter
with the new information and no extra code, making the SharedPreferences
to become pointless.
For these reasons, updating MainActivity
's account fields was impossible to perform without the mAdapter.notifyItemChanged(0)
, which did the job on the fly.
Having said that, any subsequent call to onCreate()
method in MainActivity
would load the account information from SharedPreferences()
until the user wouldn't logout somewhere else.
这篇关于如何设置观察员更新导航抽屉后onActivityResult方法的收到了意向的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!