如何在没有按钮点击事件的情况下将数据从一个片段发送到另一个片段?
问题描述:
我正在做一些片段测试来研究它。我有疑问。如何在没有按钮点击事件的情况下将数据从一个片段发送到另一个片段?
我有一个只有一个项目的工具栏的主要活动,当这个项目被点击时,我添加一个片段A有一个列表视图。
然后我点击列表视图中的一个项目,该片段A被删除,它的片段B是更换到片段A.片段B有一个TextView来显示单击项目上的片段A.文本
要将片段A中的列表视图上点击的项目的数据传递给片段BI的文本视图,还需要在片段B xml上添加一个按钮,并且当单击此按钮时,单击的项目的数据被发送到片段B,然后使用正确的单击项目文本更新文本视图。
但它不可能自动做到这一点?如果在addText(String text)方法上调用此方法“sendDataToFragmentB(View view)”,它将显示为NullPointerException in FragmentB.addText(java.lang.String)
。但是,如果按钮被点击时,我有onClick =“sendDataTofragmentB”fragmentb XML中的按钮它的作品。
接口:
public interface Listener {
public void addText(String text);
}
主要活动
public class MainActivity extends AppCompatActivity implements Listener {
Toolbar toolbar;
FragmentManager manager;
private String text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = getFragmentManager();
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Pets");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
String msg = "";
if (item.getItemId() == R.id.search) {
msg = "search";
AddFragmentA();
}
Toast.makeText(this, msg + "clicked !", Toast.LENGTH_SHORT).show();
return super.onOptionsItemSelected(item);
}
@Override
public void addText(String text) {
this.text = text;
Toast.makeText(this, "Text Received in Activity" + text, Toast.LENGTH_SHORT).show();
sendDataToFragmentB();
}
public void sendDataToFragmentB(View view) {
FragmentB fragmentB = (FragmentB) manager.findFragmentByTag("fragB");
fragmentB.addText(text);
}
}
片段A:
public class FragmentA extends Fragment {
private static final String TAG = FragmentA.class.getSimpleName();
private ListView listItems;
private String[] items = {
"item1",
"item2",
};
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
listItems = (ListView) view.findViewById(R.id.listviewInFragment);
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_list_item_1, android.R.id.text1, items);
listItems.setAdapter(adapter);
listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
int positionCode = i;
String clickedValue = (String) adapterView.getItemAtPosition(i);
Listener listener = (Listener) getActivity();
listener.addText(clickedValue);
Toast.makeText(getActivity().getApplicationContext(), clickedValue, Toast.LENGTH_SHORT).show();
removeFragmentA();
AddFragmentB();
}
});
return view;
}
public void removeFragmentA(){
FragmentA fragmentA = (FragmentA) getFragmentManager().findFragmentByTag("fragA");
FragmentTransaction transaction = getFragmentManager().beginTransaction();
if(fragmentA !=null){
transaction.remove(fragmentA);
transaction.commit();
}
else{
Toast.makeText(this.getActivity(), "Fragment A not found", Toast.LENGTH_SHORT).show();
}
}
public void AddFragmentB(){
FragmentB fragmentB = new FragmentB();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(R.id.container, fragmentB, "fragB");
transaction.commit();
}
}
片段B:
public class FragmentB extends Fragment {
private TextView txvResult;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container, false);
txvResult = (TextView) view.findViewById(R.id.txvResult);
return view;
}
public void addText(String text){
String result = text;
txvResult.setText(result);
}
}
答
简短的回答:你想用捆绑。你可以尝试这样的事情
public void AddFragmentB(String clickedText){
FragmentB fragmentB = new FragmentB();
Bundle bundle = new Bundle();
bundle.putString(R.string.clicked_text_key, clickedText);
fragmentB.setArguments(bundle);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(R.id.container, fragmentB, "fragB");
transaction.commit();
}
FragmentB
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container, false);
txvResult = (TextView) view.findViewById(R.id.txvResult);
addText();
return view;
}
public void addText(){
String result = getArguments().getString(R.string.clicked_text_key);
txvResult.setText(result);
}
答
您可以EventBus Sticky Event与StickyEvent
尝试。当单击项目,只是张贴像
EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));
一个棘手的事件,然后添加FragmentB
后,您可以在subscribe
方法接收事件。
虽然还有另一个问题会影响到这一点,但至少应该尝试通过代码进行推理,就像现在一样。在'onItemClick()'中,看看事物的顺序。你甚至在你换出Fragment之前还想调用'listener.addText()'?甚至在创建'FragmentB'实例之前? –
而不是一个监听器,谁不发送捆绑的数据并直接访问它 –
谢谢。捆绑也是同样的问题。但问题是在String text = getArguments()。getString(“clickedValue”)中的onCreateView方法。 – JonD