如何调用特定Fragment的getActivity()?

How to call a specific Fragment's getActivity()?

我的问题是我在使用 Room 的片段上实现了 recyclerview。 RecyclerViewAdapterDatabase 需要合二为一 class(我猜) .

我的问题是,如果我将它们放入 StudentActivity

recyclerView = findViewById(R.id.SubjectRecyclerView);

将为空,因为在调用此函数时片段将不可用。

如果我将它们放入 StudentSubjectsFragment, 一切都会很好,但是 NewSubjectDialogFragment 告诉我 StudentActivity 需要实施 NewSubjectDialogFragment 因为这个:

    private NewSubjectDialogListener listener;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FragmentActivity activity = getActivity();
        if (activity instanceof NewSubjectDialogListener) {
            listener = (NewSubjectDialogListener) activity;
        } else {
            throw new RuntimeException("Activity must implement the NewSubjectDialogListener interface!");
        }
    }

如果在

FragmentActivity activity = getActivity();

行不知何故我可以调用 StudentSubjectsFragment class 的 getActivity() 函数,我认为它会解决我的问题,然后 class 将实现 NewSubjectDialogFragment 的将是 StudentSubjectsFragment 而不是 StudentActivity.

我试过这个:

FragmentActivity activity = getActivity().getSupportFragmentManager().findFragmentByTag("StudentSubjectsFragment").getActivity();

但是 activity 为空。

StudentSubjectsFragmentclass:

public class StudentSubjectsFragment extends Fragment
        implements NewSubjectDialogFragment.NewSubjectDialogListener,
        SubjectAdapter.SubjectClickListener {

    public static final String TAG = "StudentSubjectsFragment";

    private RecyclerView recyclerView;
    private SubjectAdapter adapter;
    private SubjectDatabase database;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.student_subjects, container, false);

        FloatingActionButton fab = rootView.findViewById(R.id.fabbb);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new NewSubjectDialogFragment().show(getActivity().getSupportFragmentManager(), NewSubjectDialogFragment.TAG);
            }
        });

        database = Room.databaseBuilder(
                getActivity(),
                SubjectDatabase.class,
                "subject-list"
        ).build();

        recyclerView = rootView.findViewById(R.id.SubjectRecyclerView);
        adapter = new SubjectAdapter(this);
        loadItemsInBackground();
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(adapter);

        return rootView;
    }

    private void loadItemsInBackground() {
        new AsyncTask<Void, Void, List<Subject>>() {

            @Override
            protected List<Subject> doInBackground(Void... voids) {
                return database.subjectDao().getAll();
            }

            @Override
            protected void onPostExecute(List<Subject> subjects) {
                adapter.update(subjects);
            }
        }.execute();
    }

    @Override
    public void onItemChanged(final Subject item) {
        new AsyncTask<Void, Void, Boolean>() {

            @Override
            protected Boolean doInBackground(Void... voids) {
                database.subjectDao().update(item);
                return true;
            }

            @Override
            protected void onPostExecute(Boolean isSuccessful) {
                Log.d("StudentActivity", "Subject update was successful");
            }
        }.execute();
    }

    @Override
    public void onItemDeleted(final Subject item) {
        new AsyncTask<Void, Void, Boolean>() {

            @Override
            protected Boolean doInBackground(Void... voids) {
                database.subjectDao().deleteItem(item);
                return true;
            }

        }.execute();
    }

    @Override
    public void onSubjectCreated(final Subject newItem) {
        new AsyncTask<Void, Void, Subject>() {

            @Override
            protected Subject doInBackground(Void... voids) {
                newItem.id = database.subjectDao().insert(newItem);
                return newItem;
            }

            @Override
            protected void onPostExecute(Subject subject) {
                adapter.addItem(subject);
            }
        }.execute();
    }
}

StudentActivityclass:

public class StudentActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_student);

        ViewPager vpProfile = findViewById(R.id.vpStudent);
        vpProfile.setAdapter(new StudentPagerAdapter(getSupportFragmentManager()));
    }
}

NewSubjectDialogFragmentclass:

public class NewSubjectDialogFragment extends DialogFragment {

    private EditText nameEditText;

    public static final String TAG = "NewSubjectDialogFragment";

    public interface NewSubjectDialogListener {
        void onSubjectCreated(Subject newItem);
    }

    private NewSubjectDialogListener listener;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FragmentActivity activity = getActivity().getSupportFragmentManager().findFragmentByTag("StudentSubjectsFragment").getActivity();
        if (activity instanceof NewSubjectDialogListener) {
            listener = (NewSubjectDialogListener) activity;
        } else {
            throw new RuntimeException("Activity must implement the NewSubjectDialogListener interface!");
        }
    }

    private boolean isValid() {
        return nameEditText.getText().length() > 0;
    }

    private Subject getSubject() {
        Subject subject = new Subject();
        subject.name = nameEditText.getText().toString();
        return subject;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        return new AlertDialog.Builder(requireContext())
                .setTitle(R.string.new_subject_item)
                .setView(getContentView())
                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        if (isValid()) {
                            listener.onSubjectCreated(getSubject());
                        }
                    }
                })
                .setNegativeButton(R.string.cancel, null)
                .create();
    }

    private View getContentView() {
        final View contentView = LayoutInflater.from(getContext()).inflate(R.layout.dialog_new_subject_item, null);
        nameEditText = contentView.findViewById(R.id.SubjectNameEditText);
        return contentView;
    }
}

我认为有一种方法可以更改 NewSubjectDialogFragment 以与 StudentSubjectsFragment 一起使用,但我是 android 开发的初学者不知道怎么做。

Mike M. 的解决方案非常有效。

工作代码部分如下:

NewSubjectDialogFragment:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Fragment fragment = getParentFragment();
    if (fragment instanceof NewSubjectDialogListener) {
        listener = (NewSubjectDialogListener) fragment;
    } else {
        throw new RuntimeException("Fragment must implement the NewSubjectDialogListener interface!");
    }
}

学生主题片段:

FloatingActionButton fab = rootView.findViewById(R.id.fabbb);
    fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        new NewSubjectDialogFragment().show(getChildFragmentManager(), NewSubjectDialogFragment.TAG);
    }
});