在Viewpager中的2个片段之间进行通信 - 从片段A更新片段B中的RecyclerView

时间:2017-02-03 22:57:27

标签: android android-fragments android-viewpager android-recyclerview

我正在构建一个简单的股票显示应用程序,允许您获取感兴趣的股票(frag A),将它们存储在TinyDB中,并将它们显示在recyclerView(frag B)中。

该框架曾经工作正常 - 直到我决定合并一个viewpager和Tablayout主机。我无法在Frag B中获得RecyclerView来实时显示新数据。这是因为活动viewpager在启动时初始化两个片段,这意味着你不能再次调用onCreateView代码了。我相信。

通过活动在两个片段之间进行通信已经在本网站上进行过触摸,但我找到了最好的例子:

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

使用两个接口,一个用于从Frag A到Activity进行通信,另一个用于从Activity到Frag B进行通信。但是我遇到了严重的问题 -

  • 目前,点击"清除投资组合"和"添加股票" Frag A中的投资组合按钮导致Frag B中出现空白屏幕,这意味着正在调用某些内容,但新数据未显示/未与适配器相关联

活动(https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/ViewHolderActivity.java

<%= Category.find_by(name: 'test').locations.count %>

Frag A(MainFragment) (https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/MainFragment.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 B(ListFragment) (https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/ListFragment.java

@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();
    }

}

提前致谢。

编辑:通过创建新的适配器并将其链接到从TinyDB中提取的新arraylists来解决问题,从而有效地交换适配器。

1 个答案:

答案 0 :(得分:0)

通过创建一个全新的RecyclerView适配器解决了这个问题,新的arraylist数据绑定到该适配器,然后将整个recyclerview设置为使用这个新的适配器。所有这一切都是从FragA一步完成的,使用解决方案中代码中显示的接口。

如下所示的方法:

 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);


}
相关问题