0

我有一個活動,它刮在一個CustomLoader的網頁。 加載器完成後,我想用檢索到的數據更新3個選項卡的內容。Android的Viewpager標籤更新標籤片段

我使用android dev樣本提供的示例代碼在活動上實現Viewpager/Tabs/Fragments。

當爲標籤創建片段時,正確調用了onCreateView,視圖上的所有小部件都被正確定位並映射到變量。

但是,當我試圖從Activity中查找片段並在片段上調用方法來更新其內容時,變量爲空。此外,調用getView也會返回null - 我從TabsAdapter中檢索的片段的實例不是正確的實例化實例嗎?

我已經將代碼縮減爲單個標籤片段,有問題的代碼是來自onLoaderFinished的調用來更新片段。

所有3個選項卡片段將填充來自單個加載器的數據,因此加載器位於活動上,而不是片段上。我只需要一種方法來告訴碎片來繪製他們的新數據。

public class InfoBloodStocksActivity extends SherlockFragmentActivity 
    implements LoaderManager.LoaderCallbacks<BloodStocksLoaderResponse> { 

    TabHost mTabHost; 
    ViewPager mViewPager; 
    TabsAdapter mTabsAdapter; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.info_bloodstocks_tabpager); 


     mTabHost = (TabHost)findViewById(android.R.id.tabhost); 
     mTabHost.setup(); 

     mViewPager = (ViewPager)findViewById(R.id.infoBloodStocksTabPager); 
     mViewPager.setOffscreenPageLimit(3); 

     mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager); 

     mTabsAdapter.addTab(mTabHost.newTabSpec("Daily stock").setIndicator("Daily stocks"), 
       InfoBloodStocksPageFragment.class, null); 

     if (savedInstanceState != null) { 
      mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); 
     } 

     loadStockDetailsFromWebsite(); 

    } 



    private void loadStockDetailsFromWebsite() { 
     // Prepare the loader. Either re-connect with an existing one, 
     // or start a new one. 

     getSupportLoaderManager().initLoader(0, null, this); 
    } 


    @Override 
    public Loader<BloodStocksLoaderResponse> onCreateLoader(int arg0, Bundle arg1) { 
     // This is called when a new Loader needs to be created. This 
     // sample only has one Loader with no arguments, so it is simple. 
     return new BloodStocksCustomLoader(this); 
    } 



    @Override 
    public void onLoadFinished(Loader<BloodStocksLoaderResponse> loader, BloodStocksLoaderResponse response) { 
     if (response.isNewStocksLoaded()) { 

      InfoBloodStocksPageFragment fragment = (InfoBloodStocksPageFragment) mTabsAdapter.getItem(0); 

      fragment.setNewImage(response.getDailyStocksImageURL()); 
     } 
    } 


    @Override 
    public void onLoaderReset(Loader<BloodStocksLoaderResponse> arg0) { 
     // TODO Auto-generated method stub 

    } 







    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putString("tab", mTabHost.getCurrentTabTag()); 
    } 

    /** 
    * This is a helper class that implements the management of tabs and all 
    * details of connecting a ViewPager with associated TabHost. It relies on a 
    * trick. Normally a tab host has a simple API for supplying a View or 
    * Intent that each tab will show. This is not sufficient for switching 
    * between pages. So instead we make the content part of the tab host 
    * 0dp high (it is not shown) and the TabsAdapter supplies its own dummy 
    * view to show as the tab content. It listens to changes in tabs, and takes 
    * care of switch to the correct paged in the ViewPager whenever the selected 
    * tab changes. 
    */ 
    public static class TabsAdapter extends FragmentPagerAdapter 
      implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener { 

     private final Context mContext; 
     private final TabHost mTabHost; 
     private final ViewPager mViewPager; 
     private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); 

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

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

     static class DummyTabFactory implements TabHost.TabContentFactory { 
      private final Context mContext; 

      public DummyTabFactory(Context context) { 
       mContext = context; 
      } 

      @Override 
      public View createTabContent(String tag) { 
       View v = new View(mContext); 
       v.setMinimumWidth(0); 
       v.setMinimumHeight(0); 
       return v; 
      } 
     } 

     public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) { 
      super(activity.getSupportFragmentManager()); 

      mContext = activity; 
      mTabHost = tabHost; 
      mViewPager = pager; 
      mTabHost.setOnTabChangedListener(this); 
      mViewPager.setAdapter(this); 
      mViewPager.setOnPageChangeListener(this); 
     } 

     public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) { 

      tabSpec.setContent(new DummyTabFactory(mContext)); 
      String tag = tabSpec.getTag(); 

      TabInfo info = new TabInfo(tag, clss, args); 
      mTabs.add(info); 
      mTabHost.addTab(tabSpec); 

      notifyDataSetChanged(); 
     } 

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

     @Override 
     public Fragment getItem(int position) { 
      TabInfo info = mTabs.get(position); 
      return Fragment.instantiate(mContext, info.clss.getName(), info.args); 
     } 

     @Override 
     public void onTabChanged(String tabId) { 
      int position = mTabHost.getCurrentTab(); 
      mViewPager.setCurrentItem(position); 
     } 

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

     @Override 
     public void onPageSelected(int position) { 
      // Unfortunately when TabHost changes the current tab, it kindly 
      // also takes care of putting focus on it when not in touch mode. 
      // The jerk. 
      // This hack tries to prevent this from pulling focus out of our 
      // ViewPager. 

      TabWidget widget = mTabHost.getTabWidget(); 
      int oldFocusability = widget.getDescendantFocusability(); 
      widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); 
      mTabHost.setCurrentTab(position); 
      widget.setDescendantFocusability(oldFocusability); 
     } 

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

我從活動中調用setNewImage。

public class InfoBloodStocksPageFragment extends SherlockFragment { 

    private ImageView mImageView; 
    private ProgressBar mProgress; 
    private TextView mTitle; 
    private TextView mDescriptionText; 

    private String mImageURL; 

    private ImageLoader mImageLoader = ImageLoader.getInstance(); 


    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.info_bloodstocks_page, container, false); 

     mImageView = (ImageView)view.findViewById(R.id.bloodStocksPageImage); 
     mProgress = (ProgressBar)view.findViewById(R.id.bloodStocksPageProgress); 
     mTitle = (TextView)view.findViewById(R.id.bloodStockPageTitle); 
     mDescriptionText = (TextView)view.findViewById(R.id.bloodStocksPageText); 

     mProgress.setVisibility(View.VISIBLE); 
     mDescriptionText.setVisibility(View.GONE); 

     return view; 
    } 


    public void setNewImage(String imageURL) { 

     // why is mImageView null here ? 
     // why does getView() return null here ? 

     View view = getView(); 
     mImageView = (ImageView)view.findViewById(R.id.bloodStocksPageImage); 

     DisplayImageOptions displayImageOptions = new DisplayImageOptions.Builder() 
      .showImageForEmptyUri(R.drawable.loading_stock_figures) 
      .cacheOnDisc() 
      .imageScaleType(ImageScaleType.EXACT) 
      .build(); 

     mImageLoader.displayImage(imageURL, mImageView, displayImageOptions, new ImageLoadingListener() { 

      @Override 
      public void onLoadingStarted() { 
       mProgress.setVisibility(View.VISIBLE); 
      } 

      @Override 
      public void onLoadingFailed(FailReason failReason) { 
       String message = null; 
       switch (failReason) { 
        case IO_ERROR: 
         message = "Input/Output error"; 
         break; 
        case OUT_OF_MEMORY: 
         message = "Out Of Memory error"; 
         break; 
        case UNKNOWN: 
         message = "Unknown error"; 
         break; 
       } 

       mProgress.setVisibility(View.GONE); 
       mImageView.setImageResource(android.R.drawable.ic_delete); 
      } 

      @Override 
      public void onLoadingComplete() { 
       mProgress.setVisibility(View.GONE); 
       Animation anim = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in); 
       mImageView.setAnimation(anim); 
       anim.start(); 
      } 

      @Override 
      public void onLoadingCancelled() { 
       // Do nothing 
      } 
     }); 

    } 


} 

回答