2013-11-02 32 views
9

我建立一个应用程序,使用碎片和一个MainActivity是表示同ViewPager不同片段复制一个典型的MVC应用程序的行为。在ViewPager如何更新,刷新片段由主要活动编程

的问题是,不明白我怎么能编程方式更新片段与新的片断更新ViewPager改变

例如,我有这个Fragment,显示的图表,(在我的意图),当我从主调用setFragment(int interval, Point[] snodePoint),图表应该以ViewPager

public class LineFragment extends Fragment { 
    static int interval; 
    static Point snodePoints[]; 


    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     final View v = inflater.inflate(R.layout.fragment_linegraph, container, 
       false); 
     Bundle bundle = this.getArguments(); 
     ChartConfig cg = bundle.getParcelable("FragmentData"); 

     snodePoints = cg.getPoints(); 
     interval= cg.getInterval(); 
     Line l = new Line(); 

     for(int i=0; i<snodePoints.length; i++){ 
      LinePoint p = new LinePoint(); 
      Point sp=snodePoints[i]; 
      p.setX(sp.getX()); 
      p.setY(sp.getY()); 
      l.addPoint(p) 
     } 
     l.setColor(getResources().getColor(R.color.green)); 

     LineGraph li = (LineGraph) v.findViewById(R.id.linegraph); 
     li.addLine(l); 
     li.setRangeY(0, interval); 
     li.setLineToFill(0); 

     li.setOnPointClickedListener(new OnPointClickedListener() { 

      @Override 
      public void onClick(int lineIndex, int pointIndex) { 
       // TODO Auto-generated method stub 

      } 

     }); 

     return v; 
    } 
} 

更新在几句话,我需要

  • 1-根据主要活动收到的数据创建一个片段。
  • 2更改主要活动的片段,每次的数据恰好 像setFragment(...)用新数据(由主总是产生)。

我怎么能这样做?

与FragmentAdapter

public class MainActivity extends FragmentActivity { 

ViewPager mViewPager; 
MyFragmentAdapter mMyFragmentAdapter; 

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

    mViewPager = (ViewPager) findViewById(R.id.view_pager); 
    final ActionBar bar = this.getActionBar(); 
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

    LineFragment lineFrag = new LineFragment(); 
    BarFragment barFrag = new BarFragment(); 
    PieFragment pieFrag = new PieFragment(); 

    mMyFragmentAdapter = new MyFragmentAdapter(this, mViewPager); 
    mMyFragmentAdapter.addTab(bar.newTab().setText("Line"), LineFragment.class, 
      null, lineFrag); 
    mMyFragmentAdapter.addTab(bar.newTab().setText("Bar"), BarFragment.class, 
      null, barFrag); 
    mMyFragmentAdapter.addTab(bar.newTab().setText("Pie"), PieFragment.class, 
      null, pieFrag); 
    mViewPager.setOffscreenPageLimit(mMyFragmentAdapter.getCount() - 1); 
} 

public static class MyFragmentAdapter extends FragmentStatePagerAdapter implements 
     ActionBar.TabListener, ViewPager.OnPageChangeListener { 

    private final MainActivity mContext; 
    private final ActionBar mActionBar; 
    private final ViewPager mViewPager; 
    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); 
    private final ArrayList<Fragment> mFrag = new ArrayList<Fragment>(); 

    static final class TabInfo { 
     private final Class<?> clss; 
     private final Bundle args; 

     TabInfo(Class<?> _class, Bundle _args) { 
      clss = _class; 
      args = _args; 
     } 
    } 

    public MyFragmentAdapter(MainActivity activity, ViewPager pager) { 
     super(activity.getSupportFragmentManager()); 
     mContext = activity; 
     mActionBar = activity.getActionBar(); 
     mViewPager = pager; 
     mViewPager.setAdapter(this); 
     mViewPager.setOnPageChangeListener(this); 
    } 

    public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args, 
      Fragment frag) { 
     TabInfo info = new TabInfo(clss, args); 
     tab.setTag(info); 
     tab.setTabListener(this); 
     mTabs.add(info); 
     mFrag.add(frag); 
     mActionBar.addTab(tab); 
     notifyDataSetChanged(); 
    } 

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

    @Override 
    public Fragment getItem(int position) { 
     TabInfo info = mTabs.get(position); 
     Bundle args = new Bundle(); 
     ChartConfig cg = new ChartConfig(interval, snodePoint); 
     args.putParcelable("FragmentData", cg); 
     Fragment f = mFrag.get(position); 
     f.setArguments(args); 

     return f; 
    } 

    @Override 
    public void onPageScrolled(int position, float positionOffset, 
      int positionOffsetPixels) { 
    } 

    @Override 
    public void onPageSelected(int position) { 
     mActionBar.setSelectedNavigationItem(position); 

    } 

    @Override 
    public void onPageScrollStateChanged(int state) { 
    } 

    public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) { 
     Object tag = tab.getTag(); 
     for (int i = 0; i < mTabs.size(); i++) { 
      if (mTabs.get(i) == tag) { 
       mViewPager.setCurrentItem(i); 
      } 
     } 
    } 

    public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) { 
    } 

    @Override 
    public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) { 
    } 

} 

}

的第一次,我创建片段的主要活动,主要活动通过overrided getItem(int position)参数的片段成功,但如果我尝试要更改数据,同样如果我尝试调用适配器mMyFragmentAdapter上的notifyDataSetChanged(),则不会发生任何反应,并且ViewPager中的片段将继续使用创建中传递的相同数据。

EDIT

继约片段更新其它问题出现了一些部分码我还试图此

public void update() { 
     try{ 
      LineFragment fragment = 
         (LineFragment) getSupportFragmentManager().findFragmentByTag(
            "android:switcher:"+R.id.view_pager+":0"); 
        if(fragment != null) 
        { 
        if(fragment.getView() != null) 
        { 

         fragment.updateDisplay(); 
        } 
        } 
     } 
     catch(RuntimeException e){ 
      e.printStackTrace(); 
     } 

    } 

假设0是第一个片段-Tab键片段I的ID(”我不确定这种操作),但不会调用fragment.updateDisplay();

+0

您没有搜到过很多吗? http://stackoverflow.com/questions/7379165/update-data-in-listfragment-as-part-of-viewpager – Luksprog

+1

@Luksprog嗯这与我所要求的有点不同。我需要了解Fragment如何通过main传递数据,也许我错过了一些东西,但是我真的不明白我怎么能这样做。如果我尝试为我的'LineFragment'创建一个自定义构造函数,我得到错误'这个片段应该提供一个默认构造函数(一个没有参数的公共构造函数)' – AndreaF

+0

@AndreaF检查对话框片段http://developer.android.com/ reference/android/app/DialogFragment.html使用一个静态的'static MyDialogFragment newInstance(int num)'来传递参数,然后使用set和get参数。你传递的值就像'newInstance(value)',如果这就是你通过传递数据从主到片段 – Raghunandan

回答

3

我需要了解该片段可以如何获得通过的数据通过主, 也许我失去了一些东西,但我真的不明白怎么会 我做到这一点。

由此看来,您希望在创建Fragment时传递数据。如果这是你想你不应该让一个自定义的构造函数(一般为Fragment你应该只有默认的无参数的构造函数(因为该平台需要它来重新创建Fragment在特定的时间))的东西。

相反,你应该要么通过在Bundle数据:

@Override 
public Fragment getItem(int position) { 
    switch (position) { 
     //... 
     Bundle args = new Bundle(); 
     args.put("a_string_representing_theKey", data) 
     LineFragment f = new LineFragment(); 
     f.setArguments(args); 
     return f; 
     //... 
    } 
} 

如果数据可以放在一个Bundle(见Bundle类的put...方法,所有原始数据+对象这只会工作,那是Parcelable)。在片段中,您可以使用来检索参数。

您还可以使Fragment直接从Activity检索数据:

// in the lifecycle method where you want the data 
((MainActivity)getActivity()).getDataForFragment(); // use the data 

例如,我有这样的片段,显示的图表,(在我的意图) 当调用setFragment(INT间隔,点[] snodePoint) 主,图表应更新在ViewPager

你似乎自相矛盾。对于这个用法,我链接到的问题中的代码当然只是调用你当前的setFragment()方法,不会做任何事情,因为你只需更新两个变量的值,你需要让UI知道变化(如调用另一个变量方法重新创建视图层次结构,在图表视图上设置新值并调用invalidate()等)。

编辑:

在我挂应该工作的问题中所使用的代码,但你不使用正确的代码。你有一个FragmentStatePagerAdapter,但您使用的是一个FragmentPagerAdapter的代码将无法正常工作:在每边

FragmentStatePagerAdapter a = (FragmentStatePagerAdapter) mViewPager.getAdapter(); 
LineFragment f = (LineFragment) a.instantiateItem(pager, thePositionYouWant); 

记住上面的代码将只能用于可见片段加1个片段中,其他片段将不可用(并且由于用户没有看到它们或不能立即移动到它们不应该更新)。

+0

谢谢你的回答。简而言之,我需要根据主要活动收到的数据创建一个片段。 2 - 如果主要发生类似'setFragment(...)'的情况,则每次更改片段的数据。如果我可以使用Bundle来做到这一点,你能否给我更多关于如何在Fragment中使用它的细节? – AndreaF

+0

@AndreaF我已经编辑了我的答案了一下。你可以看看任何基本的教程,看看如何使用“Bundle”作为片段的参数。 – Luksprog

+0

@Raghunandan'getItem()'方法来自'FragmentPagerAdapter' /'FragmentStatePagerAdapter',在那里他创建了'Fragment',你不能把它变成'static'。 – Luksprog

30

在你的适配器,可替代getItemPosition

@Override 
public int getItemPosition(Object object) { 
    // POSITION_NONE makes it possible to reload the PagerAdapter 
    return POSITION_NONE; 
} 

之后

viewPager.getAdapter().notifyDataSetChanged() 

应该工作。

+0

@Nino处理程序..是否在适配器notifyDataSetChanged刷新所有片段或唯一片段这对用户是可见的。 –

+0

所有当前连接的 - 如果你使用FragmentStatePagerAdapter,这可能不是所有片段的情况 –

4

以上答案不被用户接受,这就是为什么在这里添加简单的解决方案。经过长时间的奋斗 找到工作解决方案。

只是通知到您的适配器,它的工作惊人,

参考代码

void setAdapter(int position) { 
     PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager()); 
     viewPager.setAdapter(pagerAdapter); 
     // when notify then set manually current position. 
     viewPager.setCurrentItem(position); 
     pagerAdapter.notifyDataSetChanged(); 
    } 

调用这个代码,当你设置适配器,当你想刷新UI 。

在你的片段添加以下代码刷新UI

((YourActivityName) getContext()).setAdapter(selectedTabPosition); 

使用instanceof铸造方面。

此代码共享不仅能帮助目的谁找到工作液

如何获得tablayout选定位置

((YourActivityName) getContext()).tablayout.getSelectedPosition(); 
+0

((YourActivityName)getContext())。setAdapter(selectedTabPosition); 你能解释一下吗?从我们得到selectedTabPosition in Fragment类 – user3530687

+0

看到更新了下一个 –

+0

以及如何获得选定的标签文本? – user3530687

1

很简单,覆盖在片段的方法

@Override

public void setUserVisibleHint(boolean isVisibleToUser) { 

    super.setUserVisibleHint(isVisibleToUser); 
    if(isVisibleToUser){ 

     actionView(); 
    } 
    else{ 
     //no 
    } 

} 
1
#How to update-refresh Fragment in ViewPager by Main Activity programmatically 
#after long struggle I find proper solution 

tablayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
      @Override 
      public void onTabSelected(TabLayout.Tab tab) { 

       refreshTab(tab.getPosition());// create a method 
       viewpager.setCurrentItem(tab.getPosition()); 
      } 

      @Override 
      public void onTabUnselected(TabLayout.Tab tab) { 

      } 

      @Override 
      public void onTabReselected(TabLayout.Tab tab) { 

      } 
     }); 
private void refreshTab(int position) { 
    switch (position) { 
     case 0: 


      break; 
     case 1: 

      CompaniesInterest comP1 = (CompaniesInterest) viewpager.getAdapter().instantiateItem(viewpager, viewpager.getCurrentItem()); 
      comP1.refreshpage(); 
      break; 
     case 2: 

      TotalSelectedCompanies toTal = (TotalSelectedCompanies) viewpager.getAdapter().instantiateItem(viewpager, viewpager.getCurrentItem()); 
      toTal.refreshpage(); 

    } 
} 
// Create a interface for refresh data for fragmen 
public interface Refreshpage { 
    void refreshpage(); 
} 
// implements Refreshpage interface in both fragment TotalSelectedCompanies and CompaniesInterest 
// 
@Override`enter code here` 
    public void refreshpage() { 
     // do what you want to refresh 
    }