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/