Android 获取 FragmentPagerAdapter 中的片段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11976397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:20:43  来源:igfitidea点击:

Android getting fragment that is in FragmentPagerAdapter

androidandroid-fragmentsfragmentpageradapter

提问by ziky90

I have following problem: I have one activity in which I have two tabs which are made both as fragments using FragmentPagerAdapterIn some moment I would like to change View of one of these fragments, but I am not able to findFragmentById()or findFragmentByTag()I am unable to set id, because I am not declaring Fragment in XML, because of the FragmentPagerAdapterAnd when I am trying to set tag I am getting following problem:

我有以下问题:我有一个活动,其中有两个选项卡,它们都使用FragmentPagerAdapter作为片段 在某些时候我想更改这些片段之一的视图,但我无法findFragmentById()findFragmentByTag( )我无法设置 id,因为我没有在 XML 中声明 Fragment,因为FragmentPagerAdapter而当我尝试设置标签时,我遇到了以下问题:

08-15 21:46:23.805: E/AndroidRuntime(9297): java.lang.IllegalStateException: Can't  change tag of fragment Companies{416d7b78 id=0x7f04002e companies}: was companies now android:switcher:2130968622:1

My code of the pager FragmentPagerAdapter:

我的寻呼机FragmentPagerAdapter代码:

public class TabsAdapter extends FragmentPagerAdapter implements    ActionBar.TabListener, ViewPager.OnPageChangeListener {
    private final FragmentActivity mContext;
    private final ActionBar mActionBar;
    private final ViewPager mViewPager;
    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();


    final class TabInfo {
        private final Class<?> clss;
        private final Bundle args;

        TabInfo(Class<?> _class, Bundle _args) {
            clss = _class;
            args = _args;
        }
    }

    public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
        super(activity.getSupportFragmentManager());
        mContext = activity;
        mActionBar = activity.getSupportActionBar();
        mViewPager = pager;
        mViewPager.setAdapter(this);
        mViewPager.setOnPageChangeListener(this);
    }

    public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
        TabInfo info = new TabInfo(clss, args);
        tab.setTag(info);
        tab.setTabListener(this);
        mTabs.add(info);
        mActionBar.addTab(tab);
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return mTabs.size();
    }

    @Override
    public Fragment getItem(int position) {
        TabInfo info = mTabs.get(position);
        FragmentTransaction ft=mContext.getSupportFragmentManager().beginTransaction();
        Fragment fragment=Fragment.instantiate(mContext, info.clss.getName(), info.args);

        if(position==1){
            ft.add(mViewPager.getId(), fragment, "companies");
        }else{
            ft.add(mViewPager.getId(), fragment);
        }
        Log.v("FRAGMENT ID", "fragment tag: "+fragment.getTag());
        ft.commit();
        Log.v("FRAGMENT ID", "fragment tag: "+fragment.getTag());
        return fragment;
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        mActionBar.setSelectedNavigationItem(position);
        new Thread(new Runnable() {

            @Override
            public void run() {
                MainActivity.this.hideKeyboard();

            }
        }).start();

    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        Object tag = tab.getTag();
        for (int i = 0; i < mTabs.size(); i++) {
            if (mTabs.get(i) == tag) {
                mViewPager.setCurrentItem(i);                   
            }
        }


    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {


    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }
}

Thank you in advance for your answers.

预先感谢您的回答。

回答by DeeV

The Fragments supplied by the FragmentPagerAdapter are auto-tagged when they're instantiated. You can retrieve the tag with this method:

FragmentPagerAdapter 提供的 Fragment 在实例化时会自动标记。您可以使用此方法检索标签:

private static String makeFragmentName(int viewPagerId, int index) {
     return "android:switcher:" + viewPagerId + ":" + index;
}

Reference: reusing fragments in a fragmentpageradapter

参考:在 fragmentpageradapter 中重用片段

回答by Daniel De León

With this function you can find the fragment by pager adapter position.

使用此功能,您可以通过寻呼机适配器位置找到片段。

public Fragment findFragmentByPosition(int position) {
    FragmentPagerAdapter fragmentPagerAdapter = getFragmentPagerAdapter();
    return getSupportFragmentManager().findFragmentByTag(
            "android:switcher:" + getViewPager().getId() + ":"
                    + fragmentPagerAdapter.getItemId(position));
}

Sample code for v4 support api.

v4 支持 api 的示例代码。

回答by nash

I found a slightly less gross way to get a handle on a Fragmentcreated by a FragmentPagerAdapter. Instead of imitating the way tags are created, override instantiateItem(), get the Fragmentreturned by the superclass, and save the tag in TabInfo. This works for me on API >= 15, may work with lower. This still makes some assumptions about private code.

我发现了一种稍微不那么粗暴的方法来处理FragmentFragmentPagerAdapter. 而不是模仿创建标签的方式,覆盖instantiateItem(),获取Fragment超类返回的 ,并将标签保存在TabInfo. 这在 API >= 15 上适用于我,可能适用于较低的版本。这仍然对私有代码做出了一些假设。

static final class TabInfo {
    private final Class<?> clss;
    private final Bundle args;
    private String tag; // ** add this

    TabInfo(Class<?> _class, Bundle _args) {
        clss = _class;
        args = _args;
    }
}


@Override
public Object instantiateItem(ViewGroup container, int position) {
    final Fragment fragment = (Fragment) super.instantiateItem(container, position);
    final TabInfo info = mTabs.get(position);
    info.tag = fragment.getTag(); // set it here
    return fragment;
}

Or in API < 16, I think instantiateItem()takes a View()instead of ViewGroup(), like this:

或者在 API < 16 中,我认为instantiateItem()需要一个View()而不是ViewGroup(),如下所示:

public Object instantiateItem(View container, int position);

Then allow a way to get the Fragment, keeping the hack contained.

然后允许一种方法来获取Fragment,保持 hack 被包含。

public Fragment getFragment(int index) {
    return mContext.getFragmentManager().findFragmentByTag(mTabs.get(index).tag);
}

For that to work, the declaration for mContextneeds to change to Activity, it's passed in as an Activityanyway:

为此,mContext需要将for 的声明更改为ActivityActivity无论如何它都作为一个传入:

private final Activity mContext;

回答by Chriss Villegas

A simpler approach to this is to get the Tags directly from the Fragment Manager; like this:

一个更简单的方法是直接从片段管理器中获取标签;像这样:

fm.getFragments().get(0).getTag()

You can replace the position, depending on the fragment you need the tag for. Hope this helps others!.

您可以替换位置,具体取决于您需要标签的片段。希望这对其他人有帮助!

回答by Suruchi Mahajan

It is very late to answer this question but i have searched a lot no one tell me the exact answer, Might be some one found it useful.

回答这个问题已经很晚了,但我已经搜索了很多没有人告诉我确切答案,可能有人发现它有用。

I have set my fragments through FragmentPagerAdapterand i did communication between fragments

我已经设置了我的片段FragmentPagerAdapter并且我在片段之间进行了通信

https://developer.android.com/training/basics/fragments/communicating.html#Deliver

https://developer.android.com/training/basics/fragments/communicating.html#Deliver

following this link and for FindFragmentById i simply used viewpager.getId()on the mainactivity .

按照这个链接和 FindFragmentById 我只是在 mainactivity 上使用了viewpager.getId()