0

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;
}
AndroidLearner
  • 4,500
  • 4
  • 31
  • 62

1 Answers1

0

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();
            }
        });
    }
};
pralonga
  • 106
  • 3
  • m getting the same exception.Question comes in my mind is that do i need to use FragmentStatePagerAdapter instead of FragmentPagerAdapter to achieve the desired result.If yes,then how to dynamically add/remove the fragment in adapter? Please guide me . – AndroidLearner Jan 28 '14 at 06:02
  • The main difference between FragmentStatePagerAdapter and FragmentPagerAdapter is the memory management : FragmentPagerAdapter loads all fragments and keep them in memory, not FragmentStatePagerAdapter. So if you have a fixed number of fragments, go on FragmentPagerAdapter, else on FragmentStatePagerAdapter. BTW I have edited my answer. Can you test it ? – pralonga Jan 28 '14 at 09:00
  • i have add your code and it works fine but my problem is that if i get the 4 fragment to load after on click of updation,my tabs not regenerated.i am using fragment state pager adapter,so do whts wrong with my implementation?and m still confused how to dynamically add or remove the fragment using getItemPosition() method of adapter.can you please help me in this direction? i have edited my code.please have a look. – AndroidLearner Jan 28 '14 at 09:06
  • As I said, if you use a FragmentStatePagerAdapter, fragments are not kept in memory, so you need to regenerate them, e.g. Fragment.instantiate(context, fragmentClassName, fragmentArgs); – pralonga Jan 28 '14 at 09:21
  • can please u show me some snippet in my adpater which help me to implement. – AndroidLearner Jan 28 '14 at 09:28
  • The best snippets you will find are the official ones : http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html and http://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html. Basically you need to transform your code to remove your fragment list, and instead create fragments each time getItem(int position) is called – pralonga Jan 28 '14 at 09:42
  • m still not able to get a clue from that links.can you please help me implement it in my code? – AndroidLearner Jan 28 '14 at 10:36