2013-06-25 95 views
1

我正在构建一个应用程序,该应用程序在ViewPager中显示不同片段。我这些片段添加到ViewPager这样的:如何在ViewPager中获取当前可见片段的实例:

public void intialiseViewPager() 
{ 
    List<Fragment> fragments = new Vector<Fragment>(); 
    numberOfTabs = application.currentReport.getODTabsList().size(); 
    for (int i = 0; i < numberOfTabs; i++)  
    { 
     ODTab tempTab = application.currentReport.getODTabsList().get(i); 
     if (tempTab.getTabType().equals(ODGrid.XML_GRID_ELEMENT)) 
     { 
      GridFragment gridFragment = GridFragment.newInstance(tempTab.getTabId()); 
      fragments.add(gridFragment); 
     } 
     else if (tempTab.getTabType().equals(ODChart.XML_CHART_ELEMENT)) 
     { 
      NewChartFragment chartFragment = NewChartFragment.newInstance(tempTab.getTabId()); 
      fragments.add(chartFragment); 
     } 
    } 
    Log.d(TAG, "Current report fragments set to adapter: "+fragments.toString()); 
    mPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fragments); 
    mViewPager = (ViewPager)findViewById(R.id.pager); 
    mViewPager.setAdapter(mPagerAdapter); 
    mViewPager.setOffscreenPageLimit(0); 
    mViewPager.setOnPageChangeListener(this); 
} 

正如你可以看到我传递给片段的字符串(tempTab.getTabId()),在这一行:

GridFragment gridFragment = GridFragment.newInstance(tempTab.getTabId()); 

在片段本身我这样做对其进行初始化:

public static final GridFragment newInstance(String tabId) 
{ 
    GridFragment f = new GridFragment(); 
    Bundle bdl = new Bundle(2); 
    bdl.putString(TAB_ID, tabId); 
    f.setArguments(bdl); 
    return f; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    String tabId = getArguments().getString(TAB_ID); 
    if (application.currentReport != null) 
    { 
     this.odTab = application.currentReport.getODTabByTabId(tabId); 
    } 
    else 
    { 
     startActivity(new Intent(getActivity(), LoginScrActivity.class)); 
    } 
    super.onCreate(savedInstanceState); 
} 

这一切是为了不重写片段的默认空构造进行,因为据我所知,这是不推荐。

现在我需要得到odTab对象,我投入到当前可见的片段在这条线的实例:

this.odTab = application.currentReport.getODTabByTabId(tabId); 

可能有人请向我解释如何可以这样做? 如何获取当前可见的片段实例,以便我可以将odTab对象拉出来?

UPDATE: 随着我这里收到我增加了一个odTab对象实例被称为currentVisibleTab和我设置odTab的实例这样的应用程序类的建议:

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) 
{ 
    Log.d(TAG, "setUserVisibleHint invoked!"); 
    super.setUserVisibleHint(isVisibleToUser); 
    if (isVisibleToUser) 
    { 
     if (odTab != null && getActivity() != null) 
     { 
      Log.d(TAG, "Currently visable tab: "+odTab.getTabTitle()); 
      application.currentVisibleTab = odTab; 
     } 
    } 
} 

UPDATE2: 这是我ViewPagerAdapter

public class ViewPagerAdapter extends FragmentPagerAdapter 
{ 
private List<Fragment> fragments; 

/** 
* @param fm 
* @param fragments 
*/ 
public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) { 
    super(fm); 
    this.fragments = fragments; 
} 

/* (non-Javadoc) 
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int) 
*/ 

@Override 
public Fragment getItem(int position) { 
    return this.fragments.get(position); 
} 

/* (non-Javadoc) 
* @see android.support.v4.view.PagerAdapter#getCount() 
*/ 

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

@Override 
public int getItemPosition(Object object) { 
    return POSITION_NONE; 
} 

public void removeAllFragments() 
{ 
    this.fragments.clear(); 
} 

public void addFragmentsListToAdapter(List<Fragment> fragments) 
{ 
    this.fragments.addAll(fragments); 
} 

public List<Fragment> getFragments() 
{ 
    return fragments; 
} 
} 

其中我有一个由ViewPager显示的片段List。该列表被初始化这样的:

List<Fragment> fragments = new Vector<Fragment>(); 

我不明白的是我如何去触发此列表中的接口方法的当前片段的引用。 这不是一个相关的问题,但也许你知道答案:ListVector有什么区别?

我仍然检查这个选项。

+0

http://stackoverflow.com/questions/10024739/how-to-determine-when-fragment-becomes-visible-in-viewpager。检查这 – Raghunandan

+0

嘿@Raghunandan,我试过“setUserVisibleHint”选项,但由于某种原因没有设法得到它的权利。所以我觉得这不是方法。我会再看看这个。 –

+0

重写'setUserVisibleHint'并在'setUserVisibleHint'内使用'GridFragment.newInstance(tabId)'。记录实例并检查。没有测试过一个建议。 – Raghunandan

回答

6

我找到当前可见片段的方式是使用setUserVisibleHint和接口返回ViewPager。该方法在fragment类中。覆盖它并使用界面回拨到您的ViewPager。如果片段可见 - 即它返回true - 那么只需使用对片段的引用(来自支持适配器的列表或者作为实例变量存储的列表),以便从片段本身获取所需的任何内容。我已经添加了下面的代码。

声明一个与你想要做的任何相关的接口。在我的情况下,我使用它来禁用ViewPager默认的x方向侦听器,当一个Google Map实例可见时,这样地图的滚动不会触发片段的变化。

public interface OnMapFragmentVisibleListener{ 
    public void mapVisible(boolean visible); 
} 

在片段:

@Override 
public void onAttach(Activity activity){ 
    super.onAttach(activity); 
    try{ 
     mapFragmentVisibilityListener = (OnMapFragmentVisibleListener) activity; 
     isAttached = true; //flag for whether this fragment is attached to pager 
    } catch (ClassCastException e){ 
     throw new ClassCastException(activity.toString() + " must implement interface onAttach"); 
    } 


@Override 
public void setUserVisibleHint(boolean isVisibleToUser){ 
    if(isVisibleToUser && isAttached){ //if listener is called before fragment is attached will throw NPE 
     mapFragmentVisibilityListener.mapVisible(true); 
    } 
} 

一件事,直到我尝试这样的是不是很明显是增加了isAttached变量。我也重写onAttach方法的片段,并在调用它时将其设置为true。否则会发生什么情况,您的片段将对用户可见,并尝试在界面初始化之前调用接口到ViewPager

在我ViewPager我只是执行OnMapFragmentVisibleListener然后添加所需的方法

@Override 
public void mapVisible(boolean visible) { 
    if(visible) 
    viewPager.allowSwipe(false); //turn off viewPager intercept touch if map visible 
} 

在我来说,我用它来关闭ViewPager刷卡功能。但是,我可以轻松地调用我的mapFragment中的公共方法。我碰巧在我的ViewPager中有3个片段,我保留参考。

更新

要查找当前显示的,你首先需要找出正在显示该片段中的片段。您可以通过多种方式来做到这一点。最简单的方法是使用您之前创建的界面将某些描述符传回给您的ViewPager/FragmentActivity

public interface OnFragmentVisibleListener{ 
    public void fragmentVisible(boolean true, String tag); 
} 

您的设置的问题是,您使用的是Vector这实在是一个同步的List来存储您的片段引用。因此,以后您无法通过其定位碎片的关键值。片段有能力通过在片段事务中创建的标记添加到片段活动时标识。但是,在ViewPager安装中,您不会单独添加碎片,因此在事务过程中不能添加标签。

我的解决方案一直支持我的BasePagerAdapterHashMap其中我存储由唯一键标识的每个片段。

LinkedHashMap<String, Fragment> tabs = new LinkedHashMap<String, Fragment>(); 
tabs.put("Frag1", fragment1); 
tabs.put("Frag2", fragment2); 
tabs.put("Frag3", fragment3); 

然后我用这个在适配器:

private class BasePagerAdapter extends FragmentPagerAdapter{ 

    private LinkedHashMap<String, Fragment> tabs; 

    public BasePagerAdapter(LinkedHashMap<String, Fragment> tabMap, FragmentManager fm) 
    { 
     super(fm); 
     this.tabs = tabMap; 
    } 

    // other basic methods 

因为您的引用存储到键值,可以很容易地找到你要找的,因为你可以通过键从搜索片段HashMap并返回。

如果您无法更改设置以脱离Vector,您需要(1)跟踪以哪种顺序添加哪个片段(假设片段未被动态添加和删除),以便您可以通过索引或(2)分开引用每个片段。

private Fragment x; 

//in onCreate 
x = new Fragment(); 

//in interface 
if(tag.equals("x"){ 
    x.doSomething(); 
} 

另一件让这更容易的事情就是我的碎片都是分类的。例如。每个执行不同功能的片段都有自己的类。由于每个类只有一个实例,所以很容易找到,因为我没有任何重复。如果您使用Fragment类的所有通用成员,则只需实现一些标记系统即可实现以上方法之一。

+0

请给我们提供一些关于你如何在片段和viewPager端类上做的代码片段? –

+0

刚刚添加 - 对不起,当我回答时我没有在我的办公桌前发帖。 – Rarw

+0

谢谢,男士......非常详细的答案,如果这能解决我的问题,我会测试并接受你的答案,同时+1为你的努力。 –

3

可以使用viewpager.getCurrentItem()方法,通过以下方式获得当前可见的片段:

片段FR = getSupportFragmentManager()findFragmentByTag( “机器人:切换:” + R.id.pager +“ :“+ mViewPager.getCurrentItem());

感谢,

Sulabh

相关问题