如何调用特定片段的getActivity()?

时间:2019-12-17 10:31:41

标签: android android-fragments android-fragmentactivity

我的问题是我在使用Room的片段上实现了recyclerview。 RecyclerView Adapter Database 需要在一个类中在一起(我想)。

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

recyclerView = findViewById(R.id.SubjectRecyclerView);

为空,因为在该函数调用时Fragment将不可用。

如果我将它们放入 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 类的getActivity()函数,我认为它将解决我的问题,然后实现NewSubjectDialogFragment的类将是 StudentSubjectsFragment ,而不是 StudentActivity

我尝试过:

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

但是活动为空。

StudentSubjectsFragment类:

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

StudentActivity类:

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

NewSubjectDialogFragment类:

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开发的初学者,不知道该怎么做。

1 个答案:

答案 0 :(得分:0)

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!");
    }
}

StudentSubjectFragment:

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