- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在我的应用程序中,我想在他登录后使用用户名的昵称和电子邮件更新抽屉导航。
从我的 MainActivity
我正在使用 startActivityForResult(intent, PICK_ACCOUNT_REQUEST);
方法启动一个 LoginActivity
让用户注册或登录。
LoginActivity
返回Intent data
结果(他的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 或类似的东西来动态更新 Navigation Drawer 的 RecyclerView.Adapter?
更多详情在下方
* 编辑 *
附言。我的抽屉导航是用 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
用户登录后动态更新数据结构,然后使用 SharedPreferences
使此更新持久化.
以下说明不起作用的原因:
String usr = data.getStringExtra("username");
String mal = data.getStringExtra("email");
this.NAME = usr; this.EMAIL=mal;
是因为 RecyclerView.Adapter mAdapter
(保存我的数据的对象)没有任何方法知道发生了某种变化,因此它没有更新它的数据。
为了让它知道某个变化确实发生了,首先我必须修改 ArrayList<DrawerItems> dataList
,其次我必须通知 Adapter
方法的变化 mAdapter.notifyItemChanged(0)
(类似于 Observer-Observable 模式的发生方式)。这样,抽屉导航会立即更新为新的 dataList
。 .
这还不是全部。只需更新 dataList
即时是一个不稳定的解决方案,因为每次用户更改 Activity 然后返回到 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
变得毫无意义。
出于这些原因,更新 MainActivity
没有 mAdapter.notifyItemChanged(0)
的帐户字段是不可能执行的,它即时完成了工作。
话虽如此,任何后续调用 onCreate()
MainActivity
中的方法将从 SharedPreferences()
加载帐户信息直到用户不会在其他地方注销。
关于android - 如何在 onActivityResult 方法收到 Intent 结果后设置 Observer 以更新抽屉导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29775020/
我是一名优秀的程序员,十分优秀!