2012-04-17 61 views
1

我對ViewPager中的FragmentActivity和mutltiple Fragments存在問題。Android AsyncLoader:在fragmentactivity/fragment之間共享對象

在FragmentActivity中加載一個對象,並在所有其他片段中使用AsyncTask。我使用了android:configChanges =「orientation | keyboardHidden | keyboard」「hack」來確保對象只加載一次,即使在屏幕旋轉期間也是如此。

但是,現在我想在其中一個碎片中顯示更多的信息風景模式,所以現在黑客無法使用。

我試着從Android樣本中實現一個AsyncLoader和FragmentRetainInstanceSupport。但沒有一個工作:

1 - 我無法讓FragmentRetainInstanceSupport在ViewPager中工作,當我遵循示例代碼時,onCreate()方法未在工作段中調用 2 - 屏幕旋轉過程中的AsyncLoader崩潰...

這裏是我的代碼中,我(想)實施AsyncLoader:

public class TeamActivity extends SherlockFragmentActivity implements LoaderManager.LoaderCallbacks<Response<Team>> { 
    ViewPager mPager; 
    PageIndicator mIndicator; 
    FragmentPagerAdapter mAdapter; 
    private final int MENU_FOLLOW = Menu.FIRST; 
    private final int MENU_UNFOLLOW = Menu.FIRST + 1; 
    Team team = null; 
    static int team_id; 

    public Team getTeam(){ 
      return team; 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
      team_id = this.getIntent().getIntExtra("index", 0); 
      Log.d("Teamid",""+team_id); 
      getSupportLoaderManager().initLoader(0, null, this);//.forceLoad(); 


      //getSupportLoaderManager().getLoader(0).startLoading(); 
      //new getTeam().execute(); 
    } 

    @Override 
    public boolean onPrepareOptionsMenu(Menu menu) { 
      if(team != null) { 
        team.getNaam(); 
        SharedPreferences keyValues = this.getSharedPreferences("teams_follow", Context.MODE_PRIVATE); 
        MenuItem menuItem_volg = menu.findItem(MENU_FOLLOW); 
        MenuItem menuItem_delete = menu.findItem(MENU_UNFOLLOW); 
        if(keyValues.contains(String.valueOf(team.getStartnummer()))) { 
          menuItem_volg.setVisible(false); 
          menuItem_delete.setVisible(true); 
        } else { 
          menuItem_volg.setVisible(true); 
          menuItem_delete.setVisible(false); 
        } 
      } 
      return super.onPrepareOptionsMenu(menu); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
      menu.add(0,MENU_UNFOLLOW,Menu.NONE, R.string.ab_verwijderen) 
      .setIcon(R.drawable.ic_action_delete) 
      .setVisible(false) 
      .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); 

      menu.add(0,MENU_FOLLOW,Menu.NONE, R.string.ab_volgen) 
      .setIcon(R.drawable.ic_action_star) 
      .setVisible(false) 
      .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); 

      return super.onCreateOptionsMenu(menu); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
      switch (item.getItemId()) { 
      case android.R.id.home: 
        Utils.goHome(getApplicationContext()); 
        break; 
      case MENU_FOLLOW: 
        Utils.addFavoTeam(getApplicationContext(), team); 
        invalidateOptionsMenu(); 

        break; 
      case MENU_UNFOLLOW: 
        Utils.removeFavoteam(getApplicationContext(), team.getID()); 
        invalidateOptionsMenu(); 
        break; 
      } 

      return super.onOptionsItemSelected(item); 
    } 

    class TeamFragmentAdapter extends FragmentPagerAdapter implements TitleProvider { 

      ArrayList<Fragment> fragments = new ArrayList<Fragment>(); 
      ArrayList<String> titels = new ArrayList<String>(); 

      public TeamFragmentAdapter(FragmentManager fm) { 
        super(fm); 
        fragments.add(new TeamInformatieFragment()); 
        titels.add("Informatie"); 
        fragments.add(new TeamLooptijdenFragment()); 
        titels.add("Routetijden"); 
      } 



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

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

      @Override 
      public String getTitle(int position) { 
        return titels.get(position); 
      } 
    } 

    private class getTeam extends AsyncTask<Void, Void, Void> { 

      private ProgressDialog progressDialog; 
      Response<Team> response; 

      protected void onPreExecute() { 
        progressDialog = ProgressDialog.show(TeamActivity.this, 
            "Bezig met laden", "Team wordt opgehaald...", true); 
        progressDialog.setCancelable(true); 
        progressDialog.setOnCancelListener(new OnCancelListener() { 
          public void onCancel(DialogInterface dialog) { 
            cancel(true); 
            Utils.goHome(TeamActivity.this); 
          } 
        }); 
      } 

      @Override 
      protected Void doInBackground(Void... arg0) { 
        if(!isCancelled()) 
          response = api.getTeamByID(team_id); 
        return null; 
      } 

      @Override 
      protected void onPostExecute(Void result) { 
        if(Utils.checkResponse(TeamActivity.this, response)) { 
          setContentView(R.layout.simple_tabs); 
          team = response.getResponse(); 
          mAdapter = new TeamFragmentAdapter(getSupportFragmentManager()); 

          mPager = (ViewPager)findViewById(R.id.pager); 
          mPager.setAdapter(mAdapter); 

          mIndicator = (TabPageIndicator)findViewById(R.id.indicator); 
          mIndicator.setViewPager(mPager); 
          invalidateOptionsMenu(); 
          progressDialog.dismiss(); 
        } 

      } 
    } 

    public static class AppListLoader extends AsyncTaskLoader<Response<Team>> { 
      Response<Team> response; 
      public AppListLoader(Context context) { 
        super(context); 
      } 

      @Override public Response<Team> loadInBackground() { 
        response = api.getTeamByID(team_id); 
        return response; 
      } 

      @Override public void deliverResult(Response<Team> response) { 
        if (isReset()) { 
          return; 
        } 

        this.response = response; 
        super.deliverResult(response); 
      } 

      @Override protected void onStartLoading() { 
        if (response != null) { 
          deliverResult(response); 
        } 
        if (takeContentChanged() || response == null) { 
          forceLoad(); 
        } 
      } 

      @Override 
      protected void onStopLoading() { 
        // Attempt to cancel the current load task if possible. 
        cancelLoad(); 
      } 

      @Override 
      protected void onReset() { 
        super.onReset(); 
        // Ensure the loader is stopped 
        onStopLoading(); 
        response = null; 
      } 
    } 

    private ProgressDialog progressDialog; 

    @Override 
    public Loader<Response<Team>> onCreateLoader(int arg0, Bundle arg1) { 
      progressDialog = ProgressDialog.show(TeamActivity.this, 
          "Bezig met laden", "Team wordt opgehaald...", true); 
      progressDialog.setCancelable(true); 
      progressDialog.setOnCancelListener(new OnCancelListener() { 
        public void onCancel(DialogInterface dialog) { 
          finish(); 
        } 
      }); 
      return new AppListLoader(this); 
    } 

    @Override 
    public void onLoadFinished(Loader<Response<Team>> loader, Response<Team> response) { 
      //Log.d("Loader", "Klaar"); 
      if(Utils.checkResponse(TeamActivity.this, response)) { 
        team = response.getResponse(); 
        setContentView(R.layout.simple_tabs); 
        mAdapter = new TeamFragmentAdapter(getSupportFragmentManager()); 

        mPager = (ViewPager)findViewById(R.id.pager); 
        mPager.setAdapter(mAdapter); 

        mIndicator = (TabPageIndicator)findViewById(R.id.indicator); 
        mIndicator.setViewPager(mPager); 
        invalidateOptionsMenu(); 
        progressDialog.dismiss(); 
      } 
    } 

    @Override 
    public void onLoaderReset(Loader<Response<Team>> arg0) {     
      //Utils.goHome(this); 
    } 

} 

片段(舉例):

public class TeamInformatieFragment extends SherlockFragment { 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 


     Team team = ((TeamActivity)this.getActivity()).getTeam(); 
//ERROR ON NEXT LINE AFTER SCREEN ROTATION: 
getSherlockActivity().getSupportActionBar().setTitle(team.getNaam());  
      View view = inflater.inflate(R.layout.team_informatie, container, false); 
    return view; 
     } 

    } 

該方法從片段(使用getActivity()。getTeam())調用,但在屏幕旋轉後getTeam()返回null; 我認爲片段調用getTeam()太快,變量隊已被初始化之前(?)

你能幫我嗎? 謝謝!

+0

我注意到沒有接受的答案。你解決了你的問題嗎?這是正確的方式來共享fragmentActivity擁有的對象與它包含的片段? – topwik 2012-08-03 22:03:05

回答

0

這可能不是你想聽到什麼,但我建議擺脫

android:configChanges="orientation|keyboardHidden|keyboard" 

這是一個醜陋的黑客攻擊,很多較新的SDK元素,如裝載機將打破,如果你不處理配置更改正確。讓Android處理配置更改,並圍繞此設計您的代碼。

+0

是的,我已經做到了!因爲我想從layout-land文件夾加載佈局。 – user1255553 2012-04-17 17:17:19