【问题标题】:How to replace a fragment from another in a ViewPager with fragmentPagerAdapter如何用 fragmentPagerAdapter 替换 ViewPager 中的另一个片段
【发布时间】:2014-09-04 21:07:03
【问题描述】:

经过大量研究和多次尝试,我仍然无法解决我的问题。 我想替换具有 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();






    }
}

}

我的页面适配器

     /**
     * 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中存在的fragment,但我不明白如何。

     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>

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

【问题讨论】:

    标签: android android-viewpager fragmentpageradapter


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      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 即可显示正确的信息。

      我想可能有一个外部类来管理应该在每个位置显示哪些片段。重要的部分是它在 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);
      
      }
      

      因此,每当“模型”(DisplayCoreModule)数据随着页面的添加或删除而发生变化时,为了更新“显示”(ViewPager),我唯一要做的就是调用notifySizeChangingDataSetChange

      addPage 简单调用notifyDataSetChanged 的原因是我总是在 ViewPager 的尾部添加新页面。因此,我不想让 ViewPager 重新创建所有片段,因为这里没有必要。

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

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

      编码愉快,祝你好运 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多