当前位置: 首页 > 知识库问答 >
问题:

使用BottomNavigationView在布局中的片段之间切换

吕征
2023-03-14

这是我第一次尝试开发android应用程序。

我有一个带有ConstraintLayout的MainActivity,它具有BottomNavigationView。每当选择第一个导航项时,我想显示一个类别列表(显示在片段中),然后每当选择此类别时,将显示与该特定类别相关的另一个列表(显示在另一个片段中)。

我读到(Android-fragment.replace()不替换内容-将其放在顶部)它指出“用XML编写的静态片段无法替换,它必须在片段容器中”,它是什么样子的?

我尝试创建我的片段容器,但是当我尝试获取ListView(容器的孙子)时有问题

categoriesListView=getView()。findViewById(R.id.categoriesList);

返回null。

主要活动

package com.alsowaygh.getitdone.view.main;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
import android.widget.TextView;


import com.alsowaygh.getitdone.R;
import com.alsowaygh.getitdone.view.services.CategoriesListFragment;
import com.alsowaygh.getitdone.view.services.OnCategorySelectedListener;
import com.alsowaygh.getitdone.view.services.ServicesListFragment;

public class MainActivity extends AppCompatActivity implements OnCategorySelectedListener {

    private static final String TAG = "MainActivity";
    FragmentManager fragmentManager;
    FragmentTransaction fragmentTransaction;


    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navigation_services:
//                    mTextMessage.setText(R.string.title_services);
                    CategoriesListFragment categoriesListFragment = new CategoriesListFragment();
                    fragmentTransaction.add(R.id.container, categoriesListFragment);
                    fragmentTransaction.commit();
                    return true;
                case R.id.navigation_bookings:
//                    mTextMessage.setText(R.string.title_bookings);
                    return true;
                case R.id.navigation_chats:
//                    mTextMessage.setText(R.string.title_chats);
                    return true;
                case R.id.navigation_settings:
                    return true;

            }
            return false;
        }
    };

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


        BottomNavigationView navigation = findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);

        fragmentManager = getSupportFragmentManager();
        fragmentTransaction = fragmentManager.beginTransaction();
    }


    @Override
    public void onCategorySelected(String category) {
        Log.w(TAG, "Successfully created CategoryListFragment!");
    }
}

activity\u主布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".view.main.MainActivity">


    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="0dp"
        android:layout_marginStart="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/navigation" />




</android.support.constraint.ConstraintLayout>

碎片

package com.alsowaygh.getitdone.view.services;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.alsowaygh.getitdone.R;
import com.alsowaygh.getitdone.view.main.MainActivity;

public class CategoriesListFragment extends Fragment {
    private ListView categoriesListView;
    OnCategorySelectedListener categoryListener;



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

        //initializing root view first to refer to it
        View rootView = inflater.inflate(R.layout.activity_main, container, false);

        //initializing ListView
        categoriesListView = getView().findViewById(R.id.categoriesList);

        //categories list
        final String[] categories = {"first category", "second category", "third category", "Fourth category"};

        //initializing and adding categories strings to the addapter
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this.getContext(),
                R.layout.category_textview);
        for (String c : categories) {
            arrayAdapter.add(c);
        }
        categoriesListView.setAdapter(arrayAdapter);

        //implement onListItemClick
        categoriesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //retrieve string from categories list at clicked position
            categoryListener.onCategorySelected(categories[position]);
            }
        });

        return rootView;
    }

    @Override //to fource container activity to implement the OnCategorySelectedListener
    public void onAttach(Context context) {
        super.onAttach(context);
        try{
            categoryListener  = (OnCategorySelectedListener) context;
        }catch(ClassCastException e){
            throw new ClassCastException(context.toString() + "must implement OnCategorySelectedListener");
        }
    }


}

碎片容器

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

    <fragment
        android:id="@+id/categories_list_fragment"
        android:name="com.alsowaygh.getitdone.view.services.CategoriesListFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp">

        <ListView
            android:id="@+id/categoriesList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp" />

    </fragment>
</FrameLayout>

你的帮助将不胜感激。

共有1个答案

芮化
2023-03-14

您需要在MainActivity(activity\u main)的布局文件中添加FrameLayout容器,只需单击底部导航视图(BottomNavigationView)中的按钮,将其替换为片段。这样,您就有了一个活动,并且片段显示在活动中,单击您可以调用的每个菜单项即可将其替换为片段。这应该可以解决您的问题。

您需要更改布局如下activity_main.xml.

<android.support.constraint.ConstraintLayout 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/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".view.main.MainActivity">

          <FrameLayout
            android:id="@+id/frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="0dp"
        android:layout_marginStart="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/navigation" />
</android.support.constraint.ConstraintLayout>

在MainActivity代码中,您需要进行如下更改:

case R.id.navigation_services:
//                    mTextMessage.setText(R.string.title_services);
                    CategoriesListFragment categoriesListFragment = new CategoriesListFragment();
                    fragmentTransaction.replace(R.id.frame, categoriesListFragment);
                    fragmentTransaction.commit();
                    return true;

在片段布局文件中,更改为LinearLayout:

<LinearLayout
    android:id="@+id/categories_list_fragment"
 android:name="com.alsowaygh.getitdone.view.services.CategoriesListFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="8dp"
    android:layout_marginTop="8dp">

    <ListView
        android:id="@+id/categoriesList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp" />

</LinearLayout>

编辑

在片段代码中,将布局更改为片段布局文件的名称(R.layout.fragment_layout_name)。

View rootView = inflater.inflate(R.layout.fragment_layout_name, container, false);
    //initializing ListView
categoriesListView = rootView.findViewById(R.id.categoriesList);
 类似资料:
  • 我有一个带有底栏的main_activity。我正在使用这个底栏在片段之间导航。然而,有一个片段不能通过底部栏直接导航。它必须通过MapView和从片段中访问。然而,每当我使用InfoWindow时,该应用程序就会崩溃。这是我的代码 异常:main process:com.teslaqubitsins.fasih.teslahcm,pid:2573 java.lang.nullpointerexc

  • 问题内容: 我正在使用带有底部导航视图的简单应用程序。我有3个带有文本的片段,我想在Botton Navigation中选择一个项目时启动它们,但是我不知道在MainActivity.java中写什么。所有片段都具有.xml布局和.java。我搜索了一些代码,写了代码,搜索了视频,但没有成功。 我正在学习Fragments和UI Dynamic,因此我在Android Studio中使用“底部导航

  • 问题内容: 我有2个要用于修改相同数据的不同布局文件,我将切换到“编辑视图”的布局,该布局允许用户修改图形数据,然后允许他们切换回“详细视图” ”显示详细的图表(使用androidplot库)。 我的问题是,当切换回我的“编辑视图”时,我的图形线不见了,只绘制了轴(因此布局切换,而我的图形视图被调用了onDraw())。一切都存储在同一个活动中,所以我不明白为什么这不起作用? 这些行存储在Grap

  • 我不是Android方面的专家,但对片段非常感兴趣。非常感谢您的帮助! 我在我的应用程序中实现了一个导航抽屉。有一个基本抽屉活动和一些片段,用户可以从抽屉菜单中切换。如果我想转移到另一个片段,没有问题,但当我使用意图开始一个新的活动时,它是有效的。如果你看一下我下面的代码,你会发现我使用了两个独立的菜单:一个用于操作栏图标(购物车和搜索),意图在其中完美工作,另一个用于导航抽屉在片段之间跳转。有没

  • 我有一个带有导航抽屉的应用程序,它为每个菜单项使用片段。 每次单击一个项目时,我都会替换当前片段。 问题是,在用户单击后显示新片段需要很长时间,并且它会被卡住。加载时间最长的片段是一个片段,其中还包含子片段的选项卡(一个片段包含一个RecyclerView)<有什么方法可以加快碎片的装载速度吗?(如果可能的话,可能会提前初始化它们?) 这是我的代码: HalachaFragment。cs(包含选项

  • 我已经使用Android ADT几个星期了,我曾经通过转到:文件来创建新活动 当我选择“新建空白活动”并单击“下一步”时,会显示一个我必须填写的新表格,标题为“片段布局名称”。为什么这突然出现,有谁知道为什么我被迫创建一个片段布局,因为我甚至不想使用它。我还记得我的一个朋友说他大约一周前更新了他的SDK,他说他有同样的问题。我是否应该在XML文档加载后删除其中的片段,或者有没有一种方法可以禁用它,