2013-11-02 33 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 
    }