อัปเดตข้อมูลใน ListFragment เป็นส่วนหนึ่งของ ViewPager


142

ฉันใช้ ViewPager ความเข้ากันได้ v4 ใน Android My FragmentActivity มีกลุ่มของข้อมูลที่จะแสดงในรูปแบบที่แตกต่างกันในหน้าต่างๆใน ViewPager ของฉัน จนถึงตอนนี้ฉันมี ListFragment เดียวกัน 3 อินสแตนซ์ แต่ในอนาคตฉันจะมี ListFragments 3 อินสแตนซ์ที่ต่างกัน ViewPager อยู่บนหน้าจอโทรศัพท์แนวตั้งรายการไม่ได้อยู่ติดกัน

ตอนนี้ปุ่มบน ListFragment จะเริ่มกิจกรรมเต็มหน้าแยก (ผ่าน FragmentActivity) ซึ่งส่งคืนและ FragmentActivity แก้ไขข้อมูลบันทึกจากนั้นพยายามอัปเดตมุมมองทั้งหมดใน ViewPager ที่นี่ฉันอยู่ตรงไหน

public class ProgressMainActivity extends FragmentActivity
{
    MyAdapter mAdapter;
    ViewPager mPager;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
    ...
        mAdapter = new MyAdapter(getSupportFragmentManager());

        mPager = (ViewPager) findViewById(R.id.viewpager);
        mPager.setAdapter(mAdapter);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        ...
        updateFragments();
        ...
    }
    public void updateFragments()
    {
        //Attempt 1:
        //mAdapter.notifyDataSetChanged();
        //mPager.setAdapter(mAdapter);

        //Attempt 2:
        //HomeListFragment fragment = (HomeListFragment) getSupportFragmentManager().findFragmentById(mAdapter.fragId[0]);
        //fragment.updateDisplay();
    }

    public static class MyAdapter extends FragmentPagerAdapter implements
         TitleProvider
    {
      int[] fragId = {0,0,0,0,0};
      public MyAdapter(FragmentManager fm)
      {
         super(fm);
      }
      @Override
      public String getTitle(int position){
         return titles[position];
      }
      @Override
      public int getCount(){
         return titles.length;
      }

      @Override
      public Fragment getItem(int position)
      {

         Fragment frag = HomeListFragment.newInstance(position);
         //Attempt 2:
         //fragId[position] = frag.getId();
         return frag;
      }

      @Override
      public int getItemPosition(Object object) {
         return POSITION_NONE; //To make notifyDataSetChanged() do something
     }
   }

    public class HomeListFragment extends ListFragment
    {
    ...
        public static HomeListFragment newInstance(int num)
        {
            HomeListFragment f = new HomeListFragment();
            ...
            return f;
        }
   ...

ตอนนี้อย่างที่คุณเห็นความพยายามครั้งแรกของฉันคือการแจ้งให้ทราบ DataSetChanged บน FragmentPagerAdapter ทั้งหมดและสิ่งนี้แสดงให้เห็นว่าอัปเดตข้อมูลบางครั้ง แต่คนอื่น ๆ ที่ฉันได้รับ IllegalStateException: ไม่สามารถดำเนินการนี้หลังจาก

ความพยายามครั้งที่สองของฉันไม่ได้พยายามเรียกใช้ฟังก์ชันการปรับปรุงใน ListFragment ของฉัน แต่ getId ใน getItem กลับมา 0 ตามเอกสารที่ฉันพยายามโดย

การรับการอ้างอิงไปยัง Fragment จาก FragmentManager โดยใช้ findFragmentById () หรือ findFragmentByTag ()

แต่ฉันไม่รู้แท็กหรือรหัสของชิ้นส่วนของฉัน! ฉันมี android: id = "@ + id / viewpager" สำหรับ ViewPager และ android: id = "@ android: id / list" สำหรับ ListView ของฉันในรูปแบบ ListFragment แต่ฉันไม่คิดว่าสิ่งเหล่านี้มีประโยชน์

ดังนั้นฉันจะทำอย่างไร: ก) อัปเดตทั้ง ViewPager อย่างปลอดภัยในคราวเดียว (ส่งผู้ใช้กลับไปยังหน้าที่เขาเคยใช้มาก่อน) - ผู้ใช้เห็นการเปลี่ยนแปลงมุมมอง หรือโดยเฉพาะอย่างยิ่ง b) เรียกใช้ฟังก์ชันในแต่ละ ListFragment ที่ได้รับผลกระทบเพื่อปรับปรุง ListView ด้วยตนเอง

ความช่วยเหลือใด ๆ จะได้รับการยอมรับสุดซึ้ง!

คำตอบ:


58

พยายามบันทึกแท็กทุกครั้งที่มีการสร้างอินสแตนซ์ของ Fragement

public class MPagerAdapter extends FragmentPagerAdapter {
    private Map<Integer, String> mFragmentTags;
    private FragmentManager mFragmentManager;

    public MPagerAdapter(FragmentManager fm) {
        super(fm);
        mFragmentManager = fm;
        mFragmentTags = new HashMap<Integer, String>();
    }

    @Override
    public int getCount() {
        return 10;
    }

    @Override
    public Fragment getItem(int position) {
        return Fragment.instantiate(mContext, AFragment.class.getName(), null);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Object obj = super.instantiateItem(container, position);
        if (obj instanceof Fragment) {
            // record the fragment tag here.
            Fragment f = (Fragment) obj;
            String tag = f.getTag();
            mFragmentTags.put(position, tag);
        }
        return obj;
    }

    public Fragment getFragment(int position) {
        String tag = mFragmentTags.get(position);
        if (tag == null)
            return null;
        return mFragmentManager.findFragmentByTag(tag);
    }
}

นี่ดูโอเค แต่มันไม่ทำงานในชั้นเรียนของฉัน มันทำงานร่วมกับคุณ? ฉันยังได้รับnullส่วน
sandalone

1
มันใช้งานได้สำหรับฉันฉันใช้มันในหลายโครงการ คุณสามารถลองอ่านซอร์สโค้ดของ FragmentPagerAdapter และพิมพ์บันทึกเพื่อดีบัก
faylon

ขอบคุณทำงานเหมือนมีเสน่ห์แม้หลังจากหมุนหน้าจอแม้ฉันสามารถเปลี่ยนเนื้อหาของ FragmentA โดยใช้ MyActivity จาก FragmentB โดยใช้โซลูชันนี้
เมห์ Fanai

5
มันทำงานให้FragmentPagerAdaperแต่ล้มเหลวFragmentStatePagerAdaper( Fragment.getTag()เสมอกลับnull.
เครื่องยนต์ตากใบ

1
ฉันลองวิธีนี้แล้วสร้างวิธีการอัปเดตข้อมูลของชิ้นส่วน แต่ตอนนี้ฉันไม่สามารถเห็นมุมมองของชิ้นส่วน ฉันเห็นว่าข้อมูลกำลังจะแยกส่วน แต่มองไม่เห็น ความช่วยเหลือใด ๆ
Arun Badole

256

คำตอบ Barkside ทำงานด้วยFragmentPagerAdapterแต่ไม่ได้ทำงานกับเพราะมันไม่ได้ตั้งค่าแท็กบนเศษมันผ่านไปFragmentStatePagerAdapterFragmentManager

ด้วยFragmentStatePagerAdapterดูเหมือนว่าเราจะได้รับโดยใช้การinstantiateItem(ViewGroup container, int position)โทร positionมันกลับอ้างอิงถึงส่วนที่ตำแหน่ง หากFragmentStatePagerAdapterมีการอ้างอิงถึงส่วนที่เป็นปัญหาอยู่แล้วให้instantiateItemส่งคืนการอ้างอิงไปยังส่วนดังกล่าวและจะไม่เรียกร้องgetItem()ให้ยกตัวอย่างอีก

สมมติว่าฉันกำลังดูส่วนที่ 50 และต้องการเข้าถึงส่วนที่ 49 เนื่องจากพวกเขาอยู่ใกล้จึงมีโอกาสที่ดีที่ # 49 จะถูกสร้างอินสแตนซ์แล้ว ดังนั้น,

ViewPager pager = findViewById(R.id.viewpager);
FragmentStatePagerAdapter a = (FragmentStatePagerAdapter) pager.getAdapter();
MyFragment f49 = (MyFragment) a.instantiateItem(pager, 49)

5
ฉันจะทำให้มันง่ายขึ้นโดยเพียงแค่ทำ "a" a PagerAdapter (PagerAdapter a = pager.getAdapter ();) หรือแม้แต่ MyFragment f49 = (MyFragment) pager.getAdapter (). instantiateItem (pager, 49); instantiateItem () มาจาก PagerAdapter ดังนั้นคุณไม่ต้องพิมพ์ใหม่เพื่อโทรหา instantiateItem ()
Dandre Allison

12
... และในกรณีที่ทุกคนสงสัย ViewPager จะติดตามดัชนีของส่วนที่ดู (ViewPager.getCurrentItem ()) ซึ่งเป็น 49 ในตัวอย่างด้านบน ... แต่ฉันต้องบอกว่าฉัน ประหลาดใจที่ ViewPager API จะไม่ส่งคืนการอ้างอิงถึง Fragment ที่แท้จริงโดยตรง
mblackwell8

6
ด้วยการFragmentStatePagerAdapterใช้รหัสข้างต้นกับa.instantiateItem(viewPager, viewPager.getCurrentItem());(เพื่อกำจัด 49) ตามที่เสนอโดย @ mblackwell8 ทำงานได้อย่างสมบูรณ์
Cedric Simon

1
รอดังนั้นฉันต้องส่ง ViewPager ไปยังทุกส่วนที่มีเพียงเพื่อให้สามารถทำสิ่งต่าง ๆ กับมุมมองในส่วนได้หรือไม่ ขณะนี้ทุกสิ่งที่ฉันทำบนสร้างในหน้าปัจจุบันเกิดขึ้นในหน้าถัดไป ฟังดูรั่วไหลอย่างชาญฉลาด
G_V

เป็นสิ่งสำคัญที่จะกล่าวถึงว่าสายใด ๆ ที่instantiateItemควรล้อมรอบด้วยstartUpdate/ finishUpdateสาย รายละเอียดอยู่ในคำตอบของฉันสำหรับคำถามที่คล้ายกัน: stackoverflow.com/questions/14035090/…
morgwai

154

ตกลงฉันคิดว่าฉันพบวิธีที่จะดำเนินการตามคำขอข) ในคำถามของฉันเองแล้วฉันจะแบ่งปันเพื่อประโยชน์ของผู้อื่น แท็กของแฟรกเมนต์ภายใน ViewPager อยู่ในรูปแบบ"android:switcher:VIEWPAGER_ID:INDEX"โดยที่VIEWPAGER_IDอยู่R.id.viewpagerในเค้าโครง XML และ INDEX คือตำแหน่งใน viewpager ดังนั้นหากทราบตำแหน่ง (เช่น 0) ฉันสามารถแสดงในupdateFragments():

      HomeListFragment fragment = 
          (HomeListFragment) getSupportFragmentManager().findFragmentByTag(
                       "android:switcher:"+R.id.viewpager+":0");
      if(fragment != null)  // could be null if not instantiated yet
      {
         if(fragment.getView() != null) 
         {
            // no need to call if fragment's onDestroyView() 
            //has since been called.
            fragment.updateDisplay(); // do what updates are required
         }
      }

ฉันไม่รู้ว่านี่เป็นวิธีที่ถูกต้องหรือไม่ แต่จะทำจนกว่าจะมีสิ่งที่ดีกว่าแนะนำ


4
ฉันลงชื่อเข้าใช้เพียง +1 คำตอบและคำถามของคุณ
SuitUp

5
เนื่องจากนี่ไม่ได้อยู่ในเอกสารอย่างเป็นทางการฉันจะไม่ใช้มัน ถ้าพวกเขาเปลี่ยนแท็กในรีลีสในอนาคต
Thierry-Dimitri Roy

4
FragmentPagerAdapter มาพร้อมกับวิธีการคงที่ที่makeFragmentNameใช้ในการสร้างแท็กที่คุณสามารถใช้แทนวิธีการHomeListFragment fragment = (HomeListFragment) getSupportFragmentManager().findFragmentByTag(FragmentPagerAdapter.makeFragmentName(R.id.viewpager, 0));
แฮ็

8
@dgmltn makeFragmentNameเป็นprivate staticวิธีการดังนั้นคุณจึงไม่สามารถเข้าถึงได้
StenaviN

1
แม่ที่น่ารักของพระเยซูนี้ใช้งานได้! ฉันจะให้นิ้วของฉันข้ามและใช้มัน
Bogdan Alexandru

35

หากคุณถามฉันการแก้ปัญหาครั้งที่สองในหน้าด้านล่างการติดตามหน้าส่วนที่ "ใช้งาน" จะดีกว่า: http://tamsler.blogspot.nl/2011/11/android-viewpager-and-fragments-part -ii.html

คำตอบจาก barkside นั้นแฮ็คเกินไปสำหรับฉัน

คุณสามารถติดตามหน้าแฟรกเมนต์ "ที่ใช้งาน" ทั้งหมด ในกรณีนี้คุณติดตามหน้าแฟรกเมนต์ใน FragmentStatePagerAdapter ซึ่งใช้โดย ViewPager

private final SparseArray<Fragment> mPageReferences = new SparseArray<Fragment>();

public Fragment getItem(int index) {
    Fragment myFragment = MyFragment.newInstance();
    mPageReferences.put(index, myFragment);
    return myFragment;
}

หากต้องการหลีกเลี่ยงการอ้างอิงไปยังหน้าส่วน "ไม่ทำงาน" เราจำเป็นต้องใช้เมธอด destroyItem (... ) ของ FragmentStatePagerAdapter

public void destroyItem(View container, int position, Object object) {
    super.destroyItem(container, position, object);
    mPageReferences.remove(position);
}

... และเมื่อคุณต้องการเข้าถึงหน้าเว็บที่มองเห็นได้ในขณะนั้นคุณโทร:

int index = mViewPager.getCurrentItem();
MyAdapter adapter = ((MyAdapter)mViewPager.getAdapter());
MyFragment fragment = adapter.getFragment(index);

... ที่เมธอด getFragment (int) ของ MyAdapter มีลักษณะดังนี้:

public MyFragment getFragment(int key) {
    return mPageReferences.get(key);
}

"


วิธีการแก้ปัญหาที่สอง @Frank ในการเชื่อมโยงเป็นเรื่องง่าย ... ขอบคุณ .. :)!
theFlash

3
ดีกว่าถ้าคุณใช้ SparseArray แทนที่จะเป็นแผนที่
GaRRaPeTa

หรือSparseArrayCompat
Dori

อัปเดตคำตอบของฉันดังนั้นจึงใช้ SparseArray หากคุณกำหนดเป้าหมาย <11 ให้ใช้ SparseArrayCompat แทนเพราะคลาสที่อัปเดตในรุ่นที่ 11
Frank

2
สิ่งนี้จะทำลายวงจรชีวิตของเหตุการณ์ ดูstackoverflow.com/a/24662049/236743
Dori

13

โอเคหลังจากทดสอบวิธีการโดย @barkside ด้านบนฉันไม่สามารถทำงานกับแอปพลิเคชันของฉันได้ จากนั้นฉันจำได้ว่าแอป IOSched2012ใช้งานได้viewpagerเช่นกันและนั่นคือที่ฉันพบวิธีแก้ปัญหาของฉัน มันไม่ได้ใช้ ID ส่วนหรือแท็กใด ๆ เนื่องจากสิ่งเหล่านี้จะไม่ถูกจัดเก็บโดยviewpagerวิธีที่เข้าถึงได้ง่าย

นี่คือส่วนสำคัญจาก HomeActivity ของแอพ IOS ให้ความสนใจเป็นพิเศษกับความคิดเห็นเนื่องจากกุญแจนั้นอยู่:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // Since the pager fragments don't have known tags or IDs, the only way to persist the
    // reference is to use putFragment/getFragment. Remember, we're not persisting the exact
    // Fragment instance. This mechanism simply gives us a way to persist access to the
    // 'current' fragment instance for the given fragment (which changes across orientation
    // changes).
    //
    // The outcome of all this is that the "Refresh" menu button refreshes the stream across
    // orientation changes.
    if (mSocialStreamFragment != null) {
        getSupportFragmentManager().putFragment(outState, "stream_fragment",
                mSocialStreamFragment);
    }
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    if (mSocialStreamFragment == null) {
        mSocialStreamFragment = (SocialStreamFragment) getSupportFragmentManager()
                .getFragment(savedInstanceState, "stream_fragment");
    }
}

และเก็บอินสแตนซ์ของคุณFragmentsในFragmentPagerAdapterลักษณะที่ต้องการ:

    private class HomePagerAdapter extends FragmentPagerAdapter {
    public HomePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return (mMyScheduleFragment = new MyScheduleFragment());

            case 1:
                return (mExploreFragment = new ExploreFragment());

            case 2:
                return (mSocialStreamFragment = new SocialStreamFragment());
        }
        return null;
    }

นอกจากนี้อย่าลืมป้องกันFragmentสายของคุณเช่น:

    if (mSocialStreamFragment != null) {
        mSocialStreamFragment.refresh();
    }

Ryan นี่เป็นการบอกว่าคุณกำลังเอาชนะฟังก์ชั่นที่ ViewPager ใช้เพื่อ 'รักษา' อินสแตนซ์แฟรกเมนต์ของคุณและตั้งค่าเป็นตัวแปรสาธารณะที่สามารถเข้าถึงได้หรือไม่? เหตุใดคุณจึงกู้คืนอินสแตนซ์ถ้า (mSocialStreamFragment == null) {?
Thomas Clowes

1
นี่เป็นคำตอบที่ดีและการอ้างอิงแอป +1 สำหรับ io12 - ไม่แน่ใจว่าสิ่งนี้จะใช้ได้กับการเปลี่ยนแปลงวงจรชีวิตทั้งหมดหรือgetItem()ไม่เนื่องจากไม่ได้ถูกเรียกหลังจากที่ผู้ปกครองถูกสร้างขึ้นใหม่เนื่องจากการเปลี่ยนแปลงวัฏจักรชีวิต ดู stackoverflow.com/a/24662049/236743 ในตัวอย่างนี้มีการป้องกันบางส่วนสำหรับหนึ่งชิ้นส่วน แต่ไม่ใช่อีกสอง
Dori

2

คุณสามารถคัดลอกFragmentPagerAdapterและแก้ไขซอร์สโค้ดเพิ่มgetTag()เมธอด

ตัวอย่างเช่น

public abstract class AppFragmentPagerAdapter extends PagerAdapter {
private static final String TAG = "FragmentPagerAdapter";
private static final boolean DEBUG = false;

private final FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
private Fragment mCurrentPrimaryItem = null;

public AppFragmentPagerAdapter(FragmentManager fm) {
    mFragmentManager = fm;
}


public abstract Fragment getItem(int position);

@Override
public void startUpdate(ViewGroup container) {
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
    if (mCurTransaction == null) {
        mCurTransaction = mFragmentManager.beginTransaction();
    }

    final long itemId = getItemId(position);


    String name = getTag(position);
    Fragment fragment = mFragmentManager.findFragmentByTag(name);
    if (fragment != null) {
        if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
        mCurTransaction.attach(fragment);
    } else {
        fragment = getItem(position);
        if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);

        mCurTransaction.add(container.getId(), fragment,
                getTag(position));
    }
    if (fragment != mCurrentPrimaryItem) {
        fragment.setMenuVisibility(false);
        fragment.setUserVisibleHint(false);
    }

    return fragment;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    if (mCurTransaction == null) {
        mCurTransaction = mFragmentManager.beginTransaction();
    }
    if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
            + " v=" + ((Fragment) object).getView());
    mCurTransaction.detach((Fragment) object);
}

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
    Fragment fragment = (Fragment) object;
    if (fragment != mCurrentPrimaryItem) {
        if (mCurrentPrimaryItem != null) {
            mCurrentPrimaryItem.setMenuVisibility(false);
            mCurrentPrimaryItem.setUserVisibleHint(false);
        }
        if (fragment != null) {
            fragment.setMenuVisibility(true);
            fragment.setUserVisibleHint(true);
        }
        mCurrentPrimaryItem = fragment;
    }
}

@Override
public void finishUpdate(ViewGroup container) {
    if (mCurTransaction != null) {
        mCurTransaction.commitAllowingStateLoss();
        mCurTransaction = null;
        mFragmentManager.executePendingTransactions();
    }
}

@Override
public boolean isViewFromObject(View view, Object object) {
    return ((Fragment) object).getView() == view;
}

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

@Override
public void restoreState(Parcelable state, ClassLoader loader) {
}


public long getItemId(int position) {
    return position;
}

private static String makeFragmentName(int viewId, long id) {
    return "android:switcher:" + viewId + ":" + id;
}

protected abstract String getTag(int position);
}

แล้วขยายออกแทนที่วิธีนามธรรมเหล่านี้ไม่จำเป็นต้องกลัวการเปลี่ยนแปลงกลุ่ม Android

FragmentPageAdapter รหัสที่มาในอนาคต

 class TimeLinePagerAdapter extends AppFragmentPagerAdapter {


    List<Fragment> list = new ArrayList<Fragment>();


    public TimeLinePagerAdapter(FragmentManager fm) {
        super(fm);
        list.add(new FriendsTimeLineFragment());
        list.add(new MentionsTimeLineFragment());
        list.add(new CommentsTimeLineFragment());
    }


    public Fragment getItem(int position) {
        return list.get(position);
    }

    @Override
    protected String getTag(int position) {
        List<String> tagList = new ArrayList<String>();
        tagList.add(FriendsTimeLineFragment.class.getName());
        tagList.add(MentionsTimeLineFragment.class.getName());
        tagList.add(CommentsTimeLineFragment.class.getName());
        return tagList.get(position);
    }


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


}

1

ยังทำงานได้โดยไม่มีปัญหา:

ที่ใดที่หนึ่งในเค้าโครงของแฟรกเมนต์ของหน้า:

<FrameLayout android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone" android:id="@+id/fragment_reference">
     <View android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>
</FrameLayout>

ในส่วนของ onCreateView ():

...
View root = inflater.inflate(R.layout.fragment_page, container, false);
ViewGroup ref = (ViewGroup)root.findViewById(R.id.fragment_reference);
ref.setTag(this);
ref.getChildAt(0).setTag("fragment:" + pageIndex);
return root;

และวิธีการส่งคืน Fragment จาก ViewPager ถ้ามี:

public Fragment getFragment(int pageIndex) {        
        View w = mViewPager.findViewWithTag("fragment:" + pageIndex);
        if (w == null) return null;
        View r = (View) w.getParent();
        return (Fragment) r.getTag();
}

1

อีกวิธีหนึ่งคุณสามารถแทนที่setPrimaryItemวิธีการFragmentPagerAdapterเช่น:

public void setPrimaryItem(ViewGroup container, int position, Object object) { 
    if (mCurrentFragment != object) {
        mCurrentFragment = (Fragment) object; //Keep reference to object
        ((MyInterface)mCurrentFragment).viewDidAppear();//Or call a method on the fragment
    }

    super.setPrimaryItem(container, position, object);
}

public Fragment getCurrentFragment(){
    return mCurrentFragment;
}

0

ฉันต้องการให้แนวทางของฉันในกรณีที่สามารถช่วยเหลือผู้อื่นได้:

นี่คืออะแดปเตอร์เพจเจอร์ของฉัน:

 public class CustomPagerAdapter extends FragmentStatePagerAdapter{
    private Fragment[] fragments;

    public CustomPagerAdapter(FragmentManager fm) {
        super(fm);
        fragments = new Fragment[]{
                new FragmentA(),
                new FragmentB()
        };
    }

    @Override
    public Fragment getItem(int arg0) {
        return fragments[arg0];
    }

    @Override
    public int getCount() {
        return fragments.length;
    }

}

ในกิจกรรมของฉันฉันมี:

public class MainActivity {
        private ViewPager view_pager;
        private CustomPagerAdapter adapter;


        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        adapter = new CustomPagerAdapter(getSupportFragmentManager());
        view_pager = (ViewPager) findViewById(R.id.pager);
        view_pager.setAdapter(adapter);
        view_pager.setOnPageChangeListener(this);
          ...
         }

}

จากนั้นเพื่อให้ได้ชิ้นส่วนปัจจุบันสิ่งที่ฉันทำคือ:

int index = view_pager.getCurrentItem();
Fragment currentFragment = adapter.getItem(index);

1
สิ่งนี้จะแตกหลังจากวิธีวงจรชีวิตของกิจกรรม / ชิ้นส่วน
Dori

0

นี่เป็นวิธีการแก้ปัญหาของฉันเนื่องจากฉันไม่จำเป็นต้องติดตามแท็บของฉันและต้องการรีเฟรชทั้งหมด

    Bundle b = new Bundle();
    b.putInt(Constants.SharedPreferenceKeys.NUM_QUERY_DAYS,numQueryDays);
    for(android.support.v4.app.Fragment f:getSupportFragmentManager().getFragments()){
        if(f instanceof HomeTermFragment){
            ((HomeTermFragment) f).restartLoader(b);
        }
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.