Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将值从适配器传递到导航组件中的BottomNavigationView片段_Java_Android_Android Fragments_Android Recyclerview_Bundle - Fatal编程技术网

Java 将值从适配器传递到导航组件中的BottomNavigationView片段

Java 将值从适配器传递到导航组件中的BottomNavigationView片段,java,android,android-fragments,android-recyclerview,bundle,Java,Android,Android Fragments,Android Recyclerview,Bundle,应用程序在main活动上有一个BottomNavigationView,它处理片段之间的导航。其中一个片段中有一个RecyclerView,而RecyclerView的项有一个按钮 我试图让RecyclerViewItems'按钮导航到另一个片段并传递一个值,但在传递数据时,我一直收到一个空对象引用 我为片段开关创建了一个界面来点击MainActivity,并创建了一个Bundle来将收到的值传递给所需的片段 适配器类 //Define interface OnItemClickListene

应用程序在
main活动
上有一个
BottomNavigationView
,它处理片段之间的导航。其中一个片段中有一个
RecyclerView
,而
RecyclerView
的项有一个按钮

我试图让
RecyclerView
Items'按钮导航到另一个片段并传递一个值,但在传递数据时,我一直收到一个空对象引用

  • 我为片段开关创建了一个界面来点击
    MainActivity
    ,并创建了一个Bundle来将收到的值传递给所需的片段
  • 适配器类

    //Define interface
     OnItemClickListener listener;
    
    //Create constructor for interface
        public LocationsAdapter(Activity activity) {
            listener = (MainActivity)activity;
    
    ...
     @Override
        public void onBindViewHolder(@NonNull LocationsViewHolder holder, int position) {
    
    //A click listener for the button
            holder.showMarkerButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    //Create instance of MapFragment to pass data as Bundle
                    MapFragment mapFragment = new MapFragment();
     LatLng latLng = new LatLng(markerObject.getLatitude(),markerObject.getLongitude());
    //Create Bundle and add data
                    Bundle bundle = new Bundle();
    bundle.putString("latitude",markerObject.getLatitude().toString());
    bundle.putString("longitude",markerObject.getLongitude().toString());
                    listener.onItemClick(bundle);
                        }
            });
    }
    
  • 然后在MainActivity中,我实现了切换底部导航视图的界面
  • 作为最后一步,我调用了我在第一步中创建的Bundle,但这就是null对象引用出现的地方

  • 提前感谢。

    使用导航控制器时,您可以通过参数传入数据。转到导航组件XML文件并进行以下更改

    1.在导航操作中,需要添加一个参数

    <action
        android:id="@+id/action_id"
        app:destination="@id/destinationFragment">
        <argument
            android:name="paramterName"
            app:argType="string" />
    </action>
    
    然后可以在目标片段中提取包

    val parameter = DestinationFragmentArgs.fromBundle(requireArguments()).parameterName
    // parameter has the value of "text123"
    
    由于导航组件使用safeargs,因此可以传递从继承的任何类型的参数

    这里的
    mapFragment
    只是一个创建的对象,不在导航图中使用。i、 e.它是独立于导航的独立对象,因此不涉及导航,因为它与navGraph中当前的
    mapFragment
    片段不同

    解决方案:

    为了解决这个问题,每当在BottomNavigationView的片段之间切换时,都需要传递参数,注册
    OnNavigationItemSelectedListener
    是一个很好的地方:

    首先,允许适配器通过侦听器回调将参数发送回活动

    因此,修改侦听器回调以接受参数

    interface OnItemClickListener listener {
        void onItemClick(Bundle args);
    }
    
    将其应用到适配器上

    @Override
        public void onBindViewHolder(@NonNull LocationsViewHolder holder, int position) {
    
            //A click listener for the button
            holder.showMarkerButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    
                    LatLng latLng = new LatLng(markerObject.getLatitude(),markerObject.getLongitude());
                    
                    //Create Bundle and add data
                    Bundle bundle = new Bundle();
                    bundle.putString("position",latLng.toString());
                    
                    //Interface to transport the click event to the MainActivity to switch Fragment in the BottomNavigationView
                    listener.onItemClick(bundle);
                }
            });
    }
    
    最后,将
    OnNavigationItemSelectedListener
    注册到
    navView
    并修改回调以接受活动中的捆绑包:

    public class MainActivity extends AppCompatActivity implements OnItemClickListener {
        BottomNavigationView navView;
        
        private Bundle mapArgs;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            navView = findViewById(R.id.nav_view);
            // Passing each menu ID as a set of Ids because each
            // menu should be considered as top level destinations.
            AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
                     R.id.navigation_home,R.id.navigation_map, R.id.navigation_locations, R.id.navigation_profile)
                    .build();
            NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
            NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
            NavigationUI.setupWithNavController(navView, navController);
            
            
            navView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    navController.navigate(item.getItemId(), mapArgs);
                    return true;
                }
            });     
            
        }
    
        @Override
        public void onItemClick(Bundle args) {
            navView.setSelectedItemId(R.id.navigation_map);
            mapArgs = args;
        }
    
    
    }
    

    您可以在主活动中包含设置片段的代码吗?您正在创建捆绑包并将数据放入其中,但不将其传递到任何地方。追踪您创建的
    mapFragment
    对象发生了什么。@ShayKin I添加了完整的MainActivity@M.Azyoksul是的,现在我明白了问题所在,包必须提交给我将切换到的片段,片段才能访问包。如何引用BottomNavigation正在使用的MapFragment的相同实例?我知道通常一个Bundle是由一个FragmentManager提交的,比如
    getFragmentManager().beginTransaction().add(R.id.container,fragment.commit()但是由于导航由NavController负责,所以我不能使用碎片管理器。为什么不在这种情况下使用碎片管理器呢谢谢,我让它工作了,但我还有一个问题。为了更好地理解,我更新了问题中的MapFragment方法。如果我按下RecyclerView项中的按钮,它将导航到MapFragment,但getArguments()方法返回null,但如果我返回到RecyclerView并再次按下按钮,它将打开MapFragment并显示带有LatLng的Toast,但它不会移动相机。setCam方法是在onMapReady()中调用的仍然在
    listener.onItemClick(bundle)之后被调用你能检查一下它是否还在那里吗;如果是,则删除它这是我的错,没有注意到在问题中留下了它,我现在就修复了它,但除此之外,我只有包含捆绑包的onItemClick。@EdwardAarma您还有问题吗?是的,基本上,当我第一次用按钮从RecyclerView导航到MapFragment时,捆绑包返回null,如果我重新创建MapFragment,那么我得到的是Bundle,但是moveCamera();方法不起作用。
    
    navigationController.navigate(actionSourceFragmentToDestinationFragment("text123"))
    
    val parameter = DestinationFragmentArgs.fromBundle(requireArguments()).parameterName
    // parameter has the value of "text123"
    
    MapFragment mapFragment = new MapFragment();
    LatLng latLng = new LatLng(markerObject.getLatitude(),markerObject.getLongitude());
    //Create Bundle and add data
    Bundle bundle = new Bundle();
    bundle.putString("position",latLng.toString());
    mapFragment.setArguments(bundle);
    
    interface OnItemClickListener listener {
        void onItemClick(Bundle args);
    }
    
    @Override
        public void onBindViewHolder(@NonNull LocationsViewHolder holder, int position) {
    
            //A click listener for the button
            holder.showMarkerButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    
                    LatLng latLng = new LatLng(markerObject.getLatitude(),markerObject.getLongitude());
                    
                    //Create Bundle and add data
                    Bundle bundle = new Bundle();
                    bundle.putString("position",latLng.toString());
                    
                    //Interface to transport the click event to the MainActivity to switch Fragment in the BottomNavigationView
                    listener.onItemClick(bundle);
                }
            });
    }
    
    public class MainActivity extends AppCompatActivity implements OnItemClickListener {
        BottomNavigationView navView;
        
        private Bundle mapArgs;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            navView = findViewById(R.id.nav_view);
            // Passing each menu ID as a set of Ids because each
            // menu should be considered as top level destinations.
            AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
                     R.id.navigation_home,R.id.navigation_map, R.id.navigation_locations, R.id.navigation_profile)
                    .build();
            NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
            NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
            NavigationUI.setupWithNavController(navView, navController);
            
            
            navView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    navController.navigate(item.getItemId(), mapArgs);
                    return true;
                }
            });     
            
        }
    
        @Override
        public void onItemClick(Bundle args) {
            navView.setSelectedItemId(R.id.navigation_map);
            mapArgs = args;
        }
    
    
    }