将值从适配器传递到导航组件中的BottomNavigationView片段 [英] Passing value from Adapter to a BottomNavigationView Fragment in Navigation components

查看:91
本文介绍了将值从适配器传递到导航组件中的BottomNavigationView片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该应用程序在 MainActivity 上具有 BottomNavigationView ,用于处理片段之间的导航.片段之一具有 RecyclerView ,并且 RecyclerView 的项目具有按钮.

The application has a BottomNavigationView on the MainActivity which deals with the navigation between Fragments. One of the Fragments has a RecyclerView in it and the items of the RecyclerView have a button.

我正在尝试使 RecyclerView 项"按钮导航到另一个Fragment,并随同传递一个值,但是在传递数据时,我一直收到空对象引用.

I am trying to make the RecyclerView Items' button navigate to another Fragment and pass a value along with it but I keep receiving a null object reference with passing the data.

  1. 我创建了一个界面,以单击Fragment开关的 MainActivity ,并创建了一个Bundle,将接收到的值传达给所需的Fragment
  1. I created an interface to get the click to the MainActivity for the Fragment switch and created a Bundle to communicate the received value to the required Fragment

// The interface
public interface OnItemClickListener {

    void onItemClick();

适配器类

//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("position",latLng.toString());
                mapFragment.setArguments(bundle);
//Interface to transport the click event to the MainActivity to switch Fragment in the BottomNavigationView
                listener.onItemClick();
                    }
        });
}

  1. 然后在MainActivity中,我实现了用于切换BottomNavigation视图的界面.

public class MainActivity extends AppCompatActivity implements OnItemClickListener {
    BottomNavigationView navView;
    @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);
    }

    @Override
    public void onItemClick() {
        navView.setSelectedItemId(R.id.navigation_map);
    }
}

  1. 最后一步,我调用了第一步中创建的Bundle,但这是出现空对象引用的地方.

//MapFragment
 private void setCam(){
        Bundle bundle = getArguments();
       String position = bundle.getString("position");
    }

谢谢.

推荐答案

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);

此处, mapFragment 只是一个已创建的对象,未在导航图中使用.也就是说,它是独立于导航的独立对象,因此它不参与导航,因为它与navGraph中的当前 mapFragment 片段不同.

Here the mapFragment is just a created object that is not used in the navigation graph. i.e. it's a standalone object that is independent of the navigation, so it is not involved in the navigation as it's not the same as the current mapFragment fragment in the navGraph.

解决方案:

为了解决这个问题,每当在BottomNavigationView的片段之间切换时,都需要传递参数,并且注册 OnNavigationItemSelectedListener 是一个不错的选择:

In order to solve this, you need to pass the argument whenever you switch among fragments of the BottomNavigationView, and registering OnNavigationItemSelectedListener is a good place for that:

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

First allow the adapter to send the arguments back to the activity through the listener callback

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

So, modify the listener callback to accept a parameter

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 ,并修改回调以接受活动中的捆绑包:

And finally, register OnNavigationItemSelectedListener to the navView and modify the callback to accept the Bundle in activity:

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;
    }


}

这篇关于将值从适配器传递到导航组件中的BottomNavigationView片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆