2012-04-17 51 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