问题
I am trying to get a fragment with three tabs displayed using ViewPager. Initially I used to instantiate the fragment from the Activity using FragmentMgr, this worked fine. When I converted this navigation using ViewPager, this Fragment is no longer displayed.
MainActivity.java
When I initiate Fragment like this, it gets displayed. eg:
LaunchListFragment fragment = new LaunchListFragment();
fragment.newInstance(LIST_TYPE);
getSupportFragmentManager().beginTransaction()
.add(R.id.item_detail_container,
fragment).commit();
I tried this change above code to make use of ViewPager as follows:
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(new LaunchPageAdapter(getSupportFragmentManager(),LIST_TYPE));
mViewPager.setCurrentItem(0);
where LaunchPageAdapter calls LaunchListFragment.
LaunchPageAdapter.java
public class LaunchPageAdapter extends FragmentPagerAdapter {
private static String select="";
public LaunchPageAdapter(FragmentManager fm, String type) {
super(fm);
select=type;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return LaunchListFragment.newInstance(select);
case 1:
return AddTeamFragment.newInstance();
}
return null;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return 2;
}
Here is LaunchListFragment.java
public class LaunchListFragment extends ListFragment implements ActionBar.TabListener {
public static String LIST_TYPE = "invalid";
GenericListData g_data[] = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View result = inflater.inflate(R.layout.fragment_launch_list,
container, false);
setActionTabs();
setList();
return (result);
}
public static Fragment newInstance(String type) {
Fragment frag = new LaunchListFragment();
Bundle args = new Bundle();
LIST_TYPE=type;
args.putString(LIST_TYPE, type);
frag.setArguments(args);
return (frag);
}
This is main.xml layout used by MainActivity
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools= "match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:baselineAligned="false"
android:divider="?android:attr/dividerHorizontal"
android:orientation="horizontal"
android:showDividers="middle"
tools:context=".MainActivity" >
<fragment
android:id="@+id/item_list"
android:name="com.teammanager.ItemListFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout="@android:layout/list_content" />
<FrameLayout
android:id="@+id/item_detail_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</FrameLayout>
fragment_launch_list.xml used by LaunchListFragment
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false" >
</ListView>
<TextView
android:id="@+id/itemName"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:gravity="center_vertical"
android:textColor="#000000"
android:textSize="22dp"
android:textStyle="bold" />
When I debug this, I can see LaunchListFragment is getting instantiated, onCreate and onCreate View is called, it just won't get displayed. :(
Can anyone here let me know if I am missing anything here in my ViewPager implementation?
Update
When I called LaunchListFragment without using Viewpager, I set the content view first and passed R.id.item_detail_container which is the id of the FrameLayout where I want the fragment to be displayed. Please refer to main.xml earlier
setContentView(R.layout.main.xml);
LaunchListFragment fragment = new LaunchListFragment();
fragment.newInstance(LIST_TYPE);
getSupportFragmentManager().beginTransaction()
.add(R.id.item_detail_container,
fragment).commit();
When I changed this to use ViewPager, I am not sure where I'm directing the Fragment to be displayed. In my fragment onView I'm inflating fragment_launch_list and returning the View. But how will the view pager know where to set the fragment view. Is it inside the id pager?
I'm an absolute beginner, I apologize if all these are naive questions.
Cheers.
回答1:
The question description is perfectly suitable to the problem I just had. I know the question is old but may this help other who face same. @Geoplex have not shown code of LaunchPageAdapter
class. So I'm not sure if this solves his problem or not. But for me that worked.
In my PagerAdapter, the
public boolean isViewFromObject(View view, Object object)
was overridden. I removed that method and allowed superClass to handle it. That started giving my expected result.
回答2:
This is useful for you,
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments=null;
private FragmentManager fragmentManager=null;
public ViewPagerAdapter(FragmentManager fragmentManager,List<Fragment> fragments) {
super(fragmentManager);
this.fragments=fragments;
this.fragmentManager=fragmentManager;
}
@Override
public Fragment getItem(int position) {
fragmentManager.beginTransaction().commitAllowingStateLoss();
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object)
{
super.setPrimaryItem(container,0,fragments.get(0));
}
@Override
public void notifyDataSetChanged()
{
super.notifyDataSetChanged();
}
@Override
public void destroyItem(ViewGroup collection, int position, Object view) {
fragmentManager.executePendingTransactions();
fragmentManager.saveFragmentInstanceState(fragments.get(position));
}
public void replaceItem(int position,Fragment fragment)
{
fragments.set(position, fragment);
this.notifyDataSetChanged();
}
}
MainActivity.java
public class MainActivity extends FragmentActivity implements OnPageChangeListener,TabListener
{
private android.support.v4.view.ViewPager mViewPager=null;
private ViewPagerAdapter mPagerAdapter=null;
private ActionBar action=null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
initilizeViewPager();
action=getActionBar();
action.setDisplayShowHomeEnabled(false);
action.setDisplayShowTitleEnabled(false);
action.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
}
public void initilizeViewPager()
{
mViewPager=(android.support.v4.view.ViewPager)findViewById(R.id.viewPager);
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(LaunchListFragment.newInstance(select));
fragments.add(AddTeamFragment.newInstance());
fragments.add(thirdFragment.newInstance());
viewPagerAdapter=new ViewPagerAdapter();
mViewPager.setAdapter(viewPagerAdapter(getSupportFragmentManager(),fragments));
new setAdapterTask().execute();
mViewPager.setOnPageChangeListener(this);
}
private class setAdapterTask extends AsyncTask<Void,Void,Void>
{
protected Void doInBackground(Void... params)
{
return null;
}
@Override
protected void onPostExecute(Void result)
{
mViewPager.setAdapter(mPagerAdapter);
Tab first=action.newTab().setTag("first").setText("First").setTabListener(MainActivity.this);
Tab second=action.newTab().setTag("second").setText("Second").setTabListener(MainActivity.this);
Tab third=action.newTab().setTag("third").setText("Third").setTabListener(MainActivity.this);
action.addTab(first);
action.addTab(second);
action.addTab(third);
}
}
}
public void onPageScrollStateChanged(int arg0)
{}
public void onPageScrolled(int arg0, float arg1, int arg2)
{}
public void onPageSelected(int position)
{
getActionBar().setSelectedNavigationItem(position);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
}
main_layout.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="fill_parent"
android:layout_below="@android:id/tabs"
android:layout_height="fill_parent"/>
</RelativeLayout>
来源:https://stackoverflow.com/questions/16078278/trouble-with-viewpager-displaying-fragments