问题
This one is driving me nuts. Basically, I want to create a ViewPager
and add a few Fragment
s to it. Then, all I want to do, it set a value in one of the Fragment
's TextView
s. I can add the Fragment
s fine, and they attach, but when I go to findViewById()
for one of the TextView
s in the first Fragment
it throws a NullPointerException
. I, for the life of me, can't figure out why.
Here's my code so far, let me know if more is needed please.
public class SheetActivity extends FragmentActivity {
// /////////////////////////////////////////////////////////////////////////
// Variable Declaration
// /////////////////////////////////////////////////////////////////////////
private ViewPager viewPager;
private PagerTitleStrip titleStrip;
private String type;
private FragmentPagerAdapter fragmentPager; //UPDATE
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sheet);
viewPager = (ViewPager) findViewById(R.id.viewPager);
titleStrip = (PagerTitleStrip) findViewById(R.id.viewPagerTitleStrip);
// Determine which type of sheet to create
Intent intent = getIntent();
this.type = intent.getStringExtra("type");
FragmentManager manager = getSupportFragmentManager();
switch (type) {
case "1":
viewPager.setAdapter(new InstallAdapter(manager));
break;
case "2":
viewPager.setAdapter(new InstallAdapter(manager));
break;
}
fragmentPager = (FragmentPagerAdapter) viewPager.getAdapter(); //UPDATE
}
@Override
public void onResume() {
super.onResume();
fragmentPager.getItem(0).setText("something"); //UPDATE
}
class MyAdapter extends FragmentPagerAdapter {
private final String[] TITLES = { "Title1", "Title2" };
private final int PAGE_COUNT = TITLES.length;
private ArrayList<Fragment> FRAGMENTS = null;
public MyAdapter(FragmentManager fm) {
super(fm);
FRAGMENTS = new ArrayList<Fragment>();
FRAGMENTS.add(new FragmentA());
FRAGMENTS.add(new FragmentB());
}
@Override
public Fragment getItem(int pos) {
return FRAGMENTS.get(pos);
}
@Override
public int getCount() {
return PAGE_COUNT;
}
@Override
public CharSequence getPageTitle(int pos) {
return TITLES[pos];
}
}
}
All of Fragment
s I created only have the onCreateView()
method overridden so I can display the proper XML layout. Other than that they are 'stock'. Why can't I interact with elements in any of the Fragment
s?
UPDATE:
So do something like this?
public class FragmentA extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle inState) {
return inflater.inflate(R.layout.fragment_a, container, false);
}
public void setText(String text) {
TextView t = (TextView) getView().findViewById(R.id.someTextView); //UPDATE
t.setText(text);
}
}
XML LAYOUT FOR FRAGMENT A
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/someTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="22sp" />
</LinearLayout>
回答1:
Unless you are planning to change the value at runtime, you can pass the value into the fragment as a parameter. It is done my using a Bundle and passing it as args into a Fragment, which then retrieves it from it's args. More info here. If you implement this, your instantiation of new Fragments might look something like this:
public InstallAdapter(FragmentManager fm) {
super(fm);
FRAGMENTS = new ArrayList<Fragment>();
FRAGMENTS.add(FragmentA.newInstance("<text to set to the TextView>"));
FRAGMENTS.add(FragmentB.newInstance("<text to set to the TextView>"));
}
If, however, you are planning to update the value at runtime (it will change as user is running the app), then you want to use an Interface to channell communication between your fragment and your activity. Info here. This is what it might look like:
//Declare your values for activity;
ISetTextInFragment setText;
ISetTextInFragment setText2;
...
//Add interface
public interface ISetTextInFragment{
public abstract void showText(String testToShow);
}
...
//your new InstallAdapter
public InstallAdapter(FragmentManager fm) {
super(fm);
FRAGMENTS = new ArrayList<Fragment>();
Fragment fragA = new FragmentA();
setText= (ISetTextInFragment)fragA;
FRAGMENTS.add(fragA);
Fragment fragB = new FragmentB();
setText2= (ISetTextInFragment)fragB;
FRAGMENTS.add(fragB);
}
//then, you can do this from your activity:
...
setText.showText("text to show");
...
and it will update your text view in the fragment.
While it can be done "more easily", these methods are recomended because they reduce chances of bugs and make code a lot more readable and maintainable.
EDIT: this is what your Fragment should look like (modified your code):
public class FragmentA extends Fragment implements ISetTextInFragment {
TextView myTextView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle inState) {
View v = inflater.inflate(R.layout.fragment_a, container, false);
myTextView = (TextView)v.findViewbyId(R.id.someTextView)
return v;
}
@Override
public void showText(String text) {
myTextView.setText(text);
}
}
If after that you are still getting a null pointer exception, your TextView is NOT located where it needs to me, namely in the R.layout.fragment_a filem, and it needs to be located there. Unless you are calling the interface method BEFORE the fragment finished loading, of course.
回答2:
The TextView
is located in the fragments layout, not in the ViewPagers
or the PagerAdapter
, that is causing the NPE. Now, you have 2 options.
- The first is the easiest, you should simple move your code for changing the text into the corresponding fragment's class, FragmentA in this case.
Secondly, you could make the
TextView
into FragmentA static, so it can be accessed by other classes. So your code would look something like this:.... TextView myText; @Override public View onCreateView(....) { myLayout = ....; myText = myLayout.findViewById(yourID); .... }
And then you would change the text from somewhere else (if it's really necessary):
FragmentA.myText.setText("new text");
Explaining method 2
Use the following in your Fragment.
public static void setText(String text) {
TextView t = (TextView) getView().findViewById(R.id.someTextView);
t.setText(text);
}
Then change the text like:
FragmentA.setText("Lulz");
回答3:
This line:
TextView t = (TextView) findViewById(R.id.someTextViewInFragmentA);
is looking for the view in your ParentActivity. Of course it wont find it and that's when you get your NPE.
Try something like this:
Add a "tag" to your fragments when you add them
Use
someFragment = getSupportFragmentManager().findFragmentByTag("your_fragment_tag")
Get the view of the fragment
fragmentView = someFragment.getView();
And finally find your
TextView
and set the textTextView t = (TextView) fragmentView.findViewById(R.id.someTextViewInFragmentA); t.setText("some text");
回答4:
How about to change this line
TextView t = (TextView) getView().findViewById(R.id.someTextView); //UPDATE
to
TextView t = (TextView) getActivity().findViewById(R.id.someTextView); //UPDATE
then you can try to update "t" with .setText("some_string") inside "SheetActivity".
来源:https://stackoverflow.com/questions/24559124/android-set-text-of-textview-in-fragment-that-is-in-fragmentpageradapter