如何使用fragmentPagerAdapter在ViewPager中替换另一个片段

时间:2014-09-04 21:07:04

标签: android android-viewpager fragmentpageradapter

经过大量的研究和多次尝试,我仍然无法解决我的问题。 我想替换具有fragmentPagerAdapter

的视图寻呼机中的片段

总结一下,我的网页浏览中有8页(片段)我会用新页面替换某些页面,但我无法获胜

我的活动

    public class AfficherOngletsCategories  extends FragmentActivity implements
 TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener   {

    private ProgressDialog pDialog;
    private static final String READ_CATEGORIES_URL = "http://192.168.1.30/GCR2000/SelectCategories.php";
    private static final String READ_SOUS_CATEGORIES_URL = "http://192.168.1.30/GCR2000/SelectSousCategories.php";


private static final String TAG_NOM = "nom";
private static final String TAG_CATEGORIES_ID = "categorie_id";
private static final String TAG_SOUS_CATEGORIES_ID = "sousCategorie_id";



private Categorie catObjet = new Categorie();
private  ArrayList<HashMap<String,String>> ListCat = null;

private SousCategorie SousCatObjet = new SousCategorie();
private ArrayList<HashMap<String,String>> ListSousCat;
private TabHost mTabHost;
private ViewPager mViewPager;
private HashMap<String, TabInfo> mapTabInfo = new HashMap<String,  n   

    AfficherOngletsCategories.TabInfo>();
    private PagerAdapter mPagerAdapter;
     Boolean flag = false;
   Bundle test;
    /**
     * Maintains extrinsic info of a tab's construct
     */
        private class TabInfo {
        private String tag;
        private Class<?> clss;
        private Bundle args;
        private Fragment fragment;

            TabInfo(String tag, Class<?> clazz, Bundle args) {
            this.tag = tag;
            this.clss = clazz;
            this.args = args;
        }

    }

/**
 * A simple factory that returns dummy views to the Tabhost
 */
class TabFactory implements TabContentFactory {

    private final Context mContext;

    /**
     * @param context
     */
    public TabFactory(Context context) {
        mContext = context;
    }

    /**
     * (non-Javadoc)
     * 
     * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
     */
    public View createTabContent(String tag) {
        View v = new View(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        return v;
    }

}

/**
 * (non-Javadoc)
 * 
 * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
 */
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Inflate the layout
    setContentView(R.layout.activity_main1);
    flag = false;
    LoadCategories lc= new LoadCategories();
    lc.execute();
    //Thread t = new Thread(new LoadCategories2());

//  t.start();
        //Attend la fin AsynTask  
        try {
            lc.get();

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //Lancer après AsynTask
        UpdateOnglet(savedInstanceState);

}



/**
 * (non-Javadoc)
 * 
 * @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
 * 
 */
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("tab", mTabHost.getCurrentTabTag()); // save the tab selected
    //outState.putSerializable("listCat", ListCat); 
    //outState.putSerializable("listSousCat", ListSousCat); 
    // selected
    super.onSaveInstanceState(outState);
}

/*
 * (non-Javadoc)
 * 
 * @see android.app.Activity#onRestoreInstanceState(android.os.Bundle)
 */
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        this.mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); // set the tab as per the saved state
        //ListCat = (ArrayList<HashMap<String, String>>) savedInstanceState.getSerializable("listCat"); 
        //ListSousCat = (ArrayList<HashMap<String, String>>) savedInstanceState.getSerializable("listSousCat");
    }
    super.onRestoreInstanceState(savedInstanceState);
}


 public void updateJSONdata() {
        //Récupere la liste des catégories
        ListCat = catObjet.updateJSONOnedata(READ_CATEGORIES_URL, TAG_CATEGORIES_ID, TAG_NOM);
        //Récupere la liste des sous-catégories
        ListSousCat = SousCatObjet.updateJSONOnedata(READ_SOUS_CATEGORIES_URL, TAG_CATEGORIES_ID, TAG_NOM, TAG_SOUS_CATEGORIES_ID);


    }


 public void UpdateOnglet(Bundle args){


     mTabHost = (TabHost) findViewById(android.R.id.tabhost);
     mTabHost.setup();
     TabInfo tabInfo = null;
     Class<?> mfragment =null;
     Bundle objetbunble = null;
     List<Fragment> fragments = new Vector<Fragment>();
     String catName = null;

     //Boucle les categories
       for ( int i = 0; ListCat.size() > i; i++){

                //Affectation de la categorie dans l'onglet
                TabSpec ts = mTabHost.newTabSpec(ListCat.get(i).get(TAG_NOM).toString()).setIndicator(ListCat.get(i).get(TAG_NOM).toString());
                Boolean flag = true;

                //Boucle des sous-categorie 
                for(int j = 0; ListSousCat.size() > j; j++){
                    //compare  primary key id avec la foreing key pour déterminer si le fragment associé a l'onglet sera une liste ou un gridlayout
                        if (ListCat.get(i).get(TAG_CATEGORIES_ID).toString().equals(ListSousCat.get(j).get(TAG_CATEGORIES_ID).toString())){

                            //Affectation du fragment a l'onglet
                            mfragment = AfficherSousCategories.class;
                            catName = ListCat.get(i).get(TAG_NOM).toString();
                            objetbunble = new Bundle();
                            //Fragment test = null;
                            objetbunble.putString("sCsousCatId", ListSousCat.get(j).get(TAG_SOUS_CATEGORIES_ID).toString());
                            objetbunble.putString("sousCatId", ListSousCat.get(j).get(TAG_CATEGORIES_ID).toString());
                            objetbunble.putString("catId",ListCat.get(i).get(TAG_CATEGORIES_ID));
                            objetbunble.putBoolean("flag", flag);
                            objetbunble.putString("tag", ListCat.get(i).get(TAG_NOM).toString());
                            //args = objetbunble;
                            //  fragments.setArguments(objetbunble);

                             break;

                        }else{

                            //Affectation du fragment a l'onglet
                            mfragment = AfficherListElem.class;

                            catName = ListCat.get(i).get(TAG_NOM).toString();
                            //Créer le bundle pour envoyer variable url caatégorie au fragment AfficherListElem
                            objetbunble = new Bundle();
                           //Renvoie l'id de la categorie
                            objetbunble.putString("catId", ListCat.get(i).get(TAG_CATEGORIES_ID));
                            objetbunble.putString("tag", ListCat.get(i).get(TAG_NOM).toString());
                            //args = objetbunble;


                        }//End if
                }//End for ListSousCat



                    //  mTabHost.addTab(ts, mfragment, objetbunble);

                    //Ajouter le fragment dans le tab
                    AfficherOngletsCategories.AddTab(this, this.mTabHost, ts,
                            (tabInfo = new TabInfo(catName, mfragment, args) ) );
                    //Ajouter tag dans map
                    this.mapTabInfo.put(tabInfo.tag, tabInfo);

                    //Ajouter à liste de fragment pour l'adapter
                    fragments.add(Fragment.instantiate(this, mfragment.getName()));
                    //répérer la position
                    //objetbunble.putInt("fragId", fragments.get(i).getId());

                    //set le bunble dans le frag
                    fragments.get(i).setArguments(objetbunble);
       }//End for listCat

                   mTabHost.setOnTabChangedListener(this);

                   //Création de l'adapter
                   this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments);
                   //this.mPagerAdapter.add(fragments);
                   //mPagerAdapter.notifyDataSetChanged();


                    this.mViewPager = (ViewPager) super.findViewById(R.id.tabviewpager2);
                    this.mViewPager.setAdapter(this.mPagerAdapter);
                    this.mViewPager.setOnPageChangeListener(this);

                   /*Forcer le scrool horizontal
                   TabWidget tw = (TabWidget) findViewById(android.R.id.tabs);
                   LinearLayout ll = (LinearLayout) tw.getParent();
                   HorizontalScrollView hs = new HorizontalScrollView(this);
                   hs.setLayoutParams(new FrameLayout.LayoutParams(
                       FrameLayout.LayoutParams.MATCH_PARENT,
                       FrameLayout.LayoutParams.WRAP_CONTENT));
                   ll.addView(hs, 0);
                   ll.removeView(tw);
                   hs.addView(tw);
                   hs.setHorizontalScrollBarEnabled(false);*/
 }


/**
 * Add Tab content to the Tabhost
 * 
 * @param activity
 * @param tabHost
 * @param tabSpec
 * @param clss
 * @param args
 */
private static void AddTab(AfficherOngletsCategories activity,
        TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) {
    // Attach a Tab view factory to the spec
    tabSpec.setContent(activity.new TabFactory(activity));
    tabHost.addTab(tabSpec);
}

/**
 * (non-Javadoc)
 * 
 * @see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
 */
public void onTabChanged(String tag) {
    // TabInfo newTab = this.mapTabInfo.get(tag);
    int pos = this.mTabHost.getCurrentTab();
    this.mViewPager.setCurrentItem(pos);

}

/*
 * (non-Javadoc)
 * 
 * @see
 * android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrolled
 * (int, float, int)
 */
int x = 0;
@Override
public void onPageScrolled(int position, float positionOffset,
        int positionOffsetPixels) {
    // TODO Auto-generated method stub
    x = position;

}

/*
 * (non-Javadoc)
 * 
 * @see
 * android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected
 * (int)
 */
@Override
public void onPageSelected(int position) {
    // TODO Auto-generated method stub
    this.mTabHost.setCurrentTab(position);

    //Faire suivre les onglets avec la pageview
    HorizontalScrollView hv = (HorizontalScrollView)findViewById(R.id.scrool);
    TabWidget tw = (TabWidget)findViewById(android.R.id.tabs);
    int ntabs = ListCat.size();
    int taille = ((tw.getWidth() / ntabs)-(tw.getWidth() / (ntabs*4)));
    if (x < position)hv.scrollBy(taille, 0);
    else hv.scrollBy(-taille, 0);


}

/*
 * (non-Javadoc)
 * 
 * @see android.support.v4.view.ViewPager.OnPageChangeListener#
 * onPageScrollStateChanged(int)
 */
@Override
public void onPageScrollStateChanged(int state) {
    // TODO Auto-generated method stub

}


//exemple thread : new thread = new (new updateJSONdata()).start();
public class LoadCategories2 implements Runnable {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        updateJSONdata();
        flag = true;
    }

}

public class LoadCategories extends AsyncTask<Void, Void, Boolean> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(AfficherOngletsCategories.this);
        pDialog.setMessage("Loading Comments...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    @Override
    protected Boolean doInBackground(Void... arg0) {

            updateJSONdata();
        return null;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        pDialog.dismiss();






    }
}

}

我的pageAdapter

     /**
     * The <code>PagerAdapter</code> serves the fragments when paging.
     */
      public class PagerAdapter extends FragmentPagerAdapter {
    FragmentTransaction transaction;
    private List<Fragment> fragments;
    private  Fragment mFragmentAtPos0 ;

    /**
     * @param fm
     * @param fragments
     */


    public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;

    }
    public void add(List<Fragment> fragments){
     for (int i = 0; fragments.size() > i; i++){


            transaction  = fragments.get(i).getFragmentManager().beginTransaction();


            //mPagerAdapter.getItem(poss).d
            //AfficherSousCategories

            transaction.add(R.id.pagercontent, fragments.get(i));
            //transaction.hide(AfficherSousCategories.this);
            //transaction.show(list);
            //getActivity().
            //transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            //transaction.remove(arg0)
            transaction.addToBackStack(null);

            transaction.commit();
            }
    }
    /* (non-Javadoc)
     * @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
     */
    @Override
    public Fragment getItem(int position) {
        Log.i("getitem", this.fragments.get(position) + " "+position);

            return this.fragments.get(position);
    }



    /* (non-Javadoc)
     * @see android.support.v4.view.PagerAdapter#getCount()
     */
    @Override
    public int getCount() {
        return this.fragments.size();
    }


    public int getItemPosition(Object object) {
           return POSITION_NONE;
        }
}

这是我要替换的作品,在此片段中按照所选类别的子类别创建按钮。一旦用户 单击此片段中的某个类别必须替换为另一个 之前我用了一个而且fragmentTabHost替换了fragmentLayout realContent中的片段,所有这些都工作得很好但是因为我想使用寻呼机视图,所以我不能多说谎。 在viewpager中,我必须替换fragmentAdapter中存在的片段,但我不明白如何。

     public class AfficherSousCategories extends Fragment {
    private ProgressDialog pDialog;

    // testing on Emulator:
    public  String urlSousCat = "http://192.168.1.30/GCR2000/ListSousCat.php";
    public  String urlListSousCat = "http://192.168.1.30/GCR2000/ListElemSousCat.php";

    //private static final String TAG_SUCCESS = "success";
    //private static final String TAG_TITLE = "title";
     Intent monIntent;
     Button btn;
    //Type d'envoie JSON
    private static final String TAG_POSTS = "posts";
    // Balise JSON :
    private static final String TAG_ELMENT_ID = "elment_id";
    private static final String TAG_NOM = "nom";
    private static final String TAG_DESCRIPTION = "description";
    private static final String TAG_PRIX = "prix";
    public String TAG = "sousCat";
    private ViewPager mViewPager;
    private PagerAdapter mPagerAdapter;
    //public static final String TAG = "sousCat";
    String sousCatId;
    String sousCategorie_id;
    String catId;
    String url;
    android.support.v7.widget.GridLayout buttonContainer;
    public ArrayList<HashMap<String, String>> nSousCat;
    private ArrayList<HashMap<String,String>> ListSousCat;
    Boolean flag = false;
    AfficherListElem list;
    //String tag;
    FragmentTransaction transaction;
    int poss;
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {

            View view = inflater.inflate(R.layout.grid_sous_categories, container, false);
            buttonContainer =             (android.support.v7.widget.GridLayout)view.findViewById(R.id.buttonContainer);   

                mViewPager = (ViewPager) getActivity().findViewById(R.id.tabviewpager2);

            return view;
        }


        public void onStart(){
            super.onStart();
                //transaction.add(R.id.realtabcontent, list);
            if(list !=null){
            //  mViewPager.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, 1));

                 transaction = getFragmentManager().beginTransaction();

                transaction.show(AfficherSousCategories.this);
                transaction.commit();
            }
        }

        public void onStop(){
            super.onStop();
                //transaction.add(R.id.realtabcontent, list);
            if(list !=null){
            //  mViewPager.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, 1));

                 transaction = getFragmentManager().beginTransaction();

                transaction.hide(list);
                transaction.commit();
            }
        }

    @Override
    public void onResume() {

        // TODO Auto-generated method stub
        super.onResume();
          //Objet Bindle qui récupérer les données envoyé de l'activity AfficherongletsCatgories
            Bundle objetbunble  = getArguments();

            catId = objetbunble.getString("catId");
            sousCatId = objetbunble.getString("sousCatId"); 
           TAG = objetbunble.getString("tag"); 
            flag = objetbunble.getBoolean("flag");
           poss = objetbunble.getInt("poss");
            new LoadElements().execute();

    }


    public void updateJSONdata() {

            SousCategorie sc = new SousCategorie();
            //La list des éléments parser nElemList = reçois un ArrayList<HashMap<String, String>> avec l'url en paramatre  
            nSousCat = sc.updateListElem(urlSousCat, catId);


    }


    /**
     * Inserts the parsed data into the listview.
     */
    private void updateList() {

             float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 175, getResources().getDisplayMetrics());

             for (int i = 0; nSousCat.size() > i; i++){
                 final String nomSouCat = nSousCat.get(i).get("nom").toString();
                 btn = new Button(getActivity());
                 btn.setText(nomSouCat);
                 // sousCategorie_id = nSousCat.get(i).get("souscategorie_id").toString();
                 btn.setId(Integer.parseInt(nSousCat.get(i).get("souscategorie_id").toString()));
                 btn.setHeight((int) pixels);
                 btn.setWidth((int) pixels);


                 btn.setOnClickListener(new View.OnClickListener() {
                     public void onClick(View v) {
                         // Perform action on click   


                        // monIntent = new Intent(getActivity(), AfficherListElem.class);
                         Bundle objetbunble = new Bundle();

                         for (int i = 0; nSousCat.size() > i; i++){
                             if (v.getId() == Integer.parseInt(nSousCat.get(i).get("souscategorie_id").toString())){
                                 objetbunble.putString("sousCatId", nSousCat.get(i).get("souscategorie_id").toString()); 
                                 Log.i("index dans if for", nSousCat.get(i).get("souscategorie_id").toString());
                                 break;

                             }

                         }
                         objetbunble.putBoolean("flag", flag);

                         objetbunble.putString("catId", catId);

                         objetbunble.putString("tag", nomSouCat);





                         //Remplacer view pager
                        // List<Fragment> fragments = new Vector<Fragment>();
                         //fragments.add(Fragment.instantiate(getActivity(), AfficherListElem.class.getName()));
                         //fragments.get(0).setArguments(objetbunble);

                        // mPagerAdapter.getItemPosition(object);

                       //  mPagerAdapter = new PagerAdapter(
                        //       getActivity().getSupportFragmentManager(), fragments);
                            //
                        //  mViewPager = (ViewPager)getActivity().findViewById(R.id.tabviewpager2);
                            //mViewPager.setAdapter(mPagerAdapter);
                         /*
                         FragmentManager manager = getFragmentManager();
                         FragmentTransaction transaction = manager.beginTransaction();
                         transaction.replace(R.id.tabviewpager2, list.newInstance(flag, catId, nomSouCat));
                         transaction.addToBackStack(null);
                         transaction.commit();
                         */
                                             list = new AfficherListElem();
                            list.setArguments(objetbunble);
                            transaction  = getFragmentManager().beginTransaction();
                                                transaction.replace(R.id.tabviewpager2, list);  //le  probleme et ici car je ne sais pas quel R.id utilisé ou je mis prend mal
                                                transaction.addToBackStack(TAG);
                            transaction.commit();

                            //mViewPager.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, 0, 0));
                            //mPagerAdapter.getItem(poss).d
                            //AfficherSousCategories
                            //mViewPager.setAdapter(mPagerAdapter);



                            //transaction.hide(AfficherSousCategories.this);
                            //transaction.show(list);
                            //getActivity().
                            //transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                            //transaction.remove(arg0)

                            //mPagerAdapter.notifyDataSetChanged();
                            //AfficherSousCategories.this.getView().setVisibility(AfficherSousCategories.this.getView().GONE);
                            //list.getView().setVisibility(list.getView().VISIBLE);
                     }
                 });


                 buttonContainer.addView(btn);
             }//Bouble for      

    }



    public class LoadElements extends AsyncTask<Void, Void, Boolean> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(getActivity());
            pDialog.setMessage("Loading Comments...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }

        @Override
        protected Boolean doInBackground(Void... arg0) {
            updateJSONdata();
            return null;

        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            pDialog.dismiss();
            updateList();
        }
    }

   }

我的布局

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >


     <include 
         android:id="@+id/top"
         layout="@layout/barre_info"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_marginBottom="5dp"
         android:layout_alignParentTop="true"
         android:layout_weight="10"
        />
         <!--  -->






   <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/top"
        >
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            >
                <HorizontalScrollView
                    android:id="@+id/scrool"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fillViewport="true"
                android:scrollbars="none">
        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal" />
            </HorizontalScrollView>

            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_weight="0"/>

            <android.support.v4.view.ViewPager
                android:id="@+id/tabviewpager2"
                android:layout_width="fill_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                />
           <FrameLayout
                android:id="@+id/pagercontent"
                android:layout_width="fill_parent"
                android:layout_height="0dp"
                android:layout_weight="1">


           </FrameLayout>
        </LinearLayout>
    </TabHost>


    <include 
        android:id="@+id/bottom"
        layout="@layout/boutons_user_standard"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_alignParentBottom="true"
            android:layout_weight="10"/>
         <!--  -->



   </RelativeLayout>

我提前感谢所有花时间阅读我的帖子的人

2 个答案:

答案 0 :(得分:0)

我没有时间完全理解您的代码,但这是我的代码,以防您可以使用它:

FragmentStatePagerAdapter(用法说明如下):

public class DisplayPagerAdapter extends FragmentStatePagerAdapter  {

    private static final String TAG = "DisplayPagerAdapter";

    SparseArray<DisplayFragment> registeredFragments = new SparseArray<DisplayFragment>();

    private final Context context;
    private final DisplayCoreModule display;
    private final FragmentManager fm;

    private boolean isAddOrRemoving;

    public DisplayPagerAdapter(Context context, FragmentManager fm,
            DisplayCoreModule display) {
        super(fm);
        this.context = context;
        this.display = display;
        this.fm = fm;

        Log.d(TAG, "pages " + display.getPagesCount());
    }


    public void notifySizeChangingDataSetChange() {
        isAddOrRemoving = true;
        notifyDataSetChanged();
        isAddOrRemoving = false;
    }

    @Override
    public int getCount() {
        int count = (display != null && display.getPagesCount() > 0) ? display
                .getPagesCount() : 1;
        return count;
    }

    @Override
    public int getItemPosition(Object object) {
        DisplayFragment frag = (DisplayFragment) object;
        if (!display.containsPageId(frag.getPageId())) {
            // this will update the 'no information' page with id -1
            return POSITION_NONE;
        }
        if (isAddOrRemoving) {
            // recreate all for simplicity
            return POSITION_NONE;
        }
        return POSITION_UNCHANGED;
    }

    @Override
    public Fragment getItem(int position) {
        Log.d(TAG, "getItem " + position);
        return DisplayFragment.newInstance(position);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        if (display != null && display.getPagesCount() > 0) {
            return context.getString(R.string.page) + " " + (position + 1);
        } else {
            return super.getPageTitle(position);
        }
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Log.d(TAG, "instantiateItem " + position);
        DisplayFragment fragment = (DisplayFragment) super.instantiateItem(
                container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        Log.d(TAG, "destroyItem " + position);
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }

    public Fragment getRegisteredFragment(int position) {
        return registeredFragments.get(position);
    }

    public SparseArray<DisplayFragment> getRegisteredFragments() {
        return registeredFragments;
    }

}

页面是根据DisplayCoreModule的信息生成的。这实际上将页面位置映射到要在每个DisplayFragment上显示的信息,这也是getItem()只需要将位置传递给新的DisplayFragment以显示正确信息的原因。

我可以想象,有一个外部类可以管理每个位置应显示哪些片段。重要的是它是处理外部的&#39;到PagerAdapter。

getRegisteredFragment()周围的代码仅用作当前可见片段的句柄(肯定会添加到Activity而不是null),尽管理论上它也可用于获取可见周围的缓存片段分段。请注意,FragmentStatePagerAdapter只添加一些片段,而不是全部,可以使用mViewPager.setOffscreenPageLimit()

更改

添加/删除片段

好的,现在回想一下DisplayCoreModule。此类保持数据的当前状态。现在,每当数据发生变化时,我都会向持有我的ViewPager的Activity发送一个回调函数。这些回调看起来像这样:

/* 
 * Get the currently visible DisplayFragment in the ViewPager
 * 
 * @see com.turios.activities.listeners.TuriosUICallback#getSelectedDisplayFragment()
 */
@Override
public DisplayFragment getSelectedDisplayFragment() {
    return (DisplayFragment) mDisplayPagerAdapter
            .getRegisteredFragment(mViewPager.getCurrentItem());
}


/* 
 * Makes the current DisplayFragment refresh it's information
 * 
 * @see com.turios.activities.listeners.TuriosUICallback#refreshDisplayFragment()
 */
@Override
public void refreshDisplayFragment() {
    DisplayFragment displayFragment = getSelectedDisplayFragment();
    if (displayFragment != null) {
        displayFragment.refreshScreen();
    }
}

/* 
 * A page has been deleted in DisplayCoreModule
 * Inform the Viewpager by calling notifySizeChangingDataSetChange
 * 
 * @see com.turios.activities.listeners.TuriosUICallback#pageDeleted(int)
 */
@Override
public void pageDeleted(int page) {
    mDisplayPagerAdapter.notifySizeChangingDataSetChange();

    deferInvalidation();

    if (display.getPagesCount() == 0) {
        locationService.stopLoactionUpdates();
        wakeScreen.screenRelease();
    }

}

/* 
 * A page has been added 
 * Inform the Viewpager by calling notifySizeChangingDataSetChange
 * 
 * @see com.turios.activities.listeners.TuriosUICallback#addPage(int)
 */
@Override
public void addPage(final int page) {
    tintBackground();

    mDisplayPagerAdapter.notifyDataSetChanged();

    if (mViewPager.getCurrentItem() == page)
        return;

    // http://stackoverflow.com/questions/13585396/viewpager-re-instantiates-items-out-of-order-after-screen-rotation
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            mViewPager.setCurrentItem(page);
        }
    }, ANIMATION_TINTBACKGROUND);

}

/*
 * New information has been added to a page
 * Tint screen to catch attention and scroll to the newly updated DisplayFragment
 *  
 * @see com.turios.activities.listeners.TuriosUICallback#pageUpdated(int, java.util.List)
 */
@Override
public void pageUpdated(final int page, final List<String> entries) {
    tintBackground();

    // http://stackoverflow.com/questions/13585396/viewpager-re-instantiates-items-out-of-order-after-screen-rotation
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            if (!(mViewPager.getCurrentItem() == page)) {
                mViewPager.setCurrentItem(page);
            } else {
                invalidateOptionsMenu();
            }

            DisplayFragment displayFrag = (com.turios.activities.fragments.DisplayFragment) mDisplayPagerAdapter
                    .getRegisteredFragment(page);
            if (displayFrag != null) {
                displayFrag.appendEntries(entries);
            }

        }
    }, ANIMATION_TINTBACKGROUND);

}

所以只要&#39;模型&#39; (DisplayCoreModule)数据随着页面的添加或删除而变化,我唯一需要做的就是更新“显示”数据。 (ViewPager),是致电notifySizeChangingDataSetChange

addPage只是调用notifyDataSetChanged的原因是我总是将新页面添加到ViewPager的尾部。因此,我不希望ViewPager重新创建所有片段,因为这里没有必要。

  • notifySizeChangingDataSetChange使ViewPager重新创建所有片段,允许更改顺序,这在添加或删除不是尾部的片段时是必需的。
  • notifyDataSetChanged对getItem使用POSITION_UNCHANGED,它在调用时对性能的影响较小。但是由于无法改变片段的顺序的限制。

这种架构可能不适合您的情况,但它对我有用。

快乐的编码和好运:))

答案 1 :(得分:0)

适配器调用getItemId(int position)以检查支持position的片段的数据是否已更改。默认实现返回位置。如果在适配器中重写此方法以返回更新数据的不同值,则适配器会知道旧Fragment不再有效。