在一个活动中浏览片段

10

我想使用一个 Activity 来管理多个 Fragment 并在它们之间进行导航。例如,在该活动中,有一个列表视图是一个 Fragment。当用户从列表中选择一项时,视图将导航到另一个 Fragment。如何实现此功能?

我知道开发者网站上有一个不错的教程,但它只介绍了在平板屏幕上使用两个片段布局,其中一个列表片段和一个详细信息片段显示在一个屏幕上。我只想在片段之间进行导航,而不要在一个屏幕上同时显示两个片段。

是否有教程可以教我如何做到这一点?


但是如果你只看纵向布局,那个教程是完全有效的。 - Warpzit
@Warpzit,但是教程让我在纵向布局中创建两个活动,每个活动对应一个片段,是吗? - Leem.fin
4个回答

12

简而言之,回答你的问题是要通知你的主 Activity,然后使用 FragmentManager 替换当前的 fragment 容器。

其中一种方法是在第一个 fragment 中创建一个接口,让主 Activity 注册/监听(实现)这个接口,然后在监听器回调中,使用 FragmentManager 来替换容器内容为第二个 fragment。

我不确定是否有教程,但这是我的代码片段:

第一个 Fragment

public class First extends Fragment{
private static onMySignalListener listener;

//call this function from whatever you like i.e button onClickListener
public void switchWindow() {
    if(listener != null){
        listener.onMySignal();
    }
}

public interface onMySignalListener {
    //customize this to your liking

    //plain without argument
    void onMySignal();

    //with argument
    void onMySignalWithNum(int mNum);
}

public static void setOnMySignalListener(onMySignalListener listener) {
    First.listener = listener;
}}

主机活动

public class HostActivity extends FragmentActivity implements onMySignalListener{
private final String ADD_TAG_IF_NECESSARY = "mTag";

@Override
public void onCreate(Bundle ssi) {
    setContentLayout(R.layout.main);

    FirstFragment.setOnMySignalListener(this);
}

@Override
public void onMySignal() {
    //if you're using compat library
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();

    //initialize your second fragment
    sfragment = SecondFragment.newInstance(null);
    //replace your current container being most of the time as FrameLayout
    transaction.replace(R.id.container, fragment, ADD_TAG_IF_NECESSARY);
    transaction.commit();
}

@Override
public void onMySignalWithNum(int mNum) {
    //you can do the same like the above probably with your own customization
}}

这只是一个演示如何实现接口的例子,您需要自行整理。但请注意,如果您有许多片段想要告知宿主活动某些事情,则此方法不是很有效。这样做将导致您需要向宿主活动实现各种监听器。


嗨,如果我有很多片段(大约5个)想要通知我的主机活动,该如何实现? - Leem.fin
可以使用Fragment的onAttach()在宿主Activity中设置监听器,而不是使用自定义的setOn方法吗? - Leem.fin
1
在Android API中,最复杂的通知系统是使用BroadcastReceiver。您可以使用此类替换传统的Java接口/监听器。在主机活动中注册一个接收器,然后从您的五个或更多片段中,您可以简单地发送广播。为了区分您的片段,您可以在sendBroadcast方法中附带Intent。查看这个:BroadcastReceiver,可能会搜索一些示例,我无法在评论中发布我的示例,干杯。 - Raymond Lagonda
为解决最后一个问题,您应该使用ViewModel在Fragment和Activity之间共享数据。 - Gastón Saillén

5
我认为这对您会有用。这是一个例子,其中两个片段在一个屏幕上独立工作。 MainActivity
public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        Fragment newFragment = new Test();
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.add(R.id.UprLayout, newFragment);
        // transaction.addToBackStack(null);
        transaction.commit();

        Fragment newFragment2 = new TestRight(); 
        FragmentTransaction transaction2 = getFragmentManager().beginTransaction();
        transaction2.add(R.id.dwnLayout, newFragment2);
        // transaction.addToBackStack(null);
        transaction2.commit();
    }
}

"main_activity.xml" :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LinearLayout2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center|center_horizontal"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/UprLayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical" />

    <LinearLayout
        android:id="@+id/dwnLayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical" />

</LinearLayout>

片段 测试 :

public class Test extends Fragment {
TextView tv;

@Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

    }

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

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

片段 TestRight

public class TestRight extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

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

    @Override
    public void onStart() {
        super.onStart();
        Button button = (Button)getActivity().findViewById(R.id.button1);
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Fragment newFragment = new Right2nd();
                FragmentTransaction transaction = getFragmentManager()
                        .beginTransaction();
                transaction.replace(R.id.dwnLayout, newFragment);
                transaction.addToBackStack("aa");
                transaction.commit();

                //transaction.add(R.id.frag, newFragment).commit();
            }
        });
    }
}

"test.xml":
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="test"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textSize="50sp" />

</LinearLayout>

"test_right.xml":
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test right"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textSize="45sp" />

</LinearLayout>

片段 Right2nd :

public class Right2nd extends Fragment{

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View vw = inflater.inflate(R.layout.right_2nd, container, false);
        return vw;
    }
}

"right_2nd.xml":
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Right 2nd"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textSize="50sp" />

</LinearLayout>

2

0

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