Viewpager returning null in fragment - android

I have a fragment that holds a viewpager and tablayout. I can access the tablayout from the fragment but when I try to do the same for the view pager it always returns null
//this is a method on the pagefragment
public override void OnActivityCreated(Bundle savedInstanceState)
{
base.OnActivityCreated(savedInstanceState);
tabs = this.View.FindViewById<TabLayout>(Resource.Id.mytab);
vp = (ViewPager) Activity.FindViewById(Resource.Id.myviewpage);
SetUpViewPager(vp);
tabs.SetupWithViewPager(vp);
}
vp alway returns null so the app crashes when it get to SetUpViewPager(vp) but the the tabs is accessible

I have a fragment that holds a viewpager and tablayout.
Problem is that you are hosting your ViewPager in a fragment, but you're trying to find it in the Activity. In the Fragment, you can code like this:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = inflater.Inflate(Resource.Layout.fragment1, container, false);
var tabs = view.FindViewById<TableLayout>(Resource.Id.mytab);
var vp1 = (ViewPager)view.FindViewById(Resource.Id.myviewpage);
return view;
}

Related

Passing arguments in Fragment

I' m trying to improve my android app. I have main app menu (with possible actions) in a GridView 3x3. And I decided to add ViewPager to separate my grid. Before I've added ViewPager, I had only one Activity with GridView. In my onCreate method, I calculated the window height with DisplayMetrics to understand, what height should I use for my GridView items.
Now I'm trying to use ViewPager with Fragments. I have my Activity with ViewPager, and 2 Fragments. Each Fragment has the same layout (GridView in LinearLayout). I'm trying to pass screen height into Fragment in this way:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_grid_layout);
pageHeight = getHeight();
Log.d("HEIGHT", "Page height: "+pageHeight);
ViewPager viewPager;
viewPager = findViewById(R.id.main_menu_viewpager);
src = new ArrayList<MainPageTableFragment>();
/*Определяем количество страниц меню*/
int pagesCount = 2;
for (int i = 0; i < pagesCount; i++) {
src.add(MainPageTableFragment.newInstance(i, pageHeight));
}
FragmentPagerAdapter adapter = new ScreenSlidePagerAdapter(getSupportFragmentManager(), src);
viewPager.setAdapter(adapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabDots);
tabLayout.setupWithViewPager(viewPager, true);
}
So, each launch of onCreate method should recreate Fragments.
And in Fragment, I get my height in this way:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.activity_main_grid_fragment, container, false);
gridView = rootView.findViewById(R.id.main_menu_grid);
//PROBLEM IS HERE...
height = this.getArguments().getInt("containerHeight");
pageNum = this.getArguments().getInt("pageNumber");
populateGridItems(); //method to load items in gridview
return rootView;
}
The problem is: when I rotate my device, all methods are called, but
height = this.getArguments().getInt("containerHeight");
uses old value. For instance, in first launch (vertical screen orientation), it is 690. When I rotate my device, in onCreate I calculate new height (382), but my Fragment takes old value (690). I tried to call getArguments() in several places (onAttach, onCreate, onActivityCreated), but didn't help.
Can anybody explain me, where is the problem, and what should I do?
Thank you!
UPD: Code of my MainPageTableFragment
public static MainPageTableFragment newInstance(int pageNumber, int height) {
Bundle args = new Bundle();
args.putInt("pageNumber", pageNumber);
args.putInt("containerHeight", height);
MainPageTableFragment fragment = new MainPageTableFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.activity_main_grid_fragment, container, false);
gridView = rootView.findViewById(R.id.main_menu_grid);
height = getArguments().getInt("containerHeight");
Log.d("HEIGHT", "Fragment height in onCreateView: "+height);
pageNum = getArguments().getInt("pageNumber");
populateGridItems();
return rootView;
}
private void populateGridItems() {
/*adding items in GridView*/
gridView.setAdapter(new MenuGridAdapter(this.getContext(), items, height));
}
}
I'm not sure but i think it's because of supportFragmentManager and pagerAdapter.
First time in instantiateItem it creates a name for fragment and in destroyItem it's just detach fragment.
Then after rotating in instantiateItem it founds fragment by name and uses old instance instead of new. I think for optimization and so on.
As a solution, you can remove all fragments from supportFragmentManager or override instantiateItem/destroyItem to remove frgament as you need.
I found another way to do this. In my Activity, I've created public method to calculate height, and in onCreateView in my Fragment, I call this method. It works. But for me, it's unknown problem: why recreation of the fragment took values of arguments from the old bundle.

FragmentManager with FragmentTabHost

I have an Activity that has a ViewPager with four Fragments. One of those Fragments must have two tabs inside of it so I tried FragmentTabHost.
private FragmentTabHost fragmentTabHost;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_zbritjet, container, false);
fragmentTabHost = (FragmentTabHost) view.findViewById(android.R.id.tabhost);
fragmentTabHost.setup(view.getContext(), getFragmentManager(), android.R.id.tabcontent);
fragmentTabHost.addTab(fragmentTabHost.newTabSpec("tab_ofertat").setIndicator("Ofertat"), OfertatItems.class, null);
fragmentTabHost.addTab(fragmentTabHost.newTabSpec("tab_bizneset").setIndicator("Bizneset"), BiznesetItems.class, null);
return view;
}
The problem is that android is throwing
java.lang.IllegalStateException: FragmentManager is already executing transactions
Stack trace:
android.support.v4.app.FragmentManagerImpl.ensureExecReady(FragmentManager.java:1946)
android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1992)
android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:762)
android.support.v4.app.FragmentTabHost.onAttachedToWindow(FragmentTabHost.java:289)
Try getChildFragmentManager() instead of getFragmentManager().
From the docs:
Return a private FragmentManager for placing and managing Fragments inside of this Fragment.

OncreateView does not call when Activity get destroyed and re-run again

I'm getting a strange problem with Fragment and ViewPager.
I have 1 ViewPager contains 3 Fragments.
When my app run for the first time. onCreateView on all my fragments get called and ViewPager works perfectly.
Code for initalizing ViewPager
private void initPager() {
mFragmentList.add(new MainSongListFragment());
mFragmentList.add(new MainAlbumArtFragment());
mFragmentList.add(new MainLyricsFragment());
if (mFragmentList == null)
mFragmentList = new ArrayList<Fragment>();
MainPagerAdapter pagerAdapter = new MainPagerAdapter(
getSupportFragmentManager(), mFragmentList);
mMainPager.setAdapter(pagerAdapter);
myListViewInsideFragment= (ListView) findViewById(R.id.my_list);
}
When I press back button and run app again. I get error at the code:
myListViewInsideFragment= (ListView) findViewById(R.id.my_list);
It returns null because the onCreateView method on Fragment does not get called so all views on this fragment is not avaiable.
Code in My Fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.lo_my_list, container,
false);
mListView = (ListView) view
.findViewById(R.id.my_list);
return view;
}
My question is:
Why does not onCreateView method get called when Activity get destroyed and re-run again?.
Thank you.

View Pager in Fragment

Once again, I am so annoyed by the AndroidSDK . Why does this have to be so complicated?
I have a ViewPager that I want to populate with my Fragment. I implemented this on an Activity and it works. But when its in another Fragment the whole thing crashes and the erros messages tells me nothing:
07-01 12:58:20.210: E/AndroidRuntime(10146): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Here is my code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_tabwrapper, container);
List<Fragment> fragments = getFragments();
pageAdapter = new MyPageAdapter(getActivity()
.getSupportFragmentManager(), fragments);
pager = (ViewPager) v.findViewById(R.id.viewpager);
pager.setAdapter(pageAdapter); // <- CRASH!
return v;
}
BTW: The whole thing is based on this tutorial: http://architects.dzone.com/articles/android-tutorial-using
This error occurs beacuse you have to remove all views before set adapter in view pager so get right way..... So check this:
MyPageAdapter pageAdapter ;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_tabwrapper, container);
List<Fragment> fragments = getFragments();
pageAdapter = new MyPageAdapter(getActivity()
.getSupportFragmentManager(), fragments);
pager = (ViewPager) v.findViewById(R.id.viewpager);
pager.removeallviews();
pager.setAdapter(pageAdapter); // <- CRASH!
return v;
}
you should not use the ViewGroup that onCreateView provides as container to put your inflated view:
Change
View v = inflater.inflate(R.layout.fragment_tabwrapper, container);
to
View v = inflater.inflate(R.layout.fragment_tabwrapper, null);
This might shed a little light on the topic: http://developer.android.com/about/versions/android-4.2.html#NestedFragments
IMHO: I don't understand why developers put up with these tools. I find them impossible to work with. No wonder there are so many low-quality apps on the Play store. I'm looking forward to the day this project is done. Won't be working with this OS anytime soon again ...

How to set data to layout inflated by a fragment

I have a FragmentActivity which sets a main layout with 3 tabs. Each tab has it's own fragment which inflates is own layout into main layout.
For example, one of the three Fragments:
public class Fragment1 extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
return inflater.inflate(R.layout.fragment1, container, false);
}
}
When I add all the fragments and connect them with tabs everything works. When I click on tab1, layout of the Fragment1 shows, when I click on Tab2, layout of the Fragment2 shows.
The problem is that when I want to change something in that inflated layout (for example execute setText to textView in fragment1 layout), I receive a NullPointerException in that line and application stops.
This doesn't work:
TextView test = (TextView) findViewById(R.id.fragmentOneText1);
test.setText("Test text!");
How to set data to inflated layout?
You have to inflate your fragment specific layout first by using LayoutInflater and map the control in your Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.R.layout.fragment1, container, false);
TextView text = (TextView) fragmentView.findViewById(R.id.fragmentOneText1);
mTextNoResult=(TextView)fragmentView.findViewById(R.id.text_noresult);
return fragmentView;
}

Categories

Resources