0

Ich habe Fragmentansicht Pager in Aktivität, die eine Anzahl von Seiten der eingegebenen Nummer erstellt zuvor. In jedem Fragment habe ich eine Recycler-Ansicht, die jedes Mal aktualisiert werden muss, wenn der Benutzer zur entsprechenden Seite wechselt. auf resume() jedes Fragments habe ich Daten aus der Hauptaktivität getter.in ViewPager-Fragment, RecyclerView Adapter notifyDataSetChanged funktioniert nicht beim ersten Mal

Was ich erlebe, ist, während ich zum nächsten Mal zur nächsten Seite gehe, es ist nicht aktualisiert, aber wenn nach einigen Seitenbewegungen ich darauf zurückkommen würde, wird es aktualisiert, mit demselben resume() Code.

Ich versuchte einige Verzögerungen nach der Aktualisierung der Daten, es hat nicht geholfen.

Also, wenn ich vor dem Aktualisieren der Daten würde ich jede Seite überprüfen würde es wie geplant funktionieren, aber wenn die Seite nicht zuvor erstellt wurde (wegen Pager-Adapter), aber ich benutze immer noch den gleichen Code für die Aktualisierung, es funktioniert nicht.

Ich würde mich für etwas Hilfe freuen, darauf schon seit 2 Tagen gestapelt.

Hauptaktivität:

package com.slavafleer.tipcalculator02; 

import android.content.Intent; 
import android.os.Bundle; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.view.ViewPager; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.util.Log; 

import com.slavafleer.tipcalculator02.recycler.PageHeaderAdapter; 

import java.util.ArrayList; 

public class ManualModeActivity extends AppCompatActivity implements 
     PageHeaderAdapter.Callbacks, DinerFragment.Callbacks { 

    private int mDinersAmount; 
    private ViewPager mViewPagerDiners; 
    private PageHeaderAdapter mHeaderAdapter; 
    private DinersPagerAdapter mDinersPagerAdapter; 
    private ArrayList<Order> mOrders; 

    public ArrayList<Order> getOrders() { 
     return mOrders; 
    } 

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

     mOrders = new ArrayList<>(); 

     // Get diners amount from previous activity 
     Intent intent = getIntent(); 
     mDinersAmount = intent.getIntExtra(Constants.KEY_DINNERS_AMOUNT, 1); 

     // Initialise PageHeader Recycler 
     mHeaderAdapter = new PageHeaderAdapter(this, mDinersAmount, this); 
     final RecyclerView recyclerPageHeader = (RecyclerView) findViewById(R.id.recyclerViewPagerHeader); 
     final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false); 
     recyclerPageHeader.setLayoutManager(linearLayoutManager); 
     recyclerPageHeader.setAdapter(mHeaderAdapter); 

     // Initialise ViewPager 
     mViewPagerDiners = (ViewPager) findViewById(R.id.viewPagerDiners); 
     FragmentManager fragmentManager = getSupportFragmentManager(); 
     mDinersPagerAdapter = new DinersPagerAdapter(fragmentManager, mDinersAmount); 
     mViewPagerDiners.setAdapter(mDinersPagerAdapter); 

     // ViewPager Listener - synchronise with headers recycler 
     mViewPagerDiners.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 

      @Override 
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 

      } 

      // Gets position for selected page 
      @Override 
      public void onPageSelected(int position) { 

       mHeaderAdapter.selectItem(position); 
       linearLayoutManager.smoothScrollToPosition(recyclerPageHeader, null,position); 
      } 

      @Override 
      public void onPageScrollStateChanged(int state) { 

      } 
     }); 
    } 

    // HeaderPage Adapter Callbacks 
    // Scroll ViewPager by clicked Header 
    @Override 
    public void onItemClick(int position) { 
     mViewPagerDiners.setCurrentItem(position, true); 
    } 

    // DinerFragment.OrderDialog.Callbacks 
    // Send data to PagerAdapter that would sent to each fragment 
    @Override 
    public void onDialogAddClick(Order order) { 

     Log.d("test", "onDialogAddClick"); 

     mOrders.add(order); 
     mDinersPagerAdapter.updateOrders(); 
    } 
} 

PagerAdapter

package com.slavafleer.tipcalculator02; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 

import java.util.ArrayList; 

/** 
* PagerAdapter for ManualModeActivity ViewPager 
*/ 
public class DinersPagerAdapter extends FragmentPagerAdapter { 

    private int mDinersAmount; 
    private ArrayList<DinerFragment> mDinerFragments; 

    public DinersPagerAdapter(FragmentManager fm, int dinersAmount) { 
     super(fm); 

     mDinersAmount = dinersAmount; 
     mDinerFragments = new ArrayList<>(); 
    } 

    @Override 
    public Fragment getItem(int position) { 

     // Insert diners amount to fragment 
     Bundle bundle = new Bundle(); 
     bundle.putInt(Constants.KEY_DINNERS_AMOUNT, mDinersAmount); 
     bundle.putInt(Constants.KEY_CURRENT_PAGE, position); 
     DinerFragment dinerFragment = new DinerFragment(); 
     dinerFragment.setArguments(bundle); 
     mDinerFragments.add(dinerFragment); // save fragments references 

     return dinerFragment; 
    } 

    // Diners amount + All 
    @Override 
    public int getCount() { 
     return mDinersAmount + 1; 
    } 

    // Update order list in each fragment of view pager 
    public void updateOrders() { 

     for(DinerFragment dinerFragment : mDinerFragments) { 
      dinerFragment.onResume(); 
     } 
    } 
} 

Fragment

package com.slavafleer.tipcalculator02; 


import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ImageView; 

import com.slavafleer.tipcalculator02.recycler.OrdersAdapter; 

import java.util.ArrayList; 


/** 
* Diner Fragment Class 
*/ 
public class DinerFragment extends Fragment implements OrderDialog.Callbacks { 

    private ArrayList<Order> mOrders = new ArrayList<>(); 
    private RecyclerView mRecyclerViewOrders; 
    private ImageView mImageViewAddOrderButton; 
    private int mDinersAmount; 
    private OrdersAdapter mOrdersAdapter; 
    private int mDinerId; 
    private Callbacks mCallbacks; 

    public DinerFragment() { 
     // Required empty public constructor 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 

     Log.d("test", "onCreateView"); 

     // Inflate the layout for this fragment 
     View view = inflater.inflate(R.layout.fragment_diner, container, false); 

     mCallbacks = (Callbacks) inflater.getContext(); 

     // Get Diners Amount 
     final Bundle bundle = getArguments(); 
     if(bundle != null) { 
      mDinersAmount = bundle.getInt(Constants.KEY_DINNERS_AMOUNT); 
      mDinerId = bundle.getInt(Constants.KEY_CURRENT_PAGE); 

      Log.d("test", "onCreateView " + mDinerId); 
     } 

     mRecyclerViewOrders = (RecyclerView) view.findViewById(R.id.recyclerViewOrders); 

     mOrdersAdapter = new OrdersAdapter(getActivity(), mOrders); 
     LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()); 
     mRecyclerViewOrders.setLayoutManager(linearLayoutManager); 
     mRecyclerViewOrders.setAdapter(mOrdersAdapter); 

     // Due to the bug, we could use just listener and not OnClick in Fragment 
     mImageViewAddOrderButton = (ImageView) view.findViewById(R.id.imageViewAddButton); 
     mImageViewAddOrderButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       ArrayList<Integer> currentPage = new ArrayList<>(); 
       currentPage.add(mDinerId); 
       OrderDialog orderDialog = new OrderDialog(getActivity(), 
         mDinersAmount, currentPage, DinerFragment.this); 
       orderDialog.show(); 
      } 
     }); 

     return view; 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 

     Log.d("test", "onResume " + mDinerId); 

     ManualModeActivity activity = (ManualModeActivity) getActivity(); 
     mOrders = activity.getOrders(); 

     for(Order order : mOrders) { 
      Log.d("test", order.getPrice() + ""); 
     } 

     int size = mOrders.size(); 
     mOrdersAdapter.notifyDataSetChanged(); 
     mRecyclerViewOrders.smoothScrollToPosition(size); 
    } 

    // Blank OrderDialog.Callbacks 
    // used due to Implements for creation OrderDialog 
    @Override 
    public void onDialogAddClick(Order order) { 

     mCallbacks.onDialogAddClick(order); 
    } 

    public interface Callbacks { 

     void onDialogAddClick(Order order); 
    } 
} 

Antwort

1

Anstelle der Verwendung von onResume die onPageSelected Methode verwenden, und verwendet das übergebene Fragment für den Kontext der Aktualisierung Methode aufrufen im Fragment.

+0

Lass es mich wissen wenn du es hast oder wenn du mehr Hilfe brauchst! – fsebek

+0

Sorry hat nicht verstanden, was in OnPageSelected zu tun ist. Können Sie bitte die Antwort kosten? Danke vielmals. – Slava

0

Schließlich was ich getan habe mOrdersAdapter.notifyDataSetChanged() ersetzen bei der Neuerstellung des Adapters. Ich verstehe, dass das keine sehr intelligente Lösung ist, aber visuell funktioniert es so, wie ich es brauchte.

Ich würde es nicht als Antwort markieren, weil ich immer noch wissen will, warum es sich so verhält, wie ich es vorher geschrieben habe.

Nochmals vielen Dank.

//  mOrdersAdapter.notifyDataSetChanged(); 
     mOrdersAdapter = new OrdersAdapter(getActivity(), mOrders); 
     mRecyclerViewOrders.setAdapter(mOrdersAdapter); 
0

Der ViewPager-Adapter erstellt zwei Fragmente gleichzeitig. Wenn Sie beispielsweise auf Seite 0 sind, wird auch Seite 1 erstellt (Lebenszyklus für Seite 1: OnCreate-> OnCreateView-> OnResume-> OnPause-> OnResume). Wenn Sie auf Seite 1 wischen, wird nur SetMenuVisibility aufgerufen . Also, um Daten zu aktualisieren für Seite 1 setMenuVisibilty ruft innerhalb von Fragmente:

@Override 
public void setMenuVisibility(boolean menuVisible) { 
    super.setMenuVisibility(menuVisible); 
    if(menuVisible && isResumed()){ 
      settingAdapter(); 
    } 
} 

Also hier innerhalb von settingAdapter i Daten neu geladen. Bisher ist es der beste Trick, den ich mit recyclerviews in Viewpager zu Fragmenten gemacht habe. Aber es gibt immer noch ein paar Millisekunden Verzögerung, um Fragmente mit neuen Daten zu füllen))) Ich hoffe, dass dir das weiterhilft

Verwandte Themen