如何设置观察员更新导航抽屉后onActivityResult方法的收到了意向的结果 [英] How to set an Observer to Update Navigation Drawer after onActivityResult method's received an Intent result

查看:180
本文介绍了如何设置观察员更新导航抽屉后onActivityResult方法的收到了意向的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序,我想与用户名的昵称和电子邮件更新导航抽屉后,他登录。

这是我的 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的< D​​rawerItem>数据列表;
    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< D​​rawerItems> 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆