【问题标题】:How to access a fragment object from another fragment如何从另一个片段访问片段对象
【发布时间】:2020-01-04 23:08:04
【问题描述】:

我有一个抽屉式导航活动(主管仪表板),其中我有一个片段(工作人员详细信息)具有 recyclerview。

在同一个活动中,我有一个显示排序选项的底部工作表片段。

现在,我想将用户选择的那些排序选项应用到 RecyclerView。

Activity -> Fragment1 (worker details) -> RecyclerView
                                       -> RecyclerViewAdapter
                                       -> RecyclerViewModel
         -> Fragment2 (bottom sheet)   -> Sort options

那么,我如何访问 Fragment1 的 RecyclerView 对象并从 Fragment2 中的 onClick 对适配器的数组进行排序

现在,我已经可以使用

从片段中调用宿主活动方法了
(SupervisorDashboard)getActivity()).method()

但是如何从宿主活动中访问 Fragment1 的 RecyclerView 对象呢?

工人详情

public class WorkerDetailsFragment extends Fragment {

    private WorkerDetailsViewModel workerDetailsViewModel;
    static RecyclerView recyclerView;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        workerDetailsViewModel = ViewModelProviders.of(this).get(WorkerDetailsViewModel.class);
        View root = inflater.inflate(R.layout.fragment_worker_details, container, false);

        recyclerView = root.findViewById(R.id.rc_worker_details);
        WorkerRVAdapter workerRVAdapter = new WorkerRVAdapter(
                workerDetailsViewModel.getWorkerNames(),
                workerDetailsViewModel.getWorkerRoles(),
                workerDetailsViewModel.getImageUrls(),
                getContext());
        recyclerView.setNestedScrollingEnabled(false);
        recyclerView.setAdapter(workerRVAdapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        return root;
    }
}

主管仪表板

public class SupervisorDashboard extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_supervisor_dashboard);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,
                R.id.nav_tools, R.id.nav_share, R.id.nav_send)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.supervisor_dashboard, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_settings:
                View view = getLayoutInflater().inflate(R.layout.fragment_bottom_sheet_sort, null);

//                BottomSheetDialog dialog = new BottomSheetDialog(this);
//                dialog.setContentView(view);
//                dialog.show();
                BottomSheetSortFragment bottomSheetFragment = new BottomSheetSortFragment();
                bottomSheetFragment.show(getSupportFragmentManager(), "hello");
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

BottomSheetSortFragment

public View onCreateView(LayoutInflater inflater, final ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_bottom_sheet_sort, container, false);

        button = view.findViewById(R.id.apply_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Sort the arrays in RecyclerView on click
                dismiss();
            }
        });

        return view;
    }

我可以在 Fragment2 中创建一个静态方法,然后从 Fragment1 调用该方法,但必须有一些正确的方法。

【问题讨论】:

    标签: android android-studio android-fragments android-recyclerview fragment


    【解决方案1】:

    示例片段

    public class SomeFragment extends Fragment {
    public View view;
    public TextView textView;
    public Button button;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        view =inflater.inflate(R.layout.fragment_blank, container, false);
        textView = (TextView)view.getRootView().findViewById(R.id.textView_fragment1);
        return view;
    }
    
    public void getTextView(){
        return textView;
    }
    
    public void getButton(){
        return button;
    }
    

    一旦在您的 MainActivity 或您想要访问的任何其他地方完成 您的 Fragment 中的 TextView/Button 您应该确保在 您的 OnCreate() 方法很可能会以其他方式抛出 nullPointer。 因此,您要更改 TextView/Button 的活动应该如下所示:

    public class MainActivity extends AppCompatActivity {
    private Button button1;
    private FragmentManager fragmentManager;
    private FragmentTransaction fragmentTransaction;
    SomeFragment someFragment = new SomeFragment();
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button1 = (Button)findViewById(R.id.button1);
        changeFragment();
    
        fragmentManager = getFragmentManager();
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.fragment1,someFragment);
        fragmentTransaction.commit();
    
        // Now we can get access to TextView and Button inside SomeFragment
    }
    
    public void updateText(String msg) {
        TextView v = this.someFragment.getTextView();
        v.setText(msg);
    }
    
    } // end of activity
    

    【讨论】:

    • 我已经可以通过调用活动的方法从片段中通知宿主活动。有没有办法在宿主活动中访问片段的对象(回收器视图)?
    • 用示例更新了我的答案。请检查。
    • 您能否指定我们如何调用该片段类方法getTextView()
    • 我在 Activity 类中添加了一个 updateText() 方法。从这里我调用片段的 getTextView() 方法。
    【解决方案2】:

    但是如何从宿主活动中访问 Fragment1 的 RecyclerView 对象呢?

    理想情况下,您不需要。您在 Fragment1 中公开一个定义您想要做什么的方法,然后根据需要在 Activity 中调用它。

    文档介绍了如何在片段之间进行通信:

    https://developer.android.com/training/basics/fragments/communicating

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-30
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多