首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在导航组件中将值从适配器传递到BottomNavigationView片段

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

Stack Overflow用户
提问于 2021-04-13 22:49:12
回答 2查看 539关注 0票数 2

应用程序在BottomNavigationView上有一个MainActivity,它处理片段之间的导航。其中一个片段中有一个RecyclerViewRecyclerView的项有一个按钮。

我试图使RecyclerView项的按钮导航到另一个片段,并同时传递一个值,但是通过传递数据,我一直收到一个空对象引用。

  1. 我创建了一个接口来获得对片段开关的MainActivity的单击,并创建了一个绑定来将接收到的值传递给所需的片段
代码语言:javascript
复制
// The interface
public interface OnItemClickListener {

    void onItemClick();

适配器类

代码语言:javascript
复制
//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);
                    }
        });
}
  1. 然后,在MainActivity中,我实现了切换BottomNavigation视图的接口。
代码语言:javascript
复制
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,但这是空对象引用出现的地方。
代码语言:javascript
复制
//MapFragment
private void setCam(){
        Bundle bundle = getArguments();
        if (getArguments() != null ){
            String SLatitude = bundle.getString("latitude");
            String SLongitude = bundle.getString("longitude");
            Double latitude = Double.parseDouble(SLatitude);
            Double longitude = Double.parseDouble(SLongitude);
            LatLng latLng = new LatLng(latitude,longitude);
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 20));
            Toast.makeText(getActivity(), latLng.toString(), Toast.LENGTH_SHORT).show();
        }
        else{
            Toast.makeText(getActivity(), "error present", Toast.LENGTH_SHORT).show();
        }
    }

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-14 04:23:47

代码语言:javascript
复制
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中的当前navGraph片段不一样。

解决方案:

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

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

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

代码语言:javascript
复制
interface OnItemClickListener listener {
    void onItemClick(Bundle args);
}

把它应用在适配器上

代码语言:javascript
复制
@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并修改回调以接受在活动中的绑定:

代码语言:javascript
复制
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;
    }


}
票数 1
EN

Stack Overflow用户

发布于 2021-04-14 03:45:56

当使用导航控制器时,输入带有参数的数据。转到您的导航组件XML文件,并进行以下更改;

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

代码语言:javascript
复制
<action
    android:id="@+id/action_id"
    app:destination="@id/destinationFragment">
    <argument
        android:name="paramterName"
        app:argType="string" />
</action>

2.向目标片段添加相同的参数

代码语言:javascript
复制
<fragment
    android:id="@+id/coursesNavFragment"
    android:name="com.example.example.DestinationFragment"
    android:label="destination_fragment"
    tools:layout="@layout/destination_fragment" >
    <argument
        android:name="parameterName"
        app:argType="string" />
</fragment>

您也可以使用设计视图轻松地做到这一点。

现在,您为导航到目标片段而调用的函数要求您传递一个参数。

代码语言:javascript
复制
navigationController.navigate(actionSourceFragmentToDestinationFragment("text123"))

然后,您可以在目标片段中提取包。

代码语言:javascript
复制
val parameter = DestinationFragmentArgs.fromBundle(requireArguments()).parameterName
// parameter has the value of "text123"

由于导航组件使用safeargs,所以可以传递从可分割继承的任何类型的参数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67083340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档