Get Fragment by Tag

限于喜欢 提交于 2019-12-22 08:35:15

问题


I am using a FragmentPagerAdapter to create a multi-pages UI with different fragments. What I want to do is to find the Fragment using the position of the Fragment.

I have applied the method of finding the nametag of fragments and use .FindFragmentbyTag() but the .FindFragmentbyTag always return me null value. The structure seems to be correct so I am not sure why I get null values, please look through and help is appreciated.

Here is the code

MainActivity.java
public void onCreate(Bundle savedInstanceState) {
    this.getSupportFragmentManager();
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    MainActivity.instance=this;
    //Initialize pager
    vpPager = (ViewPager)findViewById(R.id.mypager);
    pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
    vpPager.setAdapter(pagerAdapter);
    this.mapFragment = (MapFragment)this.findFragmentByPosition(0);
    this.drFragment = (DRFragment)this.findFragmentByPosition(1);
    this.sensorFragment = (SensorFragment)this.findFragmentByPosition(2);
    ......
}

protected Fragment  findFragmentByPosition(int position) {
    int pagerid = this.vpPager.getId();
    long pagerAdapterid = this.pagerAdapter.getItemId(position);
    return getSupportFragmentManager().findFragmentByTag("android:switcher:" + pagerid + ":" + pagerAdapterid + "");
}

MyPagerAdapter.java
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.view.View;

public class MyPagerAdapter extends FragmentPagerAdapter {
    private static final String TAG = "TM_PageAdapter";
    private static int numItems = 3;

    public MyPagerAdapter(FragmentManager fragmentManager){
        super(fragmentManager);
    }

    public int getCount() {
        return numItems;
    }

    @Override
    public Fragment getItem(int position) {
        switch(position){
            case 0:
                return MapFragment.newInstance(0, "Map Information");
            case 1:
                return DRFragment.newInstance(1, "DR Information");
            case 2: 
                return SensorFragment.newInstance(2, "Sensor Information");
            default: 
                return null;
        }
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch(position){
            case 0:
                return "Map Information";
            case 1:
                return "DR Information";
            case 2: 
                return "Sensor Information";
            default:
                return null;
        }
    }

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


    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == ((View) arg1);

    }

    @Override
    public Parcelable saveState() {
        return null;
    }

Here is one of the code of the .newInstance:

public static MapFragment newInstance(int position, String title){
    MapFragment mapFragment = new MapFragment();
    Bundle args = new Bundle();
    args.putInt("current_page", 0);
    args.putString("page_tile", "Map Information");
    mapFragment.setArguments(args);
    return mapFragment;
}

回答1:


In findFragmentByPosition, you are not using the index, when looking for the fragment:

getSupportFragmentManager().findFragmentByTag("android:switcher:" + pagerid + ":" + pagerAdapterid + "");

The second one should be the index, not the pagerAdapterId. So the correct code would be:

getSupportFragmentManager().findFragmentByTag("android:switcher:" + pagerid + ":" + position);

There's also no need to concatenate the last empty string.




回答2:


I used this approach in the past and it worked quite well.

In your adapter you can declare a instance variable as follow:

private Map<Integer, Fragment> mPageReferenceMap = new HashMap<Integer, Fragment>();

In your getItem() put a reference of the fragment in the map

mPageReferenceMap.put(position, f);

Override the InstantiateItem method:

/**
 * After an orientation change, the fragments are saved in the adapter, and
 * I don't want to double save them: I will retrieve them and put them in my
 * list again here.
 */
@Override
public Object instantiateItem(ViewGroup container, int position) {
   Fragment fragment = (Fragment) super.instantiateItem(container, position);
   mPageReferenceMap.put(position, fragment);
   return fragment;
}

Override the onDestroyItem to clean up references:

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
    mPageReferenceMap.remove(position);
}

And finally get the fragment depending on its position:

public Fragment getFragment(int key) {
    return mPageReferenceMap.get(key);
}

Hope it helps.




回答3:


It seems like the thing that caused my reference to go to null is because Loading fragments is done in background and when I reference those fragments the loading is not yet complete (Thank you Daniel Zolnai for poiting that out, I would give you right answer tick if u put it as a answer) My thoughts for solution is now:

-Load all the pages you have if the number of pages are small using (ViewPager).setOffScreenLimit(int limit)

-Pause the main activity and wait till all pages are loaded then continue on.

Now I am stuck at the second part, if anyone know how to wait or delay the MainActivty for loading pages to complete or force the loading task to foreground, it would be a big help to me, thanks



来源:https://stackoverflow.com/questions/24798145/get-fragment-by-tag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!