如何调用特定Fragment的getActivity()?
How to call a specific Fragment's getActivity()?
我的问题是我在使用 Room 的片段上实现了 recyclerview。 RecyclerView、Adapter 和 Database 需要合二为一 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);
}
});
我的问题是我在使用 Room 的片段上实现了 recyclerview。 RecyclerView、Adapter 和 Database 需要合二为一 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);
}
});