这两个片段在ViewPager中都是可见的

时间:2013-01-11 06:32:10

标签: android android-fragments android-viewpager

我在这里已经阅读了很多有用的信息并且取得了很好的进展,但现在我被卡住了。我当前状态的Android项目包含一个ViewPager,其中包含两个使用Action Bar Sherlock构建的导航选项卡。一个选项卡是ListFragment,另一个选项卡目前只是用于测试目的的片段。我想将ListFragment替换为与ListFragment在同一容器中的细节Fragment,而不是打开一个新活动。我能够使用此论坛中建议的布局(没有FrameLayout包装器,我无法获取要加载的详细信息):

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fadingEdge="none" >
    <FrameLayout
        android:id="@+id/main_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </FrameLayout>

</RelativeLayout>

单击列表项时,我会使用主Activity的回调。

来自ListFragment:

@Override
public void onListItemClick(ListView l, View v, int position, long id)  {
    mCallback.onItemSelected(position);     
}

主要活动:

public void onItemSelected(int position)  {     

    TestDetailsFragment newFragment = new TestDetailsFragment();
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

    ft.replace(R.id.main_container, newFragment);
    ft.addToBackStack(null);
    ft.commit();        
}

最后,我的TestDetailsFragment:

public class TestDetailsFragment extends SherlockFragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState)  {

    View view = inflater.inflate(R.layout.test_layout, container, false);
    return view;
}

}

我的问题是,在加载详细信息片段时,ListFragment仍然可见。如果我按&#34;返回&#34;,详细信息文本就会消失。如果我不按回,但是滑到我的其他片段,细节文本仍然存在。我想如果我可以将 ft.replace(R.id.main_container,newFragment); 更改为 ft.replace(ViewPager页面的R.id。 containerId ,newFragment)它会工作,但我无法弄清楚如何做到这一点尽管搜索很多。我尝试用以下方式替换列表布局,这也没有用(错误:找不到* my_list_layout *的视图): ft.replace(R.id.my_list_layout,newFragment); 这是ListFragment布局的XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_list_layout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<ListView android:id="@android:id/list" 
    android:layout_height="wrap_content" 
    android:layout_width="fill_parent" />

非常感谢任何建议。

我真的很陌生(这是我在这里发表的第一篇文章),所以我会继续把我的整个主要活动放在这里以防万一我错过了一些非常明显的东西。谢谢!

    import java.util.ArrayList;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.SherlockFragmentActivity;

public class MainActivity extends SherlockFragmentActivity 
        implements MyListFragment.OnItemSelectedListener  {

ViewPager mViewPager;
TabsAdapter mTabsAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setTitle(R.string.app_name);

    setContentView(R.layout.main);
    ViewPager mViewPager = (ViewPager)findViewById(R.id.pager);

    final ActionBar actionBar = getSupportActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBar.setDisplayShowTitleEnabled(true);
    actionBar.setHomeButtonEnabled(true);
    actionBar.setIcon(R.drawable.ic_title);

    mTabsAdapter = new TabsAdapter(this, mViewPager);
    mTabsAdapter.addTab(actionBar.newTab().setText("tab1"), MyFragment.class, null);
    mTabsAdapter.addTab(actionBar.newTab().setText("tab2"), MyListFragment.class, null);
    if (savedInstanceState != null)  {
        actionBar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
    }        
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
}

public void onItemSelected(int position)  {     

    TestDetailsFragment newFragment = new TestDetailsFragment();
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.main_container, newFragment);
    ft.addToBackStack(null);
    ft.commit();        
}

public static class TabsAdapter extends FragmentStatePagerAdapter
    implements ActionBar.TabListener, ViewPager.OnPageChangeListener  {

    private final Context mContext;
    private final ActionBar mActionBar;
    private final ViewPager mViewPager;
    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();


    static final class TabInfo  {
        private final Class<?> clss;
        private final Bundle args;

        TabInfo(Class<?> _class, Bundle _args)  {
            clss = _class;
            args = _args;
        }
    }

    public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
        super(activity.getSupportFragmentManager());
        mContext = activity;
        mActionBar = activity.getSupportActionBar();
        mViewPager = pager;
        mViewPager.setAdapter(this);
        mViewPager.setOnPageChangeListener(this);
    }

    public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
        TabInfo info = new TabInfo(clss, args);
        tab.setTag(info);
        tab.setTabListener(this);
        mTabs.add(info);
        mActionBar.addTab(tab);
        notifyDataSetChanged();
    }

    @Override
    public int getCount()  {
        return mTabs.size();
    }

    @Override
    public Fragment getItem(int position)  {
        TabInfo info = mTabs.get(position);
        return Fragment.instantiate(mContext, info.clss.getName(), info.args);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, 
            int positionOffsetPixels)  {
    }

    @Override
    public void onPageSelected (int position)  {
        mActionBar.setSelectedNavigationItem(position);
    }

    @Override
    public void onPageScrollStateChanged(int state)  {          
    }

    @Override
    public int getItemPosition(Object object)  {
        return PagerAdapter.POSITION_NONE;
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft)  {
        Object tag = tab.getTag();
        for (int i=0; i<mTabs.size(); i++)  {
            if (mTabs.get(i) == tag)  {
                mViewPager.setCurrentItem(i);
            }
        }

    }

    @Override 
    public void onTabUnselected (Tab tab, FragmentTransaction ft)  {

    }

    @Override
    public void onTabReselected (Tab tab, FragmentTransaction ft)  {

    }
}
}

1 个答案:

答案 0 :(得分:1)

  

我的问题是ListFragment在详细信息时仍然可见   片段已加载

这是正常的,因为您更换它们之间的片段的代码会将新的详细信息片段放在FrameLayout中,其中还包含您的ViewPager(带有相应的ListFragment),这不会被删除。

  

我想如果我可以改变ft.replace(R.id.main_container,   newFragment);到ft.replace(ViewPager页面的R.id.containerId,   newFragment)它会起作用,但我无法弄清楚如何做到这一点   尽管搜索很多。

是的,这是一个选择。我建议您使用新的嵌套Fragments API(兼容包或普通Fragments,API 16+)。如果您只想将ListFragment替换为新的详细信息Fragment(这样您可以保留Fragment的额外ViewPager +刷卡功能,那么请执行此操作:

  • 您当前使用ListFragment的地方,您将放置一个简单的包装Fragment(其布局为简单的FrameLayout),Fragment的{​​{1}} {1}}将保持不变
  • 一开始使用包装器ViewPager中的getChildFragmentManager()添加正常Fragment
  • 使包装器片段实现您的回调接口。要获得对父ListFragment的引用,您可以使用Fragment中的getParentFragment()方法并将其转换为您的听众
  • 在包装器ListFragment将实施的回调中,使用FragmentListFragment替换为详细信息Fragment

如果您希望详细信息FrameLayout替换Fragment(将它的两个片段放在一起),请修改ViewPager的布局,使其只有一个Activity您将添加包含FrameLayout或详细信息Fragment的{​​{1}}。