Android: передача данных обновления между родительским и дочерним фрагментами

Как я могу передать данные от "Родителя" Fragment "Ребенку" Fragment?. Я уже посмотрел, как передавать данные между фрагментами, но в моем случае я не могу использовать Activity,

В моем приложении у меня есть Activity который создает Fragment нажав на Listitem из Activity, Fragment создает класс и Fragment получает постоянные данные из класса создания данных, который создается циклом. После создания Fragmentсоздает несколько дочерних фрагментов, каждый из которых имеет разные представления, которые должны отображать обновленные данные.

Но моя проблема в том, что я не могу передать данные из Parentfragment к Childfragment, Я не уверен, что это преходящая проблема или проблема создания Childfragment,

В моем случае "textValueView" и "mySeries" всегда равны нулю. Зачем?

ФРАГМЕНТ РОДИТЕЛЯ

public class ScreenSlidePagerActivity extends Fragment {


    Bundle bundle = new Bundle();

    public boolean stop = false;

    private ServerFragment newServer;

   //Pager Widget for animation handeling
    private ViewPager mPager;

   //Pager Adapter provides the pages to view pager widget
    private PagerAdapter mPagerAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                        Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


        ViewGroup sliderFragmentView = (ViewGroup)   inflater.inflate(R.layout.fragment_screen_slide, container, false);

        ConnectAndReadTask myTask = new ConnectAndReadTask(ScreenSlidePagerActivity.this , "opc.tcp://10.0.2.2:52520" +
            " - " + "mySinus", new NodeId(Integer.parseInt("2"), "mySinus"));
        myTask.execute(new String[]{"opc.tcp://10.0.2.2:52520"});


        // Initiate a ViewPager and a PagerAdapter
        mPager = (ViewPager) sliderFragmentView.findViewById(R.id.pager);
        mPagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager());
        mPager.setAdapter(mPagerAdapter);

        return sliderFragmentView;

}

private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {

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

    @Override
    public Fragment getItem(int position) {
        switch(position){
            case 0:
                return newServer.newInstance("url","url","url");
            case 1:
                return new GaugeFragment();
            case 2:
                return new GaugeFragment();
            default:
                return new GaugeFragment();
        }

    }

    @Override
    public int getCount() {
        return 3;
    }
}

@Override
public void onDestroy() {
    stop = true;
    super.onDestroy();
}

/**
 *
 * @param value
 */

public void setData(String value)
{

    Log.d("ScreenSlide.SetData", value);
   // mCallback.onValueSelected(value);#
  bundle.putString("value", value);
    ServerFragment.create(value);
    newServer.setArguments(bundle);
   //newServer.setData(value);

}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    newServer = new ServerFragment();
}
}

ДЕТСКИЙ ФРАГМЕНТ

public class ServerFragment extends Fragment {

TextView urlTextView, nodeTextView, valueTextView;

public static String passValue;
//Graph
GraphView graphView;
public LineGraphSeries<DataPoint>mySeries;
private double graph2LastXValue = 5d;


public View myFragmentView;
public String url, namespace, nodeName;

public ServerFragment() {}


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

   myFragmentView  = inflater.inflate(R.layout.fragment_server, container, false);

    urlTextView = (TextView)myFragmentView.findViewById(R.id.urlTextView);
    nodeTextView = (TextView)myFragmentView.findViewById(R.id.nodeTextView);
    valueTextView = (TextView)myFragmentView.findViewById(R.id.valueTextView);



    //Graph
    graphView = (GraphView)myFragmentView.findViewById(R.id.graphView);
    mySeries = new LineGraphSeries<DataPoint>();

    mySeries.setColor(Color.RED);

    graphView.addSeries(mySeries);
    graphView.getViewport().setXAxisBoundsManual(true);
    graphView.getViewport().setMinX(0);
    graphView.getViewport().setMaxX(100);
    graphView.getViewport().setMinY(-20);
    graphView.getViewport().setMaxY(70);

    url = getArguments().getString("url");

    urlTextView.setText(getArguments().getString("url"));
    nodeTextView.setText(getArguments().getString("ns") + " | " + getArguments().getString("nodeName"));

    return myFragmentView;

}



public void setData() {


    Bundle bundle = this.getArguments();

    String value = bundle.getString("value");
    graph2LastXValue += 1d;
    try {
        mySeries.appendData(new DataPoint(graph2LastXValue, Double.parseDouble(value)),
                true, 200);
    }
    catch (Exception e)
    {
        Log.d("mySeries.appendData", e.getMessage());
    }

    try {
        valueTextView.setText(value);
    }

    catch (Exception e)
    {
        Log.d("valueTextView", e.getMessage());
    }




    Log.d("Serverfragment setData:" , value);
}



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

        setData();

}


@Override
public void onDestroy() {

    Log.d("ServerFragment", "disconnected");
    super.onDestroy();
}


@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

}


public static ServerFragment newInstance(String url, String ns, String nodeName) {

    ServerFragment sf = new ServerFragment();
    Bundle b = new Bundle();
    b.putString("url", url);
    b.putString("ns", ns);
    b.putString("nodeName", nodeName);



    sf.setArguments(b);

    return sf;
}

}

2 ответа

Решение

Вы можете добавить публичный метод к вашим фрагментам с данными, которые вы хотите в качестве аргументов. Затем вы можете вызвать этот метод из родительского фрагмента. Все, что вам нужно сделать, это получить ссылки на фрагменты, которые вы создаете.

Вы можете перебрать свои фрагменты, используя mPagerAdapter.getItem(int position);

Вы также можете добавлять идентификаторы к своим фрагментам по мере их создания, чтобы их было легче различать. например вместо new GaugeFragment() ты можешь сделать new GaugeFragment(identifierString), Теперь каждый фрагмент может рассказать вам информацию о том, "кто" это. Вы также можете иметь различные типы фрагментов.

    PagerAdapter mPagerAdapter;
    ScreenSlidePagerAdapter screenSlidePagerAdapter;

    screenSlidePagerAdapter =  new ScreenSlidePagerAdapter(getFragmentManager());
    mPagerAdapter = screenSlidePagerAdapter;

и позже, когда вы хотите установить свои данные:

    int count = screenSlidePagerAdapter .getCount();
    for(int i=0;i<count;i++){
        Fragment fragment = screenSlidePagerAdapter .getItem(i);
        if(fragment instanceof GaugeFragment){
            ((GaugeFrament)fragment).gaugeFragmentMethod(data);
            break;
        }
        else if(fragment instanceof OtherTypeOfFragment){
            ((OtherTypeOfFragment)fragment).otherTypeOfFragmentMethod(data);
            break;
        }
    }

Обычный способ - передать его из 1-го фрагмента хосту Activity, и он отправит его во 2-й фрагмент.

Я не знаю, почему вы не можете сделать это, но если это действительно так, как вы говорите, вы можете попробовать использовать библиотеку Otto Bus от Джейка Уортона и просто подписать оба своих фрагмента на автобус.

class Fragment1 { 

  @Override
    public void onResume() {
        super.onResume();
        mBus.register(this);
    }

    @Override
    public void onPause() {
        mBus.unregister(this);
        super.onPause();
    }

    //let's assume you need to do it it on button click
    @Override
    public void onClick(View v) {
      mBus.post(new SomeDataEvent())
    }
} 
//======================

class Fragment2 { 

  @Override
    public void onResume() {
        super.onResume();
        mBus.register(this);
    }

    @Override
    public void onPause() {
        mBus.unregister(this);
        super.onPause();
    }

    //here we define method to handle your data
    @Subscribe
    public void onSomeData(SomeDataEvent object) {
      //do something with it
    }
} 

Более подробная информация здесь http://square.github.io/otto/

Другие вопросы по тегам