2017-02-25 2 views
0

In den letzten zwei Tagen habe ich meine ganze Zeit damit verbracht, in einem Viewpager mit Fragment eine Lösung für ein seltsames Problem zu finden. Alle Fragmente enthalten eine Listenansicht (die einen eigenen Adapter hat). HierWarum ruft die mittlere Registerkarte von viewPagerCreateView niemals selbst auf?

ist die Situation:

  • Ich habe eine Tätigkeit, die eine viewpager und einen Adapter für sie instanziiert und enthält die Objektadapterklasse.

public class SellerActivity erweitert AppCompatActivity {

/** 
* The {@link android.support.v4.view.PagerAdapter} that will provide 
* fragments for each of the sections. We use a 
* {@link FragmentPagerAdapter} derivative, which will keep every 
* loaded fragment in memory. If this becomes too memory intensive, it 
* may be best to switch to a 
* {@link android.support.v4.app.FragmentStatePagerAdapter}. 
*/ 
private SectionsPagerAdapter mSectionsPagerAdapter; 
private FirebaseAuth mAuth = FirebaseAuth.getInstance(); 

/** 
* The {@link ViewPager} that will host the section contents. 
*/ 
private ViewPager mViewPager; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_seller); 

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 
    // Create the adapter that will return a fragment for each of the three 
    // primary sections of the activity. 
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); 

    // Set up the ViewPager with the sections adapter. 
    mViewPager = (ViewPager) findViewById(R.id.vpContainer2); 
    mViewPager.setAdapter(mSectionsPagerAdapter); 

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs2); 
    tabLayout.setupWithViewPager(mViewPager); 

    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 

     // This method will be invoked when a new page becomes selected. 
     @Override 
     public void onPageSelected(int position) { 
      mViewPager.setCurrentItem(position); 
      mSectionsPagerAdapter.getItem(position); 
      Toast.makeText(SellerActivity.this, 
        "Selected page position: " + position, Toast.LENGTH_SHORT).show(); 
     } 

     // This method will be invoked when the current page is scrolled 
     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
      // Code goes here 
     } 

     // Called when the scroll state changes: 
     // SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING 
     @Override 
     public void onPageScrollStateChanged(int state) { 
      // Code goes here 
     } 
    }); 
} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_shop, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    Intent i = new Intent(SellerActivity.this, MainActivity.class); 
    if (id == R.id.action_home) { 
     startActivity(i); 
     finish(); 
     return true; 
    } 
    if (id == R.id.action_logout) { 
     mAuth.signOut(); 
     startActivity(i); 
     finish(); 
     return false; 
    } 

    return super.onOptionsItemSelected(item); 
} 
/** 
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to 
* one of the sections/tabs/pages. 
*/ 
public class SectionsPagerAdapter extends FragmentPagerAdapter { 

    public SectionsPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     // getItem is called to instantiate the fragment for the given page. 
     // Return a PlaceholderFragment (defined as a static inner class below). 
     return SellerFragment.newInstance(position + 1, "1"); 
    } 

    @Override 
    public int getCount() { 
     // Show 3 total pages. 
     return 3; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     switch (position) { 
      case 0: 
       return "En Attente"; 
      case 1: 
       return "En cours"; 
      case 2: 
       return "Terminées"; 
     } 
     return null; 
    } 
} 
  • Ich habe dann ein Fragment, das wie folgt aussieht:

public class SellerFragment Fragment erstreckt {

private String title; 
private int page; 

private AllOrders allOrders; 

final List<CommandItemForSeller> orders = new ArrayList<>(); 
final LinkedHashMap<String, Order> saveOrders = new LinkedHashMap<>(); 

public SellerFragment(){ 

} 

// newInstance constructor for creating fragment with arguments 
public static SellerFragment newInstance(int page, String title) { 
    SellerFragment fragmentFirst = new SellerFragment(); 
    Bundle args = new Bundle(); 
    args.putInt("someInt", page); 
    args.putString("someTitle", title); 
    fragmentFirst.setArguments(args); 
    return fragmentFirst; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    page = getArguments().getInt("someInt", 0); 
    title = getArguments().getString("someTitle"); 
    allOrders = new AllOrders(); 
    setRetainInstance(true); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.fragment_seller, container, false); 
    TextView tvLabel = (TextView) view.findViewById(R.id.tvLabel); 
    tvLabel.setText(page + " -- " + title); 

    DatabaseReference myRef = FirebaseDatabase.getInstance().getReference().child("orders"); 
    ChildEventListener childEventListener = new ChildEventListener() { 
     @Override 
     public void onChildAdded(DataSnapshot dataSnapshot, String s) { 


      for (DataSnapshot orders : dataSnapshot.getChildren()) { 

       String orderString = orders.getValue(String.class); 

       //allOrders.addOrder(new Order(orderString, orders.getKey().substring(orders.getKey().length() - 4, orders.getKey().length()))); 
       saveOrders.put(orders.getKey(), new Order(orderString, orders.getKey().substring(orders.getKey().length() - 4, orders.getKey().length()))); 

      } 

     } 

     @Override 
     public void onChildChanged (DataSnapshot dataSnapshot, String s){ 

     } 

     @Override 
     public void onChildRemoved (DataSnapshot dataSnapshot){ 

     } 

     @Override 
     public void onChildMoved (DataSnapshot dataSnapshot, String s){ 

     } 

     @Override 
     public void onCancelled (DatabaseError databaseError){ 

     } 
    }; 

    myRef.addChildEventListener(childEventListener); 
    orders.clear(); 

    allOrders.clear(); 
    allOrders.addAllOrders(saveOrders.values()); 
    List<Order> selectedOrders = allOrders.getItemsOrderedByStatus(page); 
    for (int i = 0; i < selectedOrders.size(); i++) { 
     orders.add(new CommandItemForSeller(selectedOrders.get(i))); 
    } 

    CommandItemForSellerAdapter aa = new CommandItemForSellerAdapter(getActivity(), R.layout.pending_listview_item, orders); 


    ListView lv = (ListView) view.findViewById(R.id.commandListView); 
    lv.setAdapter(aa); 


    return view; 
} 

Wie du kannst Jedes Fragment ruft Inhalte aus der Firebase-Datenbank auf, sodass es asynchron bleibt.

Mein Problem ist:

Wenn ich versuche, „synchron“ Daten zu laden (die ich previsouly in meinem Code zu schreiben), Listeninhalt von onCreate Methode bei der ersten Schöpfung so jedes Fragment für jeden Reiter gesetzt etwas Inhalt bekommen. Die zweite Registerkarte wird jedoch niemals für neue Daten aktualisiert. Also in einem Fall von asynchroner, onCreate Methode gibt keine Daten zurück (wegen der Ladezeit) und neue Daten sollten von der onCreateView hinzugefügt werden (wie eine Aktualisierung), aber für die zweite Registerkarte passiert es nie! von

Wenn ich wechseln Register 1 bis Register 2, Fragment wird für Reiter 3 gemacht:

Nach vielen Stunden Debugging, habe ich nur folgendes herausgefunden. Wenn ich von Registerkarte 3 zu Registerkarte 2 umschalt, wird Fragment für Registerkarte 1 gerendert. Auch wenn getItem (position) die richtige Position für die Registerkarte zurückgibt, ruft die Registerkarte 2 jetzt nie die Methode onCreateView auf und bleibt leer.

Bitte .. sagen Sie mir, warum dieses Projekt so verhält, ich möchte nicht aufgeben, aber ich verstehe wirklich nicht, was das Problem hier ist.

Wenn Sie genauere Informationen benötigen, sagen Sie mir, ich kann Ihnen alles geben, was Sie wollen.

Antwort

0

Wenn Sie FragmentPagerAdapter verwenden, behält ViewPager benachbarte Seiten "am Leben" (eine nach links und eine nach rechts). Wenn Sie also nur drei Fragmente haben, wird die zweite nicht zerstört. Sie müssen einen anderen Weg finden, wenn Sie Daten aktualisieren wollen, wenn Fragmente in Sicht kommen - eine Idee besteht darin, einen Listener für Seitenänderungen hinzuzufügen, indem Sie die ViewPager.addOnPageChangeListener-Methode verwenden - Dann können Sie die Aktualisierung innerhalb von onPageSelected Callback auslösen.

In meinem Fall denke ich, dass die einfachste Lösung darin besteht, dass SectionsPagerAdapter ViewPager.OnPageChangeListener implementiert, einen Verweis auf jedes erstellte Fragment speichert (vorzugsweise WeakReference) und dann einige Refresh-Methoden für eine entsprechende SellerFragment-Instanz aufruft.

+0

Ok danke, in meinem Fall habe ich einen Tab hinzugefügt. Ein bisschen einfacher haha ​​ –

+0

@ pablo432 Ich habe versucht, onPageChangeListener in ViewPagerAdpater (hier sectionsAdapter) hinzufügen. Aber ich hatte keinen Erfolg. Das wird im Lebenszyklus nie genannt. Kannst du mir helfen? –

+0

@malavshah teilen einige Code, dann werde ich einen Blick :) – pablo432

Verwandte Themen