将值从适配器传递到导航组件中的BottomNavigationView片段 [英] Passing value from Adapter to a BottomNavigationView Fragment in Navigation components
问题描述
该应用程序在 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.
- 我创建了一个界面,以单击Fragment开关的
MainActivity
,并创建了一个Bundle,将接收到的值传达给所需的Fragment
- 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();
}
});
}
- 然后在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);
}
}
- 最后一步,我调用了第一步中创建的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屋!