【问题标题】:How to call a specific Fragment's getActivity()?如何调用特定 Fragment 的 getActivity()?
【发布时间】:2019-12-17 10:31:41
【问题描述】:

我的问题是我在使用 Room 的片段上实现了一个 recyclerview。 RecyclerViewAdapterDatabase 需要放在一个类中(我猜)。

我的问题是,如果我将它们放入 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();

line 我将能够调用 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 开发的初学者,不知道该怎么做。 p>

【问题讨论】:

  • NewSubjectDialogFragment的代码在哪里,请发在这里。
  • 我真的无法理解你的问题……你想达到什么目的?
  • 编辑:添加了NewSubjectDialogFragment的代码
  • 我想要一个关于 StudentSubjectsFragment 的工作 recyclerview。我只知道如何在单个 Activity 上实现它,但是如果有一个带有片段的 Activity,由于我提到的问题,我不知道如何实现它。 Adapter、Recyclerview、Database应该在StudentSubjectFragment里面,但是StudentActivity里面也需要,因为StudentActivity需要实现NewSubjectDialogFragment。我的问题:StudentSubjectFragment 是否有可能实现 NewSubjectDialogFragment 而不是 StudentActivity?如果是,如何?如果没有,那还有什么办法?
  • 是的,你可以这样做。在NewSubjectDialogFragment#show() 调用中,使用getChildFragmentManager() 而不是getActivity().getSupportFragmentManager(),在NewSubjectDialogFragment 中,检查并指定getParentFragment() 作为NewSubjectDialogListener,而不是getActivity()。这通常在onAttach() 中完成,顺便说一句,而不是onCreate(),但两者都可以,因为onCreate()onAttach() 之后运行。

标签: android android-fragments android-fragmentactivity


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 2015-04-04
    相关资源
    最近更新 更多