2015-11-14 88 views
3

我試過了,但是錯誤的列表綁定到recyclerview。我也嘗試了SparseArray,即使這不起作用。當我開始Mainactivity時,getItem()會被調用兩次。我如何處理返回的職位? 我試圖返回viewpager currentItem,即使這不起作用。FragmentStatePagerAdapter處理getItem()位置

MainActivity

public class PagerAdapter extends FragmentStatePagerAdapter { 
    int mNumOfTabs; 


    public PagerAdapter(android.support.v4.app.FragmentManager fragmentManager, int tabCount) 
    { 
     super(fragmentManager); 
     this.mNumOfTabs = tabCount;  
    } 

    @Override 
    public Fragment getItem(int position) { 

     return Categories_Fragment.newInstance(position); 

    } 

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

} 

Categories_Fragment

public class Categories_Fragment extends Fragment 
{ 
private RecyclerView lvMessages; 
private int fromPage; 


public static Categories_Fragment newInstance(int num) { 
    Categories_Fragment f = new Categories_Fragment(); 

    // Supply num input as an argument. 
    Bundle args = new Bundle(); 
    args.putInt("from", num); 
    f.setArguments(args); 

    return f; 
} 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 
    fromPage = getArguments().getInt("from"); 


} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) {  
    // TODO Auto-generated method stub 
    View rootView = inflater.inflate(R.layout.categories_filter, container, false); 
    lvMessages = (RecyclerView)rootView.findViewById(R.id.lv_categories_filter); 

    LinearLayoutManager x = new LinearLayoutManager(getActivity()); 
    x.setOrientation(LinearLayoutManager.VERTICAL); 

    lvMessages.setLayoutManager(x); 


    return rootView; 
} 


@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onActivityCreated(savedInstanceState); 

    // bind different data to the RecyclerView based on fromPage value. 

    } 

} 
+0

嘗試將片段設置爲靜態:'公共靜態類Categories_Fragment擴展Fragment' –

+0

請張貼在那裏引用PagerAdapter代碼。我認爲主要問題是「getItem()被調用兩次...」 –

+0

這應該適合你。實現一個僅在片段可見時才被調用的接口。 http://stackoverflow.com/a/24386516/2102304 – shreyas

回答

2

這裏是什麼可能是意料之外...

@Override 
public void setUserVisibleHint(boolean isVisible) { 
    super.setUserVisibleHint(isVisible); 
    if (isVisible) { 
     // bind to stuff using value of fromPage from here 
    } 
} 

public void setUserVisibleHint (boolean isVisibleToUser)爲系統設置有關此片段的用戶界面當前是否可見的提示。此提示默認爲true,並且在片段實例狀態保存和恢復中保持不變。

什麼可能是問題(如果我正確理解你的問題)是尋呼機正在傳遞其「最後知道」的位置,這並不一定意味着當前正在顯示的片段的位置在設備屏幕上。

UPDATE:這裏有ViewPager處理相同片段但傳遞給它不同的數據的完整的例子:

public class ViewPagerAdapter extends FragmentStatePagerAdapter { 

    private JSONArray itemsArray; 
    private int fragmentId; 

    public ViewPagerAdapter(JSONArray itemsArray, int fragmentId, FragmentManager manager) { 
     super(manager); 
     this.itemsArray = itemsArray; 
     this.fragmentId = fragmentId; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     JSONObject itemObject = new Listing(itemsArray, position).getObject(); 
     Bundle bundle = new Bundle(); 
     bundle.putString("item_object", itemObject.toString()); 
     bundle.putInt("item_position", position); 
     bundle.putInt("total_items", getCount()); 
     bundle.putInt("fragment_Id", fragmentId); 
     Fragment fragment = new ListingFragment(); 
     fragment.setArguments(bundle); 
     return fragment; 
    } 

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

} 

這裏的房源片段(減去不重要位):

public class ListingFragment extends Fragment { 

    private Listing listing; 

    private String itemObject; 
    private int itemPosition; 
    private int totalItems; 
    private int fragmentId; 

    public ListingFragment() { } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Bundle bundle = getArguments(); 
     itemObject = bundle.getString("item_object"); 
     itemPosition = bundle.getInt("item_position"); 
     totalItems = bundle.getInt("total_items"); 
     fragmentId = bundle.getInt("fragment_Id"); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
     View view = ... 
     // nothing special to see here, just the usual stuff 
     return view; 
    } 

    @Override 
    public void setUserVisibleHint(boolean isVisible) { 
     super.setUserVisibleHint(isVisible); 
     if (isVisible) { 
      // send fragmentID to wherever you want to use it 
      // such as your recyclerview/adapter from here 
     } 
    } 

} 

我希望這個例子能夠提供一些亮點,我知道它對我有用而且沒有失敗。

+0

我認爲這將工作,如果我有不同種類的片段。但是我使用了傳遞給它的參數的單個片段。 – Anirudh

+0

它應該與單個片段一起工作。我有一個與獲取新聞標題的應用程序完全相同的問題:每個片段都是相同的,包含一個recyclerview,但根據我在setUserVisibleHint()內傳遞的類別ID,顯示的標題不同。如果我從getItem()傳遞了ID,則該片段從下一個類別(或之前的一個,取決於我滑動的方式)加載項目,因爲它保存的ID是在尋呼機中緩存的最後一個,而不是當前可見片段的ID。 – mjp66

+0

Neil Agarwal的回答下面解釋了多個getItem()調用的方式,因爲該尋呼機正在獲取當前可見的片段以及後面的片段。 – mjp66

0

您懷疑您創建了一個名爲PagerAdapter的類,它是一個Android抽象類。將它重命名爲像MyPagerAdapter這樣的唯一名稱。

+0

試圖更改名稱。不起作用。 – Anirudh

+0

@Anirudh,它仍然調用getItem()兩次?或者根本沒有? –

0

爲什麼爲getItem()被調用兩次的原因是因爲在ViewPager分配給offScreenPageLimit的默認值。

您可以offScreenPageLimit設置1或0使用setOffscreenPageLimit(INT限制)ViewPager類的方法,這將解決您的調用getItem()時兩次的問題。

因此,如果getItem()被調用一次,那麼您將在片段中獲得正確的位置值,並且您的問題將得到解決。

結賬的鏈接方法定義和描述

http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit(int)

+0

甚至在發佈問題之前嘗試了此操作。不適合我。 – Anirudh

0

使用FragmentStatePagerAdapterHashMap<Integer,Demo_Fragment>

public class ViewPagerAdapter extends FragmentStatePagerAdapter { 
     List<String> mList; 

     public ViewPagerAdapter(FragmentManager fm, List<String> list) { 
      super(fm); 
      mList = list; 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      String title = mList.get(position); 
      return title; 
     } 

     public int getCount() { 
      return mList.size(); 
     } 

     public Fragment getItem(int position) { 
      Demo_Fragment fragment = new Demo_Fragment(); 
      Bundle bundle = new Bundle(); 
      bundle.putString("text",mList.get(position)); 
      fragment.setArguments(bundle); 
      fragment.setTags(position); 
      mPageReferenceMap.put(position, fragment); 

      return fragment; 
     } 

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

     public int getItemPosition(Object item) { 
      Demo_Fragment fragment = (Demo_Fragment) item; 
      int position = fragment.getTags(); 
      if (position >= 0) { 
       return position; 
      } else { 
       return POSITION_NONE; 
      } 
     } 
    } 

對於獲得片段

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

對於獲取當前片段

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
      @Override 
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
      } 

      @Override 
      public void onPageSelected(int position) { 
       final Demo_Fragment demo_Fragment = getFragment(mViewPager.getCurrentItem()); 
       final String str = mArrString.get(mViewPager.getCurrentItem()); 
       demo_Fragment.updateView(str); 
       showDialog(); 
       mRunnable = new Runnable() { 
        @Override 
        public void run() { 
         randomGenerator = new Random(); 
         randomInt = randomGenerator.nextInt(10000); 
         demo_Fragment.updateView(str +"\n" +randomInt+"-Updated Value"); 
         hideDialog(); 
        } 
       }; 
       mHandler.postDelayed(mRunnable, 2000); 


      } 

      @Override 
      public void onPageScrollStateChanged(int state) { 
      } 
     }); 

工作的例子 - Click Here

相關問題