【问题标题】:How to open a fragment from another fragment?如何从另一个片段打开一个片段?
【发布时间】:2020-06-18 05:47:50
【问题描述】:

我无法从一个片段转到另一个片段。我一直在使用 FragmentTransaction.replace() 和 FragmentManager 对象,但由于某种原因,应用程序没有转到下一个片段。我正在尝试通过列表视图中的点击事件从 HomeFragment 转到 ToDoListFragment。

HomeFragment.java:

public class HomeFragment extends Fragment {

    private HomeViewModel homeViewModel;
    DatabaseHelper myDb;
    ArrayList<ToDoList> arrayList;
    ArrayList<String> list;
    ArrayAdapter adapter;
    ListView listView;
    MyAdapter myAdapter;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        homeViewModel =
                ViewModelProviders.of(this).get(HomeViewModel.class);
        View root = inflater.inflate(R.layout.fragment_home, container, false);
        myDb = new DatabaseHelper(getActivity());
        list = new ArrayList<String>();
        ToDoList toDoList;

        final Cursor list_result = myDb.getAllListData();


        listView = root.findViewById(R.id.toDoList_list);
        viewData();

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
            {
                String text = listView.getItemAtPosition(i).toString();
                ToDoListFragment fragment = new ToDoListFragment();
                while (list_result.moveToNext())
                {
                    String title = list_result.getString(1);

                    if (title.equals(text))
                    {
                        FragmentManager fm = getFragmentManager();
                        FragmentTransaction transaction = fm.beginTransaction();
                        transaction.replace(R.id.home_container, fragment);
                        transaction.addToBackStack(null);
                        transaction.commit();
                    }
                }
            }
        });

        return root;
    }

fragment_home.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/home_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/toDoList_list"/>

</FrameLayout>

ToDoListFragment.java:

public class ToDoListFragment extends Fragment {
    ListView listView;

    public ToDoListFragment()
    {

    }

    private ToDoListViewModel mViewModel;
    DatabaseHelper myDb;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.to_do_list_fragment, container, false);
        listView = view.findViewById(R.id.task_list);

        myDb = new DatabaseHelper(getActivity());

        return view;
    }

to_do_list_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/task_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.ToDoListFragment">

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/task_list"/>

</FrameLayout>

MainActivity.java:

public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;
    private DrawerLayout drawer;
    DatabaseHelper myDb;
    Menu menu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myDb = new DatabaseHelper(this);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        NavigationView navigationView = findViewById(R.id.nav_view);
        drawer = findViewById(R.id.drawer_layout);
        menu = navigationView.getMenu();

        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_add_new_list, R.id.nav_delete_list)
                .setDrawerLayout(drawer)
                .build();

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);

    }

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <FrameLayout
        android:id="@+id/frame_container"
        android:clickable="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

另外,在 transaction.replace() 中,我想使用初始片段中的 FrameLayout 的 id 还是我想去的片段?

【问题讨论】:

  • 我发布了一个代码,请检查它。您有错误,因为您的片段布局必须处于活动状态

标签: android android-fragments


【解决方案1】:

原因很简单,fragment中有framelayout,不正确,因为fragment必须包含在activity中

XML 活动

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                tools:context=".MainActivity">


    <FrameLayout
        android:id="@+id/content_frame"
        android:clickable="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>


</RelativeLayout>

在片段中

getSupportFragmentManager().beginTransaction()
                    .replace(R.id.content_frame, new MyListFragment())
                    .commit();

【讨论】:

  • 我试过这个,但由于某种原因,应用程序仍然崩溃。我忘了说我在 MainActivity 中使用了导航视图,所以我认为这可能会使事情变得复杂一些。我使用 MainActivity 代码及其布局更新了代码。此外,getSupportFragmentManager() 仅适用于活动,因此我在 HomeFragment 中使用 getChildFragmentManager() 代替。感谢您为我指出正确的方向,因为我不知道片段必须包含在活动中才能使其工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
相关资源
最近更新 更多