如何从Fragments更新Fragment Pager Adapter?

时间:2014-01-25 13:44:42

标签: android android-fragments android-viewpager fragmentpageradapter

问题::

我有一个SherlockFragmentActivity,其中我添加了六个片段。 现在根据条件添加了6个片段。

加载片段::

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();
    }
}

适配器::

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;
}

在最后一个片段(即片段6)中,我有一个更新选项,现在单击该按钮我将删除我的本地数据库并从服务器获取新值并将其存储在我的本地数据库中。

所以在再次加载片段之前,我只是再次检查条件并相应地创建片段列表。所以基本上它不是必须每次加载片段6,它也可以是3,4或5。

我想要什么::

所以我想在片段内的视图寻呼机中添加或删除片段。单击按钮,如果我得到列表4片段,那么它应该是4显示否。当时的片段(通过onSwipe或onTabChanged)。

我试过了什么? ::

为实现这一目标,我创建了一个方法loadMenu()的接口,如下所示::

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

现在在Fragment 6中,我从TestActivity传递了Interface的对象(从我设置适配器的地方)

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

现在在Fragment 6的新InstanceMethod中我得到了对象并调用了loadMenu()方法。

但现在应用此机制后,我得到以下异常....

错误::

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)

编辑::

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

适配器::

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 个答案:

答案 0 :(得分:0)

从异常看,您似乎正在尝试在非UI线程中执行UI应用程序,这是禁止的。尝试使用以下方法封装您的UI代码(尤其是TestActivity.java:238):

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