0

Ich baue eine einfache Aktienanzeige-App, mit der Sie interessante Aktien (Frag A) abrufen, in einer TinyDB speichern und anzeigen können in einer RecyclerView (Frag B).Kommunikation zwischen 2 Fragmenten in einem Viewpager - Aktualisierung RecyclerView in Fragment B aus Fragment A

Das Framework verwendet funktionieren - bis ich einen viewpager und Tablayout Host zu übernehmen entschieden. Ich kann den RecyclerView in Frag B nicht abrufen, um neue Daten live anzuzeigen. Dies liegt daran, dass der Aktivitäts-Viewpager beide Fragmente beim Start initialisiert, was bedeutet, dass Sie den onCreateView-Code nicht erneut aufrufen können, glaube ich.

Kommunikation zwischen zwei Fragmente durch eine Aktivität wurde auf dieser Seite berührt vor, aber ich fand das beste Beispiel dieser sein:

(https://github.com/kylejablonski/InterfaceDemo),

, die zwei Schnittstellen verwendet, ein kommunizieren von Frag A Aktivität, und eine weitere von Aktivität zu Frag B. zu kommunizieren Aber ich habe ein ernstes Problem -

  • Derzeit sind sowohl die „clear-Portfolio“ und „add Lager“ zu Portfolio-Schaltflächen in Frag ein Klick Ergebnis in einem leeren scr een in Frag B, die etwas bedeutet, wird noch neue Daten aufgerufen wird nicht mit dem Adapter

Aktivität (https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/ViewHolderActivity.java)

public class ViewHolderActivity extends AppCompatActivity implements CommunicateToActivity,CommunicateToFragment{ 
//Job of ViewHolderActivity is to allow swiping between list and MainFragment/Fragment 
TabLayout tablayout; 
ViewPager viewPager; 
List<HistoricalQuote> historicaldata; 
Bundle bundle; 
Adapter adapter; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_view_holder); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 


    viewPager =(ViewPager)findViewById(R.id.viewpager); 
    tablayout= (TabLayout)findViewById(R.id.tabs); 
    tablayout.setupWithViewPager(viewPager); 

    setupViewPager(viewPager); 
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 

     } 

     @Override 
     public void onPageSelected(int position) { 


     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 

     } 
    }); 

} 
//----------------------- Interface code----------- 
@Override 
public void communicateup(){ 
    communicatedown(); 
    //call communicate down STRAIGHT, since we call it from mainfrag 
} 

@Override 
public void communicatedown(){ 
    //This line works 
    ListFragment currentFragment =(ListFragment)adapter.instantiateItem(viewPager,1); 
    currentFragment.refreshUI(); 
} 

private void setupViewPager(ViewPager viewPager) { 
    adapter = new Adapter(getSupportFragmentManager()); 
    adapter.addFragment(new MainFragment(), "Add Stock"); 
    adapter.addFragment(new ListFragment(), "Portfolio"); 

    viewPager.setAdapter(adapter); 
} 

static class Adapter extends FragmentPagerAdapter { 
    private final List<Fragment> mFragmentList = new ArrayList<>(); 
    private final List<String> mFragmentTitleList = new ArrayList<>(); 

    public Adapter(FragmentManager manager) { 
     super(manager); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return mFragmentList.get(position); 
    } 

    @Override 
    public int getCount() { 
     return mFragmentList.size(); 
    } 

    public void addFragment(Fragment fragment, String title) { 
     mFragmentList.add(fragment); 
     mFragmentTitleList.add(title); 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return mFragmentTitleList.get(position); 
    } 
} 

Frag A (MainFragment) (https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/MainFragment.java)

angezeigt/verknüpft ist
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    View view =inflater.inflate(R.layout.content_main,container,false); 
    stocknames = new ArrayList<String>(); 
    stocktickers = new ArrayList<String>(); 
    tinyDB = new TinyDB(getContext()); 



    /* 
    menu.setDisplayShowHomeEnabled(true); 
    //menu.setLogo("INSERT LOGO HERE"); 
    menu.setDisplayUseLogoEnabled(true); 
    menu.setTitle(" Stock Selector"); 
    */ 

    fetch =(Button) view.findViewById(R.id.fetchBtn); 
    enterID =(EditText)view.findViewById(R.id.enterID); 
    display =(TextView)view.findViewById(R.id.display); 
    mCalendar = Calendar.getInstance(); 
    clear = (Button)view.findViewById(R.id.clearportfolio); 









    fetch.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 

      //TODO all the main page should do is add stocktickers and names to portfolio 
      //Fetch id and the dates 
      id =enterID.getText().toString(); 




      /*to = Calendar.getInstance(); 
      from = Calendar.getInstance(); 
      to.setTime(dateto); 
      from.setTime(datefrom); 
      */ 

      FetchXDayData getData = new FetchXDayData(); 
      getData.execute(id); 












     } 
    }); 
    clear.setOnClickListener(new View.OnClickListener(){ 
     @Override 
     public void onClick(View view) { 
      tinyDB.clear(); 
      recyclerinterface.communicateup(); 

     } 
    }); 





    return view; 

} 

//----------------------------INTERFACE CODE 


@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 

    // This makes sure that the container activity has implemented 
    // the callback interface. If not, it throws an exception 
    try { 
     recyclerinterface = (CommunicateToActivity) activity; 
    } catch (ClassCastException e) { 
     throw new ClassCastException(activity.toString() 
       + " must implement RecyclerUpdateInterface"); 
    } 
} 







///-------End of Oncreate--------------------------------------------------------------- 

//Called by AsyncTask, moving result to main thread 
public void moveResultToUI(Stock result){ 

    this.stock = result; 
    Toast.makeText(getActivity(),"Stock "+stock.getName()+" successfully added to portofolio",Toast.LENGTH_LONG).show(); 
    //reverse the list of course, stock names and tickrs to portfolio 



    stocknames.add(stock.getName()); 
    stocktickers.add(stock.getSymbol()); 


    /*DEBUG Test code, Test. 30012017 WORKS 
    for (int i =0;i<historicaldata.size();i++){ 
     HistoricalQuote current = historicaldata.get(i); 
     Toast toast = Toast.makeText(this,current.getClose().toString(),Toast.LENGTH_SHORT); 
     toast.show(); 
    } 
    */ 


    // 
    if (stock != null){ 
     display.setText("Name: "+stock.getName() +"\n"+"Price: "+ stock.getQuote().getPrice()+"\n"+ "Change(%)"+stock.getQuote().getChangeInPercent()); 
     /*SMA = getSMA(10); 
     decision=checkSimpleCrossover(SMA,stock.getQuote().getPrice().longValue()); 
     decisionView.setText("SMA: " + SMA + "\n"+decision); 
     */ 
     tinyDB.putListString("names",stocknames); 
     tinyDB.putListString("tickers",stocktickers); 
     //call interface activity comming up to Activity, then down to next fragment 
     recyclerinterface.communicateup(); 






    }else{ 
     Toast error = Toast.makeText(getActivity(),"Network Problem",Toast.LENGTH_SHORT); 
     error.show(); 
    } 

} 

Frag B (ListFragment) (https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/ListFragment.java)

public class ListFragment extends Fragment { 
private HistoricalQuote[] hisstocks; 
private Stock[] stocks; 
private RecyclerView recyclerView; 
private StockAdapter mAdapter; 


public ArrayList<String> stocknames; 
public ArrayList<String>stocktickers; 
TinyDB tinyDB; 


@Override 
public void onCreate(Bundle savedInstanceState){ 
    //exists only to set the options menu 
    super.onCreate(savedInstanceState); 
    setHasOptionsMenu(true); 

    //fetching arraylists 

} 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.content_list, container, false); 
    //Convert the arraylist into an array for arrayadapter 
    stocknames = new ArrayList<String>(); 
    stocktickers = new ArrayList<String>(); 

    tinyDB = new TinyDB(getContext()); 

     stocknames = tinyDB.getListString("names"); 
     stocktickers= tinyDB.getListString("tickers"); 

     if (!stocknames.isEmpty()){ 
      for (int i =0;i<stocknames.size();i++){ 
       Toast toast= Toast.makeText(getActivity(),stocknames.get(i),Toast.LENGTH_SHORT); 
       toast.show(); 
      } 
     } 


    recyclerView = (RecyclerView)view.findViewById(R.id.recylerView); 

    recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.HORIZONTAL)); 
    //http://stackoverflow.com/questions/24618829/how-to-add-dividers-and-spaces-between-items-in-recyclerview 
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 
    recyclerView.setItemAnimator(new DefaultItemAnimator()); 
    //layoutManager necessary because it positions views on screen, in this case linearly 

    if (stocknames.isEmpty() ||stocknames ==null){ 
     recyclerView.setVisibility(View.GONE); 
    }else{ 

     updateUI(); 

    } 


    return view; 

} 

public void refreshUI(){ 
    stocknames.clear(); 
    stocktickers.clear(); 

    stocknames = tinyDB.getListString("names"); 
    stocktickers= tinyDB.getListString("tickers"); 
    if (mAdapter == null) { 
     mAdapter = new StockAdapter(stocknames,stocktickers); 
     recyclerView.setAdapter(mAdapter); 
    } else { 
     recyclerView.invalidate(); 
     mAdapter.notifyDataSetChanged(); 


    } 

} 


public void updateUI() { 
    //updateUI must be called EXPLICITLY! 

    stocknames = tinyDB.getListString("names"); 
    stocktickers= tinyDB.getListString("tickers"); 
     if (mAdapter == null) { 
      mAdapter = new StockAdapter(stocknames,stocktickers); 
      recyclerView.setAdapter(mAdapter); 
     } else { 
      mAdapter.notifyDataSetChanged(); 


     } 



} 

private class StockAdapter extends RecyclerView.Adapter<StockHolder>{ 
    private ArrayList<String>stocknames; 
    private ArrayList<String>stocktickers; 



    public StockAdapter(ArrayList<String>names,ArrayList<String> tickers){ 

     this.stocknames=names; 
     this.stocktickers=tickers; 
    } 

    @Override 
    public StockHolder onCreateViewHolder(ViewGroup parent, int viewType){ 
     LayoutInflater layoutinflater = LayoutInflater.from(getActivity()); 
     View view= layoutinflater.inflate(R.layout.row,parent,false); 
     return new StockHolder (view); 
    } 

    //Bind datato stockholder depending on position in arraylist 
    public void onBindViewHolder(StockHolder holder, int position){ 
     String stockname = stocknames.get(position); 
     String stockticker =stocktickers.get(position); 
     holder.bindStock(stockname,stockticker); 
    } 

    @Override 
    public int getItemCount(){ 
     return stocknames.size(); 
    } 
} 


private class StockHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ 

    private String stockname; 
    private String stockticker; 
    private TextView nametextView; 
    private TextView tickertextView; 

    public StockHolder(View itemView){ 
     super(itemView); 
     itemView.setOnClickListener(this); 
     nametextView =(TextView)itemView.findViewById(R.id.name); 
     tickertextView= (TextView)itemView.findViewById(R.id.ticker); 
    } 

    @Override 
    public void onClick(View v){ 
     Intent launchGraph= new Intent(v.getContext(),GraphActivity.class); 

     launchGraph.putExtra("stockticker",stockticker); 
     launchGraph.putExtra("stockname",stockname); 

     startActivity(launchGraph); 

     //Animations? 


    } 
    //Actual binder method, maybe add a current 

    public void bindStock(String stocknom, String stocktick){ 
     this.stockname=stocknom; 
     this.stockticker = stocktick; 

     nametextView.setText(stockname); 
     tickertextView.setText(stockticker); 
    } 
} 

Vielen Dank im Voraus.

BEARBEITEN: Problem gelöst, indem ein neuer Adapter erstellt und mit neuen Arraylisten verknüpft wurde, die aus der TinyDB gezogen wurden, wodurch Adapter effektiv ausgetauscht wurden.

+0

zeigen eine [MCVE] Ihres Codes in Ihrer Frage, nicht als externe Links, bitte. –

+0

mein Fehler, behoben. –

+0

Danke, das ist komplett, ja, aber ist das minimal? Viel Platz und Block Kommentare ... –

Antwort

0

Das Problem wurde behoben, indem ein ganz neuer RecyclerView-Adapter erstellt wurde, an den neue Arraylist-Daten gebunden wurden. Anschließend wurde die gesamte Recycleransicht für die Verwendung dieses neuen Adapters festgelegt. All dies wurde in einem einzigen Schritt von FragA durchgeführt, wobei die im Code der Lösung gezeigten Schnittstellen verwendet wurden.

Methode unten gezeigt:

public void refreshUI(){ 
    tinyDB = null; 

    tinyDB = new TinyDB(getContext()); 

    newnames = tinyDB.getListString("names"); 
    newtickers= tinyDB.getListString("tickers"); 

     mAdapter = new StockAdapter(newnames,newtickers); 
     recyclerView.setAdapter(mAdapter); 


} 
Verwandte Themen