1

我在这里阅读了很多很好的信息并取得了很好的进展,但现在卡住了。我当前状态的 Android 项目由一个 ViewPager 和两个使用 Action Bar Sherlock 构建的导航选项卡组成。一个选项卡是 ListFragment,另一个目前只是一个用于测试目的的 Fragment。我想用与 ListFragment 相同的容器中的详细信息片段替换 ListFragment,而不是打开一个新活动。我可以使用此论坛中建议的布局来做到这一点(没有 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 仍然可见。如果我按“返回”,详细信息文本就会消失。如果我不按回,而是滑动到我的另一个片段,详细信息文本仍然存在。我想如果我可以改变ft.replace(R.id.main_container, newFragment); ft.replace(R.id. containerId of ViewPager page , 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)  {

    }
}
}
4

1 回答 1

1

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

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

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

是的,这将是一个选择。我建议您使用新的嵌套FragmentsAPI(可用于兼容包或普通FragmentsAPI 16+)。如果您只想ListFragment用新的详细信息替换Fragment(这样您就可以保留额外FragmentViewPager+ 滑动到它的能力),然后执行以下操作:

  • 在您当前使用的地方,ListFragment您将放置一个简单的包装器Fragment(其布局为 simple FrameLayout),另一个FragmentViewPager保持不变
  • 在开始时使用getChildFragmentManager()包装器Fragment中的添加正常ListFragment
  • 使包装片段实现您的回调接口。要获取对父级的引用,Fragment您可以使用中的getParentFragment()方法ListFragment并将其转换为您的侦听器
  • 在包装器Fragment将实现的回调中,使用. 替换ListFragment为详细信息。FragmentFrameLayout

如果您希望详细信息Fragment替换ViewPager( 将它的两个片段放在一起),则修改 的布局,Activity使其只有 a FrameLayout,您将向其中添加Fragment包含 theViewPager或 details的 a Fragment

于 2013-01-11T13:33:41.103 回答