当前位置: 动力学知识库 > 问答 > 编程问答 >

Android getting fragment that is in FragmentPagerAdapter

问题描述:

I have following problem:

I have one activity in which I have two tabs which are made both as fragments using FragmentPagerAdapter

In 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 FragmentPagerAdapter

And when I am trying to set tag I am getting following problem:

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:

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.

网友答案:

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

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

Reference: reusing fragments in a fragmentpageradapter

网友答案:

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.

网友答案:

I found a slightly less gross way to get a handle on a Fragment created by a FragmentPagerAdapter. Instead of imitating the way tags are created, override instantiateItem(), get the Fragment returned 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.

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:

public Object instantiateItem(View container, int position);

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

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

For that to work, the declaration for mContext needs to change to Activity, it's passed in as an Activity anyway:

private final Activity mContext;
网友答案:

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 FragmentPagerAdapter and i did communication between fragments

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

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

分享给朋友:
您可能感兴趣的文章:
随机阅读: