我有一个Activity
来托管两个Fragments
。一个包含EditText
,另一个包含GridView
中的输入。 Fragment1
实现了一个接口,用于在用户想要保存输入时进行通知。在Activity
我想将数据传递给Fragment2的ArrayAdapter
,但在这里我得到了NullPointerException
。
的活动:
public class SwipeTest extends FragmentActivity implements TestFragment1
.OnFragmentInteractionListener {
private final String[] tabs = {"Test 1", "Test 2"};
private ViewPager pager;
private ActionBar actionBar;
private TabsPagerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.pager = new ViewPager(this);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup
.LayoutParams.MATCH_PARENT,
ViewGroup
.LayoutParams.MATCH_PARENT);
this.pager.setLayoutParams(params);
setContentView(this.pager);
this.actionBar = getActionBar();
this.adapter = new TabsPagerAdapter(
getSupportFragmentManager());
this.pager.setAdapter(this.adapter);
this.actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
setUpViewPager();
setUpActionBar();
}
/**
* Sets up the ViewPager and adds an OnPageChangeListener
*/
private void setUpViewPager() {
this.pager.setAdapter(this.adapter);
// pager needs an id; crashes if it has none
this.pager.setId(123456789);
// Set up the listener
ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager
.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i2) {
}
@Override
public void onPageSelected(int i) {
SwipeTest.this.actionBar.setSelectedNavigationItem(i);
}
@Override
public void onPageScrollStateChanged(int i) {
}
};
this.pager.setOnPageChangeListener(onPageChangeListener);
}
/**
* Sets up the ActionBar with it's tabs and adds an ActionBar.TabListener to
* them
*/
private void setUpActionBar() {
this.actionBar = getActionBar();
this.actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Set up listener
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
@Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction
fragmentTransaction) {
SwipeTest.this.pager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction
fragmentTransaction) {
}
@Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction
fragmentTransaction) {
}
};
for (String tab_name : this.tabs) {
this.actionBar.addTab(
this.actionBar.newTab()
.setText(tab_name)
.setTabListener(tabListener));
}
}
/**
* Interface method of Fragment1
*/
@Override
public void onFragmentInteraction(String s) {
// This gets the fragment correct
TestFragment2 fragment = (TestFragment2) ((TabsPagerAdapter) pager
.getAdapter()).getItem(1);
// This assigns null to adapter
ArrayAdapter<String> adapter = (ArrayAdapter<String>) fragment
.getAdapter();
adapter.add(s);
adapter.notifyDataSetChanged();
}
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new TestFragment1();
case 1:
return new TestFragment2();
}
return null;
}
@Override
public int getCount() {
return 2;
}
}
}
片段1:
public class TestFragment1 extends Fragment {
private OnFragmentInteractionListener mListener;
private EditText edit;
public TestFragment1() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
LinearLayout layout = new LinearLayout(getActivity());
layout.setLayoutParams(params);
this.edit = new EditText(getActivity());
Button btn = new Button(getActivity());
btn.setText("Save");
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onButtonPressed();
}
});
layout.addView(this.edit);
layout.addView(btn);
return layout;
}
public void onButtonPressed() {
if (this.mListener != null) {
String input = this.edit.getText().toString();
this.mListener.onFragmentInteraction(input);
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
this.mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement " +
"OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
this.mListener = null;
}
public interface OnFragmentInteractionListener {
public void onFragmentInteraction(String s);
}
}
Fragment2:
public class TestFragment2 extends Fragment {
private final List<String> data = new ArrayList<String>();
private ArrayAdapter<String> adapter;
public TestFragment2() {
// Required empty public constructor
}
public ArrayAdapter getAdapter() {
return this.adapter;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
GridView view = new GridView(getActivity());
GridView.LayoutParams params = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
view.setLayoutParams(params);
this.data.add("Hello");
this.data.add("World");
this.adapter = new ArrayAdapter(getActivity(),
android.R.layout
.simple_list_item_1,
this.data);
view.setAdapter(this.adapter);
return view;
}
}
我不知道为什么ArrayAdapter<String> adapter = (ArrayAdapter<String>) fragment.getAdapter();
为空。那么,我如何访问Fragment2的字段?
答案 0 :(得分:1)
关于生命周期似乎有问题。您可能知道,onCreateView()是异步方法,因此可以在setAdapter()之前访问片段实例。
我的建议是在SwipeTest#onCreate()中创建TestFragment2实例。此外,每次按下按钮时,您的代码都会创建新实例。这似乎不太好。
答案 1 :(得分:0)
如果寻呼机从未显示过第二个片段,则在调用fragment1接口回调时,寻呼机返回null:
// This gets the fragment correct
TestFragment2 fragment = (TestFragment2) ((TabsPagerAdapter) pager
.getAdapter()).getItem(1);
因此,您对getAdapter()
的后续调用将导致NPE。
答案 2 :(得分:0)
问题出在PagerAdapter
之内。我使用getItem()
来接收绑定到标签位置的Fragment
。错误是我返回了Fragment
的新实例,而不是返回现有的Fragment
。由于新的Fragment
从未显示过Fragment
的{{1}},因此onCreateView()
从未被调用过。这就是我在
setUpAdapter()
的原因
NPE
方法[*]:
ArrayAdapter<String> adapter = (ArrayAdapter<String>) fragment
.getAdapter();
adapter.add(s);
[*]未经测试,因为我改变了我的代码而不再使用public class TabsPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<Fragment>();
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
mFragments.add(0, new TestFragment1());
mFragments.add(1, new TestFragment2());
}
@Override
public Fragment getItem(int index) {
if (index > (mFragments.size() - 1) )
return null;
return mFragments.get(index);
}
@Override
public int getCount() {
return mFragments.size();
}
}
,但我认为解决方案是可理解的。