As the title says, I am trying to access (setText,etc) a TextView thats inside a fragment. The fragment is loaded into a viewpager in an activity. I want to access this TextView from the activity class.
private PagerAdapter mPagerAdapter;
private ViewPager pager;
FragmentPageOne fragPageOne;
FragmentPageTwo fragPageTwo;
Exert of Activity's onCreate:
fragPageOne= new FragmentPageOne();
fragPageTwo = new FragmentPageTwo();
mPagerAdapter = new ViewPagerAdapter(this, getSupportFragmentManager(),
fragPageOne.getClass(), fragPageTwo.getClass(),
);
pager = (ViewPager) findViewById(R.id.eventPager);
pager.setAdapter(mPagerAdapter);
ViewPagerAdapter class:
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Class<? extends Fragment>> fragmentsClasses;
private final Context context;
public EventViewPagerAdapter(Context context, FragmentManager fm, Class<? extends Fragment>... fragmentsClasses) {
super(fm);
this.context = context;
this.fragmentsClasses = Arrays.asList(fragmentsClasses);
}
public Fragment getItem(int position) {
return Fragment.instantiate(context, fragmentsClasses.get(position).getName());
}
#Override
public int getCount() {
return fragmentsClasses.size();
}
}
FragmentPageOne class (FragmentPageTwo's structure is similar.):
public class FragmentPageOne extends Fragment {
public View rootView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(container == null) {
return null;
}
rootView = inflater.inflate(R.layout.fragment_page_1, container, false);
return (LinearLayout) rootView;
}
}
I am getting a null pointer (obviously) when i try to use this (within the activity itself):
TextView text = (TexView) pager.findViewById(R.id.textview1);
text.setText("hello world);
get your current fragment :
public Fragment getVisibleFragment(){
FragmentManager fragmentManager = this.getSupportFragmentManager();
List<Fragment> fragments = fragmentManager.getFragments();
if(fragments != null){
for(Fragment fragment : fragments){
if(fragment != null && fragment.isVisible())
return fragment;
}
}
return null;
}
then get the view of the fragment to use findViewById from this view.
You're best bet is to do this in the instantiateItem override method in the pager adapter like so;
private LayoutInflater layoutInflater;
private Activity activity;
private int[] layouts;
public WalletViewPagerAdapter(int[] layouts , Activity activity) {
this.activity = activity;
this.layouts =layouts;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
layoutInflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(layouts[position], container, false);
if (position ==0) {
TextView availableBalance = view.findViewById(R.id.available);
availableBalance.setText("N100,0000,000");
}
container.addView(view);
return view;
}
The view you're trying to access is not yet available as at the time you're calling it. Try overriding the onViewCreated method then use the view parameter to get textView like so;
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
TextView availableBalance = view.findViewById(R.id.available);
availableBalance.setText("N100,0000,000");
}
Related
I have a ViewPager that I want to add Fragments to.
The ViewPager is viewed correctly on the screen but unfortunately it does not hold any content.
I have seen the suggestion in some posts to replace
getSupportFragmentManager()
with
getChildFragmentManager()
But I need the ActionBar. Unfortunately the ChildFragmentmanager is not available in the AppCompatActivity.
While debugging I have realized that the Fragment's onCreateView() method is called and it returns a layout.
Question: How can I make the Fragments visible? And were is the main difference from my code to that sample ?
Activity:
public class ViewPagerActivity extends AppCompatActivity {
private ViewPager mViewPager;
private List<Location> locationList = new ArrayList<>();
private locationsBaseHandler db;
private CustomPagerAdapter mAdapter;
private Location mLocation;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewpager);
locationList.add(someData);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mAdapter = new CustomPagerAdapter(this, getSupportFragmentManager(), locationList);
mViewPager.setAdapter(mAdapter);
}
}
Pager Adapter:
public class CustomPagerAdapter extends FragmentPagerAdapter {
private Context mContext;
private List<Location> locationList = new ArrayList<>();
public CustomPagerAdapter(Context mContext, FragmentManager fm, List<Location> locationList) {
super(fm);
this.locationList.addAll(locationList);
this.mContext = mContext;
}
#Override
public Fragment getItem(int position) {
return LocationFragment.newInstance(position);
}
#Override
public int getCount() {
return 5;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return false;
}
}
Fragment:
public class LocationFragment extends Fragment {
private static final String ARG_LAYOUT_ID = "page_number";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_location, container, false);
return layout;
}
public static LocationFragment newInstance(int selectedIdForIndex) {
LocationFragment fragment = new LocationFragment();
Bundle args = new Bundle();
args.putInt(ARG_LAYOUT_ID, selectedIdForIndex);
fragment.setArguments(args);
return fragment;
}
public int getPageNumber() {
return getArguments().getInt(ARG_LAYOUT_ID);
}
}
Try to remove the method isViewFromObject in CustomPagerAdapter.
#Override
public boolean isViewFromObject(View view, Object object) {
return false;
}
We can see this comment to isViewFromObject:
Determines whether a page View is associated with a specific key object
as returned by {#link #instantiateItem(ViewGroup, int)}. This method is
required for a PagerAdapter to function properly.
i'm trying to put ViewPager into ListView
here the code of ListView AdapterClass:
public class AdapterPager extends BaseAdapter {
.....
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.component_pager, parent, false);
new ViewHolder(view, itemData.get(position));
}
return view;
}
View Holder:
private class ViewHolder {
ViewPager pager;
PagerAdapter pagerAdapter;
public ViewHolder(View view, ModelItem model){
pager = (ViewPager) view.findViewById(R.id.pager);
pager.setId(model.getId()); /// uniq ID
pagerAdapter = new MyFragmentPagerAdapter(((FragmentActivity)view.getContext()).getSupportFragmentManager());
pager.setAdapter(pagerAdapter);
}
then, Pager Adapter:
static final int PAGE_COUNT = 2;
private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return FragmentComponentPager.newInstance(position, mModel);
}
#Override
public float getPageWidth(int position) {
float f_width = 1f;
return f_width;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
}
and, the last, Pager Fragment:
public class FragmentComponentPager extends Fragment {
static final String ARGUMENT_PAGE_NUMBER = "arg_page_number";
static final String ARGUMENT_NAME = "arg_name";
int pageNumber;
public static FragmentComponentPager newInstance(int page, ModelItem data) {
FragmentComponentPager pageFragment = new FragmentComponentPager();
Bundle arguments = new Bundle();
arguments.putInt(ARGUMENT_PAGE_NUMBER, page);
if (data != null){
arguments.putString(ARGUMENT_NAME, data.getName());
}
pageFragment.setArguments(arguments);
return pageFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pageNumber = getArguments().getInt(ARGUMENT_PAGE_NUMBER);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.component_list, null);
TextView tvTitle = (TextView) view.findViewById(R.id.tvTitle);
tvTitle.setText(getArguments().getString(ARGUMENT_NAME));
return view;
}
}
when i run it ListView shows all items that i've added, but all of them, except the last one, with empty ViewPager.
and, if i removed pager.setId(model.getId()); the first item shows view pager, and the others empty.
guess that smth wrong with FragmentManager, but have no idea how deal with it :(
In your ViewHolder you need to call getChildFragmentManager instead of getSupportFragmentManager.
I am using ViewPager in my activity and it only has two fragments, both implemented in similar structure as follow, so there should always be a fragment returned when getInstanced is called:
public class ListReminderFragment extends Fragment {
private View rootView;
private static ListReminderFragment listReminderFragment;
public static ListReminderFragment getInstance() {
if(listReminderFragment != null)
return listReminderFragment;
else {
listReminderFragment = new ListReminderFragment();
return listReminderFragment;
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.content_main_screen, container, true);
return rootView;
}
#Nullable
#Override
public View getView() {
return rootView;
}
}
This is my adapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return ListReminderFragment.getInstance(); // temporary
}
#Override
public int getCount() {
return 2;
}
}
And I am initialising my ViewPager as below, in OnCreate() in the activity that has the ViewPager:
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
ViewPager viewPager = (ViewPager) findViewById(R.id.main_view_pager);
viewPager.setAdapter(viewPagerAdapter);
But when I call viewPager.getChildAt(), viewPagerAdapter.getItem(0).getView(), they both return null,
when I call viewPager.getChildCount(), it returns 0 instead of 2.
How should I access the views in side the fragment in ViewPager?
Have a 2 level UI, The top level has a tab strip powered by a FragmentPagerAdapter. One of the fragments in turn has a 2nd level FragmentPagerAdapter and its own tab strip carrying a couple of "sub"fragments. Now, the sub fragments display when the first time the top level tabs are traversed. But the "sub"fragments do not display upon a 2nd iteration
Here is how the subtabpager adapter is created in one of the fragments which exist at the top level
public final class MainLevelTabFragment extends Fragment {
private SubpageTabsPagerAdapter mSubpagePagerAdapter;
private ViewPager mSubpageViewPager;
private SlidingTabLayout mSlidingTabLayout;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View rootView = null;
Bundle bundle = getArguments();
rootView = inflater.inflate(R.layout.fragment_tab_main_level, container, false);
mSubpageViewPager = (ViewPager) rootView.findViewById(R.id.subpage_screen_tabs_pager);
mSlidingTabLayout = (SlidingTabLayout) rootView.findViewById(R.id.sliding_tabs);
mSubpagePagerAdapter = new SubpageTabsPagerAdapter(getSupportFragmentManager, getActivity());
mSubpageViewPager.setAdapter(mSubpagePagerAdapter);
return rootView;
}
The SubpageTabsPagerAdapter code looks like this
public class SubpageTabsPagerAdapter extends FragmentPagerAdapter {
private Context mContext;
private Cursor mCursor;
public SubpageTabsPagerAdapter(FragmentManager fm, Context context) {
super(fm);
mContext = context;
}
#Override
public Fragment getItem(int position) {
if (null == mCursor)
return null;
mCursor.moveToPosition(position);
Fragment fragment = new SubtabFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return (null != mCursor) ? mCursor.getCount() : 0;
}
#Override
public CharSequence getPageTitle(int position) {
if (null == mCursor)
return null;
mCursor.moveToPosition(position);
return "title";
}
public void swapCursor(Cursor c) {
if (mCursor == c)
return;
mCursor = c;
notifyDataSetChanged();
}
}
I think you might have to use getChildFragmentManager() instead of getSupportFragmentManager() in your SubpageTabsPagerAdapter constructor.
I have a viewpager with 2 fragment pages inside it. Now i want to access the views (textview,buttons) from the first fragment page but everytime Iam getting Nullpointer exception
check out my code
Fragment i want to access its views:
public class ListPagerFragment extends Fragment
{
ListView listview;
TextView text;
private ViewPager pager;
public static ListPagerFragment newInstance(int message)
{
ListPagerFragment f = new ListPagerFragment();
// pass the text message received from main activity into a bundle to be
// delivered to the new fragment
Bundle bdl = new Bundle();
bdl.putInt("num", message);
f.setArguments(bdl);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.list_pager_fragment, container, false);
return v;
}
public void fillList(Nameslist list)
{
listview = (ListView) getView().findViewById(R.id.listView1);
if (listview == null)
System.out.println("listview null"); //this should not be null but
//it is thus the nullpointerexception
if (listview.getAdapter() == null)
{
MyListAdapter listAdapter = new MyListAdapter(getActivity(), R.layout.listview_item, list.getVenues());
listview.setAdapter(listAdapter);
}
else
{
((MyListAdapter) listview.getAdapter()).updateAdapter(list.getnames());
}
}
PagerAdapter code
public class MyPagerAdapter extends FragmentStatePagerAdapter
{
private int mCount = 1;
public MyPagerAdapter(FragmentManager fm)
{
super(fm);
// TODO Auto-generated constructor stub
}
#Override
public Fragment getItem(int position)
{
switch (position)
{
case 1:
return ResultsPagerFragment.newInstance(position);
}
return ListPagerFragment.newInstance(position);
}
#Override
public int getCount()
{
// TODO Auto-generated method stub
return mCount;
}
}
and main finally activity code
private ViewPager pager;
private MyPagerAdapter pagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(pagerAdapter);
}
and later somewhere in the activity i have the code that should trigger the fillList from Fragment to do the job
Fragment frag = pagerAdapter.getItem(0); //this should give me the Fragment i want right?
((ListPagerFragment)frag).fillList(result);
What am I missing here?
Ok I found it seems like the problem was in my custom FragmentStatePagerAdapter
All I had to do is create the fragments when activity is created and put them into an ArrayList which it will be later passed to MyPagerAdapter
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
frags = new ArrayList<Fragment>();
frags.add(ListPagerFragment.newInstance(0));
frags.add(ResultsPagerFragment.newInstance(1));
pagerAdapter = new MyPagerAdapter(getSupportFragmentManager(),frags);
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(pagerAdapter);
}
And then modify the MyPagerAdapter like so:
public class MyPagerAdapter extends FragmentStatePagerAdapter
{
private List<Fragment> fragments;
public MyPagerAdapter(FragmentManager fm, List<Fragment> frags)
{
super(fm);
this.fragments = frags;
}
#Override
public Fragment getItem(int position)
{
return fragments.get(position);
}
}
kind of silly isn't it? I don't understand the point but it worked
That's probably because you are trying to use the views from your Activity, before your ListPagerFragment.onCreateView() has inflated your xml layout. Move what's inside your onCreate() and some code of fillList() to onCreateView(), something like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.list_pager_fragment, container, false);
listview = (ListView) v.findViewById(R.id.listView1);
pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
pager = (ViewPager) v.findViewById(R.id.pager);
pager.setAdapter(pagerAdapter);
return v;
}
After your fragments onCreateView() has inflated the view, you can try to fill it.
And don't forget to clear your view references and unregister your listview listener(if you set one) in onDestroyView() to avoid memory leaks, e.g.
#Override
public void onDestroyView() {
super.onDestroyView();
listview.setOnItemClickListener(null);
...
listview = null;
}
read about the fragment's lifecycle --> Fragment's Lifefycle