ViewPager显示Fragments有问题

4
我正在尝试使用ViewPager显示带有三个选项卡的片段。最初,我使用FragmentMgr从Activity中实例化片段,这很好用。但当我使用ViewPager进行导航时,此片段不再显示。
MainActivity.java
如果我像这样初始化片段,则会显示它。例如:
LaunchListFragment fragment = new LaunchListFragment();
fragment.newInstance(LIST_TYPE);
getSupportFragmentManager().beginTransaction()
                .add(R.id.item_detail_container,   
 fragment).commit();

我尝试修改上面的代码,使用ViewPager,代码如下:
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(new LaunchPageAdapter(getSupportFragmentManager(),LIST_TYPE));
mViewPager.setCurrentItem(0);
          

在哪里LaunchPageAdapter调用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;
    }

这里是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);
}

这是MainActivity使用的main.xml布局

<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 是 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" />

当我调试这个程序时,我发现LaunchListFragment已经被实例化了,onCreate和onCreateView方法也被调用了,但它就是不显示出来。:(
请问有没有人能告诉我在ViewPager的实现中我是否漏掉了什么?
更新:
当我不使用ViewPager调用LaunchListFragment时,我首先设置内容视图,然后传递R.id.item_detail_container,这是我想要显示该片段的FrameLayout的ID。请参阅前面的main.xml。
 setContentView(R.layout.main.xml);
 LaunchListFragment fragment = new LaunchListFragment();
 fragment.newInstance(LIST_TYPE);
  getSupportFragmentManager().beginTransaction()
                .add(R.id.item_detail_container,    
  fragment).commit();

当我将它改为使用ViewPager时,我不确定我要在哪里指定要显示的Fragment。在我的Fragment的onView方法中,我正在填充fragment_launch_list并返回View。但是viewpager将如何知道在哪里设置片段视图?它是在id pager内部吗?
我是一个绝对的初学者,如果这些问题都很幼稚,请原谅。
干杯。

1
只是好奇,为什么select变量是static的? - Glenn
我曾经使用过从其他片段选择值的方式来设置数值,这是在对象之间传递数据的一种懒惰方式。 - Geoplex
当您想要从一个片段传递值到另一个片段时,请使用接口。不要使用静态变量,这不是正确的方法..! - Sino Raj
2个回答

2
问题描述与我刚遇到的问题完美契合。我知道这个问题很旧了,但它可能会帮助其他面临同样问题的人。@Geoplex没有展示LaunchPageAdapter类的代码。所以我不确定这是否解决了他的问题。但对我来说,这起作用了。
在我的PagerAdapter中,覆盖了public boolean isViewFromObject(View view, Object object)方法。我删除了该方法并允许超类处理它。这开始给出我期望的结果。

1

这对你很有用,

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>

谢谢你的回答。我复制了你的代码并按照说明进行操作,但LaunchListFragment没有显示出来。我进行了调试,它在ActionBar上添加了选项卡 - 这部分是有效的,然后使用正确的值填充列表等,在Fragment的onView方法中被调用,只是没有显示列表。你认为这是否与ViewPager的可见性设置有关? - Geoplex
所有片段事务的设置应该在它们的父级(如活动或它们的父片段)中填充。我认为您的事务在它们的活动上,因此您可以处理所有视图分页器事务并在活动内添加选项卡。 - Sino Raj
嗨,刚才我将ActionTab的设置值从LaunchListFragment移除到MainActivity(父活动)。这没有产生任何变化,因为使用ViewPager仍然无法显示LaunchListFragment。我怀疑是布局问题,请检查我在最初的问题中的更新。 - Geoplex
你认为主布局有什么问题?我应该在哪里添加Activity?是缺少</LinearLayout>吗?它已经存在,只是这个注释没有显示出来。 - Geoplex
1
我已经编辑了我的答案,请尝试一下。它们都是超出MainActivity的所有交易。 - Sino Raj
嗨,我已经将我的代码更改为您的更新代码,但是当我使用ViewPager时,LaunchListFragment中的Listview仍未显示:(当我将main.xml布局更改为Relative而不是LinearLayout时,其中的itemListFragment也未显示。我正在使用由eclipse生成的布局,当您为项目选择Master/Detail Activity时。因此,我在左侧(项目列表)上有一个ListFragment,然后是一个FrameLayout,那里我尝试显示具有三个选项卡的片段。不确定是否要放弃所有这些并从简单的activity/viewPager开始。 - Geoplex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接