Confusion about fragments and their activities - android

I have a TabLayout and ViewPager to hold and navigate between my fragments (3 of them) and that is working fine however I'm getting confused as to how I interact with each fragment for example button clicks or edit texts. Here is my main activity xml.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.design.widget.TabLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/tabLayout"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#color/colorPrimary"
app:tabMode="fixed"
app:tabGravity="fill" />
<android.support.v4.view.ViewPager
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/viewPager"
android:layout_centerHorizontal="true"
android:layout_below="#+id/tabLayout" />
</RelativeLayout>
This is the activity for it.
public class ActivityMain extends AppCompatActivity {
private String tabTitles[] = new String[] { "contacts", "home", "search" };
TabLayout tabLayout;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(new CustomAdapater(getSupportFragmentManager(),getApplicationContext()));
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
});
}
private class CustomAdapater extends FragmentPagerAdapter {
private String fragments [] = {"contacts", "home", "search"};
public CustomAdapater(FragmentManager supportFragmentManager, Context applicationContext) {
super(supportFragmentManager);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new FragmentContacts();
case 1:
return new FragmentMain();
case 2:
return new FragmentSearch();
default:
return null;
}
}
#Override
public int getCount() {
return fragments.length;
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
}
}
And here is a fragment activity.
public class FragmentSearch extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return inflater.inflate(R.layout.fragment_search,container,false);
}
}
Now say in my R.layout.fragment_search I had a button just for examples sake, how do I set an onclicklistener for it? Is it within the FragmentSearch or ActivityMain? I've searched around but I'm just getting more confused.

You'd set your onClickListener in the fragment's onCreateView method by doing something like:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment1, container, false);
myButton = (Button) rootView.findViewById(R.id.buttonId);
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
}
});
return rootView;
}
Everything is the same regarding the onClickListener, as you can see. The only difference is that you have to inflate to view and use that view to find the appropriate components (e.g. buttons, textviews..)

Now, if you want to communicate between Fragments, you will need to implement more things. The basic way is to use interfaces to be implemented by your activity, so each fragment can call those methods within the activities.
There are also messaging libraries such as Otto and EventBus, they are great by sending stuff between not just fragments, but services also.

Related

Android TabLayout ViewPager not inflating tab fragment on backstack

I've got a tab view set up that that has custom fragments for each tab using a viewpager. This is my code:
Holding Fragment
public class FragInboxMainView extends Fragment implements CGFragment {
private CGController controller;
private CGFragment thisFragment;
#Bind(R.id.inboxViewPager)ViewPager inboxViewPager;
#Bind(R.id.inboxTabs)TabLayout inboxTabLayout;
#Bind(R.id.inbox_progress_wheel)ProgressWheel inboxProgressWheel;
public FragInboxMainView(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_inbox_mainview, container, false);
ButterKnife.bind(this, rootView);
thisFragment = this;
Globals g = Globals.getInstance();
/** Show loading spinner */
this.inboxProgressWheel.setBarColor(ContextCompat.getColor(controller.getContext(), g.getUserObject().getUserThemeColor()));
this.inboxProgressWheel.setVisibility(View.VISIBLE);
/** Display the profile information based off the ID */
controller.displayInbox(thisFragment);
return rootView;
}
public void hideProgressSpinner() {
this.inboxProgressWheel.setVisibility(View.GONE);
}
public ViewPager getInboxViewPager() {
return this.inboxViewPager;
}
public TabLayout getInboxTabLayout() {
return this.inboxTabLayout;
}
}
Its layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:wheel="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/inboxTabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable" />
<com.pnikosis.materialishprogress.ProgressWheel
android:id="#+id/inbox_progress_wheel"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center"
wheel:matProg_barColor="#5588FF"
wheel:matProg_progressIndeterminate="true"
android:visibility="gone"/>
<android.support.v4.view.ViewPager
android:id="#+id/inboxViewPager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#android:color/white" />
</LinearLayout>
Tab fragment and its inflation file
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:id="#+id/main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.baoyz.widget.PullRefreshLayout
android:id="#+id/tabPullRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<view
android:id="#+id/tabRecyclerHolder"
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:clipToPadding="false"
android:layout_centerInParent="true"/>
</com.baoyz.widget.PullRefreshLayout>
<com.melnykov.fab.FloatingActionButton
android:id="#+id/tabFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:src="#mipmap/ic_add_white"/>
</android.support.design.widget.CoordinatorLayout>
public class TabRecyclerHolder extends Fragment {
#Bind(R.id.tabRecyclerHolder) RecyclerView tabRecyclerHolder;
#Bind(R.id.tabPullRefresh) PullRefreshLayout tabPullRefresh;
#Bind(R.id.tabFab) FloatingActionButton recyclerFab;
private String tabTitle = "Title";
public TabRecyclerHolder(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab_recycler_holder, container, false);
ButterKnife.bind(this, rootView);
recyclerFab.hide(false);
tabPullRefresh.setRefreshStyle(PullRefreshLayout.STYLE_MATERIAL);
return rootView;
}
public RecyclerView getTabRecyclerHolder() {
return this.tabRecyclerHolder;
}
public FloatingActionButton getRecyclerFab() {
return this.recyclerFab;
}
public String getTabTitle() {
return this.tabTitle;
}
public void setTabTitle(String title) {
this.tabTitle = title;
}
public PullRefreshLayout getTabPullRefresh() {
return this.tabPullRefresh;
}
}
My tab adapter
public class TabPagerAdapter extends FragmentStatePagerAdapter {
private CGController controller;
private List<Object> items;
public TabPagerAdapter(FragmentManager fm, CGController controller, List<Object> items) {
super(fm);
this.controller = controller;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Fragment getItem(int num) {
return (TabRecyclerHolder)items.get(num);
}
#Override
public String getPageTitle(int num){
return ((TabRecyclerHolder)items.get(num)).getTabTitle();
}
}
The processing code
public void viewInbox() {
/** Set up the views */
receivedHolder = new TabRecyclerHolder();
receivedHolder.setTabTitle(Constants.TAB_INBOX_RECEIVED);
sentHolder = new TabRecyclerHolder();
sentHolder.setTabTitle(Constants.TAB_INBOX_SENT);
tabs.add(receivedHolder);
tabs.add(sentHolder);
/** Set up the tabs */
final ViewPager inboxViewPager = inboxFragment.getInboxViewPager();
TabLayout inboxTabLayout = inboxFragment.getInboxTabLayout();
/** Set the adapter for the view pager */
inboxViewPager.setAdapter(new TabPagerAdapter(inboxFragment.getChildFragmentManager(), controller, tabs));
/** set up the tab look and feel */
inboxTabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
inboxTabLayout.setTabMode(TabLayout.MODE_FIXED);
inboxViewPager.setOffscreenPageLimit(3);
inboxViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(inboxTabLayout));
inboxTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
inboxViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
/** And, display! */
inboxTabLayout.setupWithViewPager(inboxViewPager);
receivedAdapter = new RecyclerListAdapter(controller, items);
final RecyclerView receivedList = receivedHolder.getTabRecyclerHolder();
receivedList.setLayoutManager(new LinearLayoutManager(controller.getContext()));
receivedList.setAdapter(receivedAdapter);
}
There is some code i've missed out but its not pertanent to the question.
The code works perfectly when initially viewing the fragment. However since my application contains a single activity and just replaces a content view for each fragment navigated to, each fragment is added to the back stack and then popped when the back button is pressed. My issue is that when navigating back to this fragment the view inside the tab isn't being inflated, which means that no elements can be accessed (and therefore the app crashes while trying to display the data in the recyclerview etc).
I have had a look at this question: TabLayout ViewPager Not Loading When Using Backstack and implemented its suggestion (using getChildFragmentManager() when setting up the pager adapter) however that has not fixed my issue.
Help would be appreciated!
Change this public View onCreateView(LayoutInflater inflater,... to public void onViewCreated (View view, Bundle savedInstanceState)
so you are going to have something like this
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.tab_recycler_holder, container, false);
}
then
#Override
public void onViewCreated (View view, Bundle savedInstanceState){
ButterKnife.bind(this, view);
recyclerFab.hide(false);
tabPullRefresh.setRefreshStyle(PullRefreshLayout.STYLE_MATERIAL);
...
see if it helps
Extend FragmentStatePagerAdapter in TabPagerAdapter as
FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)

ViewPage Fragment disappear when reload again

The following is layout
test.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Click"
android:id="#+id/button"
/>
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
test_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Hello"
android:id="#+id/textView" android:layout_gravity="center_horizontal"/>
</LinearLayout>
common_view_pager_layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/MainViewerPage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<android.support.v4.view.PagerTabStrip
android:id="#+id/TitlePageTabStrip"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v4.view.ViewPager>
</LinearLayout>
The following is my Activity code
public class TestFragmentActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.test);
Button button = (Button) this.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, new HomeFragment()).commit();
}
});
}
public class HomeFragment extends Fragment {
private PagerAdapter _adapter;
public HomeFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.common_view_pager_layout, container, false);
this._adapter = new PagerAdapter(TestFragmentActivity.this);
this._adapter.add(new DetailFragment());
ViewPager pager = (ViewPager) view.findViewById(R.id.MainViewerPage);
pager.setAdapter(this._adapter);
return view;
}
}
public class DetailFragment extends Fragment {
public DetailFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.test_detail, container, false);
return rootView;
}
}
public class PagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> _fragments;
public PagerAdapter(FragmentActivity activity) {
super(activity.getSupportFragmentManager());
this._fragments = new ArrayList<Fragment>();
}
public void add(Fragment fragment) {
this._fragments.add(fragment);
}
#Override
public Fragment getItem(int position) {
return this._fragments.get(position);
}
#Override
public CharSequence getPageTitle(int position) {
return "Test";
}
#Override
public int getCount() {
return 1;
}
}
}
When I click a button the fragment in ViewPager was display
But when I click the button again the fragment disappear
Please help me.
try using this:
in the constructor of your adapter change this :
public class MyPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> _fragments;
public MyPagerAdapter(FragmentManager activity) {
super(activity);
this._fragments = new ArrayList<Fragment>();
}
public void add(Fragment fragment) {
this._fragments.add(fragment);
}
#Override
public Fragment getItem(int position) {
return this._fragments.get(position);
}
#Override
public CharSequence getPageTitle(int position) {
return "Test";
}
#Override
public int getCount() {
return 1;
}
}
and when you want to create the adapter send getChildFragmentManager() to its constructor
public class HomeFragment extends Fragment {
private MyPagerAdapter _adapter;
public HomeFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.common_view_pager_layout, container, false);
ViewPager pager = (ViewPager) view.findViewById(R.id.MainViewerPage);
this._adapter = new MyPagerAdapter(getChildFragmentManager());
this._adapter.add(new DetailFragment());
pager.setAdapter(this._adapter);
return view;
}
}
I test it and it works, any problem comment it.
Good Luck!
In your Fragment class, in the onCreate() method, you have to call setRetainInstance(true) like this:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
This tells the FragmentManager to keep your fragments on reloads.
In addition, check your manifest file doesn't have any
android:screenOrientation
config changes where you are basically saying you will handle reloads due to config changes yourself.
In PagerFragment 's onResume() add this:
#Override
public void onResume() {
super.onResume();
for (Fragment fragment : getFragmentManager().getFragments()) {
if (fragment instanceof Tab1Fragment || fragment instanceof Tab2Fragment) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(fragment);
ft.attach(fragment);
ft.commit();
}
}
}
Try to add this lines in your code:
public int getItemPosition(Object object) {
return POSITION_NONE;
}
and Add the below lines
pager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
... anything you may need to do to handle pager state ...
adapter.notifyDataSetChanged(); //this line will force all pages to be loaded fresh when changing between fragments
}
Under
pager.setAdapter(adapter);
Hope this may help you!
Ensure you pass the adapter instance the child fragment manager, not the fragment manager.
Like this:
this._adapter = new PagerAdapter(getChildFragmentManager());

move from a fragment to another in an activity

From what I understand from this thread, fragments can be easily replaced with another.
However in my case, I have 2 fragments combined in scrollable Activity, so when I say "move", I mean going from the fragment left to the right or right to the left without replacing any fragment with another. Is this somehow possible?
you could use ViewPager for that. And on your adapter class you will have to switch between the fragments via getItem(). Eclipse/new AndroidProject/ swipe with/out tabs. And check the example code generated by Android.
edit:
create xml file call it main_activity.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Main" >
<android.support.v4.view.PagerTitleStrip
android:id="#+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#FAFAFA"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:textColor="#36466E" />
create a class call it Main
public class Main extends FragmentActivity {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
Context ctx;
static MySQLiteHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
mSectionsPagerAdapter.notifyDataSetChanged();
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch(position){
case 0:
fragment = new GridApp();
break;
case 1:
fragment = new ListApp();
break;
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Select App";
case 1:
return "Selected Apps";
}
return null;
}
}
}
now create a class called GridApp and ListApp
GridApp class.
public class GridApp extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.gridpp,
container, false);
}
}
ListApp class
public class GridApp extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.listapp,
container, false);
}
}
and you are done.

Source Not Found when using ListFragment & ViewPager

I've been trying to create a simple Horizontal scrolling option.
I have 2 ListFragments, which I would like to scroll between.
I'm getting a "Source Not Found" error when returning the View from onCreateView function.
This is my MainActivity Class:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
ViewPager mViewPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
final ActionBar actionBar = getActionBar();
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setText(mAppSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
}
public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
Fragment a;
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
return new FragmentA();
default:
return new FragmentB();
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return "Section " + (position + 1);
}
}
}
This is one of my ListFragment class (the second is the same but different name & layout file):
public class FragmentA extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.favorites_layout, container, false);
updateStationsView(0);
return rootView;
}
}
updateStationView is a function that populates the List. removing it did not help, so I figured it's harmless.
The error is thrown right after the:
return rootView;
which returns to the onCreate functions of MainActivity.
When I'm changing the ListFragment to be a simple Fragment it works. I think I'm lacking some knowledge to figure this one out. I really want to use ListFragment...
Can someone please try an help ?
Many thanks for your efforts.
Adding the XML files:
activity_main.xml:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
favorites_layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
I im quite sure the issue is that your custom layout for the ListFragment does not contain a ListView. These lines of code are causing the error because you need to have a ListView inside your "favourites_layout" .xml file.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.favorites_layout, container, false);
updateStationsView(0);
return rootView;
}
ListFragment has a default layout that consists of a single list view.
However, if you desire, you can customize the fragment layout by
returning your own view hierarchy from onCreateView(LayoutInflater,
ViewGroup, Bundle). To do this, your view hierarchy must contain a
ListView object with the id "#android:id/list" (or list if it's in
code)
So your layout could for example look like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
See here for more:
http://developer.android.com/reference/android/app/ListFragment.html

ViewPager with FragmentPagerAdapter does not show content

I'm trying to use the Fragment, ViewPager & co. from the Android support library v4. Fragments seem to scroll when I listen to page change events from the pager but the content is not visible. What I basically have is:
A FragmentActivity:
public class MyActivity extends FragmentActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentPagerAdapter fpa = new MyPagerAdapter(this, createFragments());
ViewPager vp = (ViewPager) findViewById(R.id.pager);
vp.setAdapter(fpa);
}
private List<Fragment> createFragments() {
List<Fragment> list = new ArrayList<Fragment>();
list.add(Fragment.instantiate(this, First.class.getName()));
list.add(Fragment.instantiate(this, Second.class.getName()));
list.add(Fragment.instantiate(this, Third.class.getName()));
return list;
}
#Override
protected void onSaveInstanceState(Bundle outState) {
}
A FragmentPagerAdapter:
public class MyPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public MyPagerAdapter(FragmentActivity activity, List<Fragment> fragments) {
super(activity.getSupportFragmentManager());
this.fragments = fragments;
}
#Override
public Fragment getItem(int i) {
return fragments.get(i);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public boolean isViewFromObject(View view, Object o) {
return view.equals(o);
}
}
And three Fragments that look like this:
public class First extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.first, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
And they have layout like these:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:text="First Fragment"
android:id="#+id/firstText"/>
</LinearLayout>
I originally forgot to add the main layout, here it comes:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_width="fill_parent"/>
</LinearLayout>
I would appreciate if someone can tell me what I am doing wrong.
This is because you have overridden isViewFromObject in MyPagerAdapter.
FragmentPagerAdapter handles isViewFromObject, so you shouldnt override it.
As with me, I reckon most visitors to this post started with a basic PagerAdapter, then realised they needed to page fragments and changed their base class without realising the consequences. Unfortunate, but I couldn't criticise the Android team for this.
Ya correct as Ian Newson told, just remove isViewFromObject overrided method from your code
#Override
public boolean isViewFromObject(View view, Object object) {
return false;
}

Categories

Resources