如何在另一个片段(通过Activity)调用片段后显示片段

时间:2015-07-26 22:09:12

标签: android-fragments fragmentpageradapter fragmenttransaction

我的代码很结束。在被另一个片段(通过Activity)调用后,我无法显示片段。我在Fragment / FragmentPagerAdapter / FragmentTransactions上阅读了Android Developer guide和许多与SO相关的主题,无法解决我的问题。这个是一个明显的解决方案Is it possible to remove a fragment without replacing it by another fragment

我有一个活动类,它将根据所选的选项卡托管片段。这些片段由FragmentPagerAdapter根据用户对选项卡的选择动态创建。在第一个选项卡中,它创建FragmentA(ListFragment),它由一个项目列表组成。当用户点击任何一个项目时,它应该显示另一个包含该项目详细信息的片段,但令我沮丧的是(并且眼睛在燃烧),它所做的就是打印出我的登录logcat。请看我的代码。也许,我盯着它看太久和/或只是不知道android足以看到发生了什么。我怀疑它与这一行有关:fragTransaction.replace(R.id.curriculumParent,fragC);现在我知道如果第一个参数是活动布局文件中的一个片段容器是定义的,但是由于它不是静态完成的,我不知道除了调用FragmentB的布局文件之外还要放什么。

提前致谢!

MainActivity.java

public class MainActivity extends FragmentActivity implements
    FragmentB.OnColorSelectedListener {

private static final String TAG = "MainActivity";
private final Handler handler = new Handler();

private PagerSlidingTabStrip tabs;
private ViewPager pager;
private MyPagerAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
    pager = (ViewPager) findViewById(R.id.pager);

    FragmentManager fm = getSupportFragmentManager();
    adapter = new MyPagerAdapter(fm);

    pager.setAdapter(adapter);

    final int pageMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4,
            getResources().getDisplayMetrics());
    pager.setPageMargin(pageMargin);

    tabs.setViewPager(pager);
}

...
...
...

public class MyPagerAdapter extends FragmentPagerAdapter {

    private final String[] TITLES = { "FragmentB", "2ndTabFragment", "3rdTabFragment" };

    public MyPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public CharSequence getPageTitle(int position)
    {
        return TITLES[position];
    }

    @Override
    public int getCount()
    {
        return TITLES.length;
    }

    @Override
    public Fragment getItem(int position)
    {
        Fragment fragment = null;
        switch (position) {
        case 0:
            fragment = Fragment.instantiate(getBaseContext(), FragmentB.class.getName());
            break;
        case 1:
            fragment = Fragment.instantiate(getBaseContext(), SecondTabFragment.class.getName());
            break;
        case 2:
            fragment = Fragment.instantiate(getBaseContext(), ThirdTabFragment.class.getName());
            break;
        }
        return fragment;
    }
}

@Override
public void onColorLevelSelected(int position)
{
    Log.i(TAG, "Got Here!");
    FragmentC fragC = new FragmentC(); 
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction fragTransaction = fm.beginTransaction();
    **fragTransaction.replace(R.id.curriculumParent, fragC);**
    fragTransaction.addToBackStack(null);
    fragTransaction.commit();
}

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
 >

<com.astuetz.PagerSlidingTabStrip
    android:id="@+id/tabs"
    android:layout_width="match_parent"
    android:layout_height="48dip"
    android:background="@drawable/background_tabs" />

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/tabs"
    tools:context=".MainActivity" />
</RelativeLayout>

FragmentB.java

public class FragmentB extends ListFragment{

OnColorSelectedListener mCallback;

private String[] colorLevel = new String[]{
        "Yellow",
        "Orange",
        "Green",
        "Blue",
        "pink",
        "Black"
};
private int[] colorImages = new int[]{
        R.drawable.yellow,
        R.drawable.orange,
        R.drawable.green,
        R.drawable.blue,
        R.drawable.pink,
        R.drawable.black
};

public interface OnColorSelectedListener{
    public void onItemLevelSelected(int position);
}

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

    List<HashMap<String, String>> colorList = new ArrayList<HashMap<String, String>>();
    for(int i = 0; i < 6; i++){
        HashMap<String, String> colorMap = new HashMap<String, String>();
        colorMap.put("lvl", colorLevel[i]);
        colorMap.put("img", Integer.toString(colorImages[i]));
        colorList.add(colorMap);
    }

    String[] from = {"img", "lvl"};

    int[] to = {R.id.colorLevelImg, R.id.colorLevelTxt};

    SimpleAdapter adapter = new SimpleAdapter(getActivity().getBaseContext(),colorList, R.layout.fragment_b ,from, to);
    setListAdapter(adapter);

    return super.onCreateView(inflater, container, savedInstanceState);
}

@Override
public void onAttach(Activity activity){
    super.onAttach(activity);

    try{
        mCallback = (OnColorSelectedListener) activity;
    }catch(ClassCastException e){
        throw new ClassCastException(activity.toString()
            + " must implement OnColorSelectedListener");
    }
}

@Override
public void onListItemClick(ListView l, View v, int pos, long id){
    Toast.makeText(getActivity(), "selected color :" + colorLevel[pos],
            Toast.LENGTH_LONG).show();
    mCallback.onColorLevelSelected(pos);

} 
}

fragment_b.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    **android:id="@+id/curriculumParent"**
    ...
    ...

    android:background="#FEFDFB">

    <ImageView
        android:id="@+id/colorLevelImg"
        ...
        android:paddingBottom="10dp" />

    <LinearLayout
        ...
        android:orientation="vertical" >

        <TextView
            android:id="@+id/colorLevelTxt"
            ...
            android:textSize="25sp" />
    </LinearLayout>
 </LinearLayout>

FragmentC.java

    public class FragmentC extends Fragment{

    public static final String TAG = "Fragment C";

    public FragmentC(){}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        Log.i(TAG, "HI");
        return inflater.inflate(R.layout.fragment_c, container, false); 
    }
}

fragment_c.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFCC00" >

    <TextView
        android:id="@+id/editText1"
        ...
        android:layout_margin="16dp"
        android:text="This is the C Fragment that will replace the B Fragment" >
    </TextView>

</RelativeLayout>

1 个答案:

答案 0 :(得分:1)

我注意到FragmentB.java没有明确指向任何要扩充的布局文件。如果您不知道,

  

ListFragment具有由单个列表视图组成的默认布局

,记录为@ ListFragment。如果你只想要一个简单的ListView,那么你仍然可以,但也许不是。但是你有代码引用FragmentB的另一个布局:

new SimpleAdapter(getActivity().getBaseContext(),colorList, R.layout.fragment_b...

注意:R.layout.fragment_b是仅为ArrayAdapter指定的布局!不是片段。但这是正常的,可能没问题。

MainActivity 中,onColorLevelSelected():

fragTransaction.replace(R.id.curriculumParent,...

注意:

  • 我认为这只替换了适配器而不是片段的布局。
  • 也许您想要扩展包含ListView的布局文件,并将其用于片段。
  • 你的问题基本上就是布局,可以使用它。

修改 代码建议:

SimpleAdapter adapter = new SimpleAdapter(getActivity().getBaseContext(),colorList, R.layout.fragment_x

public void onColorLevelSelected(int position)
   FragmentC fragX = new FragmentX();
   ...
   fragTransaction.replace(R.id.curriculumParent, fragX);

注意:

  • 注意我正在使用任意FragmentX的示例。 Adapter和replace()相互匹配。
  • 我理解这个代码更改有点可观。既然我说过,这是一个新的代码建议:

    public void onListItemClick(ListView l, View v, int pos, long id){
        Toast.makeText(getActivity(), "selected color :" + colorLevel[pos], Toast.LENGTH_LONG).show();
        SimpleAdapter adapter = new SimpleAdapter(getActivity().getBaseContext(),colorList, R.layout.fragment_b ,from, to);
        ...
        setListAdapter(adapter);
        ...
        mCallback.onColorLevelSelected(pos);   }
    

注意:此代码更改只是为了更简单,我的尝试。这个想法是当用户单击ListView中的一行时,您知道使用了哪个布局和片段。希望这会使代码变得更简单。