How to update Fragment Pager Adapter from Fragments?

倾然丶 夕夏残阳落幕 提交于 2019-12-25 02:43:28

问题


Problem ::

I have one SherlockFragmentActivity in which i have added six fragments. Now out of six 3 fragments are added based on the conditions.

loading the fragments ::

private void loadFragments()
{
    try
    {
        dataHelper=new DataHelper(this);
        menuInfo=dataHelper.getTransMenuInfo();

        servicesName = new ArrayList<String>();
        servicesImage = new ArrayList<Integer>();

        if(menuInfo.contains("1"))
        {
            servicesName.add(dataHelper.getTransMenu_ModuleName("1"));
            servicesImage.add(R.drawable.icon);
        }
        if(menuInfo.contains("2"))
        {
            servicesName.add(dataHelper.getTransMenu_ModuleName("2"));
            servicesImage.add(R.drawable.icon);
        }
        if(menuInfo.contains("4"))
        {
            servicesName.add(dataHelper.getTransMenu_ModuleName("4"));
            servicesImage.add(R.drawable.icon);
        }

        dataHelper.close();
        servicesName.add("Fragment 4");
        servicesImage.add(R.drawable.wallet);

        servicesName.add("Fragment 5");
        servicesImage.add(R.drawable.reports);

        servicesName.add("Fragment 6");
        servicesImage.add(R.drawable.setting);

        List<Fragment> fragments = getFragments();

        if(fragments!=null && fragments.size()>0)
        {
            actionbartabmenuAdapter = new ActionBarTabMenuAdapter(getSupportFragmentManager(), fragments,this,servicesName,servicesImage);
            awesomePager.setAdapter(actionbartabmenuAdapter);
        }
    }
    catch(SQLiteException e)
    {
        e.printStackTrace();
    }
    catch(NullPointerException e)
    {
        e.printStackTrace();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

Adapter ::

private class ActionBarTabMenuAdapter extends FragmentPagerAdapter  
{
    Activity context;
    Context ctx;
    ArrayList<String> menuInfo;
    private List<Fragment> fragments;
    ArrayList<String> services;
    ArrayList<Integer> images;

    public ActionBarTabMenuAdapter(FragmentManager fm, List<Fragment> fragments,Context ctx,ArrayList<String> servicesName,ArrayList<Integer> servicesImage)
    {
        super(fm);
        this.context=(Activity) ctx;
        dataHelper=new DataHelper(ctx);
        menuInfo=dataHelper.getTransMenuInfo();
        dataHelper.close();

        this.services = servicesName;
        this.images = servicesImage;
        this.fragments = fragments;
        menuInfo.add("Wallet To Wallet");
        menuInfo.add("Reports");
        menuInfo.add("Settings");
    }

    @Override
    public int getCount() 
    {
        return fragments.size();
    }
    @Override
    public Fragment getItem(int position) 
    {
        return this.fragments.get(position);
    }
}

class ViewHolder {
    TextView Title, Description, ReadMore;
}

In last fragment(i.e. Fragment 6)in which i have one option for updation,now on click of that button i am removing my local database and get the new value from server and store it in my local database.

So before loading the fragments again,i am simply checking the conditions again and create the fragment list accordingly.so basically its not compulsory that fragment will be loaded 6 every time,it can be 3,4 or 5 also.

What i want ::

So i want to add or remove the fragment in view pager inside the fragment.On click of button,if i get the list 4 fragment then it should be 4 display that no. of fragment at that time(by onSwipe or onTabChanged).

What i have tried ?? ::

To achieve this, i have created one Interface with method loadMenu() like this ::

MenuInterface mInterface=new MenuInterface() {
    @Override
    public void loadMenu() {
        loadFragments();
    }
};

Now in the Fragment 6 i have passed the object of Interface from TestActivity(from where i am setting the adapter)

fList.add(SettingsListFragment.newInstance(this,"Settings",extraMessage,mInterface));

Now in Fragment 6's new InstanceMethod i am getting the object and call the loadMenu() method.

But now after applying this mechanism i am getting the following exception ....

Error ::

java.lang.IllegalStateException: Must be called from main thread of process
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1392)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139)
at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:321)
at com.example.testapp.TestActivity.loadFragments(TestActivity.java:238)
com.example.testapp.TestActivity.access$0(TestActivity.java:193)
at v.ButtonPayActivity$1.loadTransactionMenu(TestActivity.java:596)
at com.example.testapp.home.SettingsListFragment$4.run(SettingsListFragment.java:769)
at java.lang.Thread.run(Thread.java:1019)

EDIT ::

MenuInterface mMenuInterface=new MenuInterface() {
        @Override
        public void loadTransactionMenu() {
            runOnUiThread(new Runnable() {
                public void run() {
                    loadFragments();
                    if(actionbartabmenuAdapter!=null){
                        actionbartabmenuAdapter.notifyDataSetChanged();
                    }
                }
            });
        }
    };

Adapter ::

private class ActionBarTabMenuAdapter extends FragmentStatePagerAdapter  
{
    Activity context;
    Context ctx;
    ArrayList<String> menuInfo;
    private List<Fragment> fragments;
    ArrayList<String> services;
    ArrayList<Integer> images;

    public ActionBarTabMenuAdapter(FragmentManager fm, List<Fragment> fragments,Context ctx,ArrayList<String> servicesName,ArrayList<Integer> servicesImage)
    {
        super(fm);
        this.context=(Activity) ctx;
        dataHelper=new DataHelper(ctx);
        menuInfo=dataHelper.getTransMenuInfo();
        dataHelper.close();

        this.services = servicesName;
        this.images = servicesImage;
        this.fragments = fragments;
        menuInfo.add("Wallet To Wallet");
        menuInfo.add("Reports");
        menuInfo.add("Settings");
    }

    @Override
    public int getCount() 
    {
        return fragments.size();
    }
     public int getItemPosition(Object item) {
        //Fragment fragment = (Fragment)item;
        return POSITION_NONE;
    }

    @Override
    public Fragment getItem(int position) 
    {
        return this.fragments.get(position);
    }
}

class ViewHolder {
    TextView Title, Description, ReadMore;
}

回答1:


From the exception, it looks like you are trying to perform a UI application in a non-UI thread, which is forbidden. Try to encapsulate your UI code (especially TestActivity.java:238) with this :

MenuInterface mInterface=new MenuInterface() {
    @Override
    public void loadMenu() {
        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                loadFragments();
            }
        });
    }
};


来源:https://stackoverflow.com/questions/21351331/how-to-update-fragment-pager-adapter-from-fragments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!