2015-04-10 2 views
2

У меня есть Fragment с TableLayout. Данные в таблице взяты из SQLite db. SQLite db заполняется из веб-службы RESTful в AsyncTask в MainActivity. Fragment должен дождаться завершения задачи перед заполнением таблицы. Fragment прослушивает задание onPostExecute(). Когда это так, вызывается метод onLoadAndStoreComplete в Fragment. Все это работает.Получите активность фрагмента за пределами Fragment.OnCreateView()

Не работает то, что мне нужно действие фрагмента, чтобы создать новые TableRows и TextViews в onLoadAndStoreComplete, и я не могу получить его.

Я пробовал:
- создание класса члена fragmentActivity и назначение в onCreateView(), но к тому времени он попадает в onLoadAndStoreComplete(), она равна нулю.
- вызов this.getActivity() снова в onLoadAndStoreComplete(), но он возвращает null.

Как получить активность фрагмента?

MyFragment.java:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     fragmentActivity = this.getActivity(); // return value is valid 
     ... 
} 

@Override        
public void onLoadAndStoreComplete() { 

     fragmentActivity = this.getActivity(); // returns null 
    ... 
} 

от MainActivity.java (распространяется ActionBarActivity)

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

     Resources resources = getResources(); 
     String[] tabTitleArray = { resources.getString(R.string.first_fragment), 
            resources.getString(R.string.second_fragment), 
            resources.getString(R.string.help_fragment) }; 

     viewPager = (ViewPager) findViewById(R.id.pager); 
     actionBar = getSupportActionBar(); 
     mAdapter = new TabsPagerAdapter(this.getSupportFragmentManager()); 

     viewPager.setAdapter(mAdapter); 
     actionBar.setHomeButtonEnabled(false); 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);   

     for (String tab_name : tabTitleArray) { 
      actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this)); 
     } 

     // On swiping the ViewPager, select the respective tab 
     viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { 

      @Override 
      public void onPageSelected(int position) { 
       actionBar.setSelectedNavigationItem(position) ;// on changing the page, make respected tab selected 
      } 
      @Override 
      public void onPageScrolled(int arg0, float arg1, int arg2) { 
      } 
      @Override 
      public void onPageScrollStateChanged(int arg0) { 
      } 
     }); 

     String url = "http://myrestfulwebservice"; 
     Fragment secondFragment = mAdapter.getItem(SECOND_TAB); 
      new LoadAndStoreDataTask((OnLoadAndStoreCompleteListener)secondFragment).execute(url);  
    } 

} // end OnCreate 

TabsPagerAdapter.java

public class TabsPagerAdapter extends FragmentPagerAdapter { 

    public TabsPagerAdapter(FragmentManager fragmentManager) { 
     super(fragmentManager); 
    } 

    @Override 
    public Fragment getItem(int index) { 
     switch (index) { 
     case 0: 
      return new FirstFragment(); 
     case 1: 
      return new SecondFragment(); 
     case 2: 
      return new HelpFragment(); 
     } 

     return null; 
    } 

    @Override 
    public int getCount() { 
     return 3; // get item count - equal to number of tabs 
    } 

    public static void setTabColor(TabHost tabhost) { 
     for(int i=0;i<tabhost.getTabWidget().getChildCount();i++) { 
      tabhost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#FF0000")); //unselected 
     } 
     tabhost.getTabWidget().getChildAt(tabhost.getCurrentTab()).setBackgroundColor(Color.parseColor("#0000FF")); // selected 
    } 

} 
+0

PLS показывает, где вы начнете загружать db – yummy

+0

Можете ли вы показать свой код «TabsPagerAdapter»? –

+0

добавлен TabsPagerAdapter к оригиналу –

ответ

2

Я не проверял это, но мне кажется, что это будет работать.

Добавить параметр Context в конструктор для TabsPagerAdapter и MyFragment.

Что-то вроде этого:

TabsPagerAdapter.java:

public class TabsPagerAdapter extends FragmentPagerAdapter { 

    private Context mCtx; 

    public TabsPagerAdapter(FragmentManager fragmentManager, Context context) { 
     super(fragmentManager); 
     mCtx = context; 
    } 

    @Override 
    public Fragment getItem(int index) { 
     switch (index) { 
     case 0: 
      return new FirstFragment(mCtx); 
     case 1: 
      return new SecondFragment(mCtx); 
     case 2: 
      return new HelpFragment(mCtx); 
     } 

     return null; 
    } 

    @Override 
    public int getCount() { 
     return 3; // get item count - equal to number of tabs 
    } 

    public static void setTabColor(TabHost tabhost) { 
     for(int i=0;i<tabhost.getTabWidget().getChildCount();i++) { 
      tabhost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#FF0000")); //unselected 
     } 
     tabhost.getTabWidget().getChildAt(tabhost.getCurrentTab()).setBackgroundColor(Color.parseColor("#0000FF")); // selected 
    } 

} 

MainActivity.java:

mAdapter = new TabsPagerAdapter(this.getSupportFragmentManager(), this); 

MyFragment.java (сделать это в FirstFragment, SecondFragment и HelpFragment):

public static class MyFragment extends Fragment { 

    private Context fragmentActivity ; 

    public MyFragment(Context context){ 
     fragmentActivity = context; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     //.........    
     return rootView; 
    } 

    @Override 
    public void onLoadAndStoreComplete() { 

     //do something with fragmentActivity 

    } 
} 
+0

Я думаю, что это в правильном направлении. Однако, если я понимаю это правильно, «это» в настройке mAdapter в MainActivty является MainActivity, и мне нужна операция SecondFragment. –

+0

@AlLelopath Фактически, когда вы вызываете 'fragmentActivity = this.getActivity();' в Fragment, вы получаете контекст активности MainActivity. Итак, передача 'this' в конструктор ссылается на тот же самый« Контекст », какой вы были раньше. На самом деле нет такой вещи, как контекст фрагмента, каждый фрагмент использует контекст его родительской активности. Когда вы говорите: «Мне нужна операция SecondFragment», это именно то, что вы получаете здесь. –

+0

@AlLelopath Деятельность SecondFragment - MainActivity. Имейте в виду, что вам действительно нужен «Контекст», а поскольку «Активность» расширяет «Контекст», вы можете просто использовать «this» внутри Activity для ссылки на контекст активности. Этот ответ объясняет это довольно прямо: http://stackoverflow.com/questions/8215308/using-context-in-fragment/8215398#8215398 –

1

Кажется AsyncTask начинается слишком рано. предлагают загрузку БД в onActivityCreated(), это можно назвать после onCreateView

@Override 
public void onActivityCreated (Bundle savedInstanceState) { 
    //load your db here 
} 
+0

AsyncTask - последнее, что делалось в 'OnCreateView()' (см. Код, добавленный в OP). Поэтому вы предлагаете переместить этот код из MainActivity в Fragment. Мне это не нравится, потому что тогда что мне делать, если мне нужны данные в другом фрагменте. –

+0

Хотя AsyncTask находится в последней строке в onCreate, но фрагмент не может быть привязан к активности, даже когда AsyncTask завершен.Если вы хотите поделиться данными с другими фрагментами, то я думаю, что лучше использовать «глобальный кеш» – yummy

Смежные вопросы