TPWang
TPWang

Reputation: 1352

How to change views in ViewPager Fragment

I have a ViewPager with fragments in my activity, each page has a textview, I want to change the text of the textview from the onCreate method in the activity that contains the viewpager. How should I go about doing that?

below is the code that would return a null object exception:

Fragment:

public class MyFragment extends Fragment {

private TextView textView;

public static MyFragment getInstance(){
    return new MyFragment();
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_layout, container, false);

    textView = (TextView) rootView.findViewById(R.id.textView);

    return rootView;
}

public void setText(String text){
    textView.setText(text);
}
}

Adapter:

public class ViewPagerAdapter extends FragmentPagerAdapter {

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

@Override
public Fragment getItem(int position) {
    return MyFragment.getInstance();
}

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

Activity onCreate:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
    final ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(adapter);

    MyFragment fragment = (MyFragment) adapter.getItem(0);
    fragment.setText("Altered");        // and this returns null pointer exception
}

Thank you!

Upvotes: 1

Views: 68

Answers (2)

Narendra Motwani
Narendra Motwani

Reputation: 1115

Try This Fragment:

public class MyFragment extends Fragment {

private TextView textView;
private String Text;
public MyFragment (String Text){
    this.Text=Text;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_layout, container, false);

    textView = (TextView) rootView.findViewById(R.id.textView);
    textView.setText(Text); 
    return rootView;
}

}

Adapter :

public class ViewPagerAdapter extends FragmentPagerAdapter {

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

@Override
    public Fragment getItem(int position) {
    return new MyFragment("Altered");
}

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

Activity onCreate:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
    final ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(adapter);
}

Upvotes: 0

tachyonflux
tachyonflux

Reputation: 20211

Most FragmentPagerAdapters will have an addFragment method and will keep track various fragments that are added to it via an internal object:

public class MyPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragments = new ArrayList<>();
    private final List<String> mFragmentTitles = new ArrayList<>();

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

    public void addFragment(Fragment fragment, String title) {
        mFragments.add(fragment);
        mFragmentTitles.add(title);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

    @Override
    public int getCount() {
        return mFragments.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitles.get(position);
    }
}

As it stands, your implementation of getItem returns a new instance of MyFragment every time it is called. As such, MyFragment fragment = (MyFragment) adapter.getItem(0); is a new instance that will never be loaded into the ViewPager, will never be inflated, and hence has a null textView reference.

The other issue is that within the onCreate of your activity, the fragments have not yet been inflated, so the textView will be null unless you delay the call:

final MyFragment fragment = (MyFragment) mPagerAdapter.getItem(0);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        fragment.setText("Altered");
    }
}, 100);

But really, why not just set it to the correct value when it is initialized?

Upvotes: 1

Related Questions