【问题标题】:How to update Fragment Pager Adapter from Fragments?如何从片段更新片段寻呼机适配器?
【发布时间】:2014-01-25 13:44:42
【问题描述】:

问题 ::

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

加载片段 ::

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 传递了接口对象(从我设置适配器的位置)

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

【问题讨论】:

    标签: android android-fragments android-viewpager fragmentpageradapter


    【解决方案1】:

    从例外情况来看,您似乎正试图在非 UI 线程中执行 UI 应用程序,这是被禁止的。尝试用这个封装你的 UI 代码(尤其是 TestActivity.java:238):

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

    【讨论】:

    • m 得到相同的异常。我想到的问题是我是否需要使用 FragmentStatePagerAdapter 而不是 FragmentPagerAdapter 来实现所需的结果。如果是,那么如何在适配器中动态添加/删除片段?请指导我。
    • FragmentStatePagerAdapter 和 FragmentPagerAdapter 的主要区别在于内存管理:FragmentPagerAdapter 加载所有 Fragment 并将它们保存在内存中,而不是 FragmentStatePagerAdapter。因此,如果您有固定数量的片段,请继续使用 FragmentPagerAdapter,否则请使用 FragmentStatePagerAdapter。顺便说一句,我已经编辑了我的答案。你能测试一下吗?
    • 我已经添加了你的代码,它工作正常,但我的问题是,如果我在点击更新后加载 4 个片段,我的标签不会重新生成。我正在使用片段状态寻呼机适配器,所以我的实现有什么问题吗?我仍然对如何使用适配器的 getItemPosition() 方法动态添加或删除片段感到困惑。你能在这个方向上帮助我吗?我已经编辑了我的代码。请看一下。
    • 正如我所说,如果您使用 FragmentStatePagerAdapter,片段不会保存在内存中,因此您需要重新生成它们,例如Fragment.instantiate(context, fragmentClassName, fragmentArgs);
    • 能否请您在我的 adpater 中给我看一些帮助我实施的 sn-p。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多