嘿,我真的需要您的帮助。我花了大约5天的时间才尝试让recyclerview进行更新,仅当用户在从菜单操作栏显示的对话框中按“确定”时才进行更新。我尝试了我能想到的每种可能的方法,在stackoverflow,YouTube等上看到的每种方法,但没有一种对我有用。 对话框关闭后,如何在片段中获取recyclerview进行更新?我知道关于更新菜单和(带有dialogfragment的recyclerviews)也有类似的问题,但是它们都没有结合在一起。
在无数次尝试中,下面发布的当前代码配置不会引起任何错误,但是,recyclerview保持空白。我必须找到解决方案的最接近的尝试是创建一个适配器并在onOptionsItemSelected中设置回收站。但显然,它仅在用户单击按钮时更新,并且首次单击将创建空白的recyclerview。
片段:
(通过不同的尝试有很多重复的注释代码)
public class ExerciseRoutine extends Fragment implements ExerciseRoutine_Dialog.RoutineDialogListener{
private String Routine_name, Routine_split;
private ArrayList<ExerciseRoutine_Information> Routine_information = new ArrayList<>();
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
@Override
public void sendInput(String name, String split, RecyclerView.Adapter DialogAdapter) {
Routine_name = name;
Routine_split = split;
adapter = DialogAdapter;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.exercise_routine_fragment, container, false);
//Report that this fragment would like to participate in populating the options menu by
//receiving a call to onCreateOptionsMenu(Menu, MenuInflater) and related methods.
//If true, the fragment has menu items to contribute.
setHasOptionsMenu(true);
recyclerView = view.findViewById(R.id.ExerciseRoutine_Recycler);
//BuildRecyclerView();
//recyclerView.setHasFixedSize(true); //If the Recyclerview is static
/*Routine_information.add(new ExerciseRoutine_Information(Routine_name, Routine_split));
recyclerView = view.findViewById(R.id.ExerciseRoutine_Recycler);
//recyclerView.setHasFixedSize(true); //If the Recyclerview is static
layoutManager = new LinearLayoutManager(getActivity());
adapter = new ExerciseRoutineAdapter(Routine_information);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);*/
return view;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.exercise_routine_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.action_addRoutine:
ExerciseRoutine_Dialog routineDialog = new ExerciseRoutine_Dialog();
routineDialog.setTargetFragment(ExerciseRoutine.this, 1);
routineDialog.show(getFragmentManager(), "Routine Dialog");
//Routine_information.add(new ExerciseRoutine_Information(Routine_name, Routine_split));
BuildRecyclerView();
//adapter.notifyItemInserted(Routine_information.size());
//if(!Routine_name.equals("") && !Routine_split.equals("")) {
//}
}
return super.onOptionsItemSelected(item);
}
public void BuildRecyclerView(){
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
public void BuildAdapter(){
//adapter = new ExerciseRoutineAdapter(getContext(),Routine_information);
adapter.notifyItemInserted(Routine_information.size());
}
}
我的对话框片段:
public class ExerciseRoutine_Dialog extends DialogFragment{
private TextView ActionOK, ActionCANCEL;
private EditText Routine_name, Routine_split;
private RoutineDialogListener activityCommander;
private ArrayList<ExerciseRoutine_Information> Routine_information = new ArrayList<>();
private RecyclerView.Adapter adapter;
public interface RoutineDialogListener{
void sendInput(String name, String split, RecyclerView.Adapter DialogAdapter);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try{
activityCommander = (RoutineDialogListener) getTargetFragment();
}catch(ClassCastException e){
throw new ClassCastException(context.toString() + "Must Implement RoutineDialogListener");
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.exercise_routine_dialog, container, false);
Routine_name = view.findViewById(R.id.ExerciseRoutine_DialogNameInput);
Routine_split = view.findViewById(R.id.ExerciseRoutine_DialogSplitInput);
ActionOK = view.findViewById(R.id.ExerciseRoutine_DialogAction_OK);
ActionCANCEL = view.findViewById(R.id.ExerciseRoutine_DialogAction_CANCEL);
//recyclerView = view.findViewById(R.id.ExerciseRoutine_Recycler);
ActionCANCEL.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getDialog().dismiss();
}
});
ActionOK.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String name = Routine_name.getText().toString();
String split = Routine_split.getText().toString();
if(!name.equals("") && !split.equals("")) {
Routine_information.add(new ExerciseRoutine_Information(name, split));
adapter = new ExerciseRoutineAdapter(getContext(), Routine_information);
activityCommander.sendInput(name, split, adapter);
adapter.notifyItemInserted(Routine_information.size());
}
getDialog().dismiss();
}
});
return view;
}
}
答案 0 :(得分:1)
您当前的方法似乎是将RecyclerView.Adapter
传递给DialogFragment
,然后尝试在现场插入新数据。我认为这是一个有问题的设置。该对话框的目的是为用户提供一些输入所需数据,时段的方法。不应将其与管理RecyclerView
或其Adapter
一起工作,因为那样一来,您的组件将非常紧密地耦合在一起:
想象一下,首先在实现中使用ListView
,然后突然有人决定从应用中禁止每个ListView
(也许出于性能原因),然后将它们全部换成{{1} } s。然后,您的方法将迫使您更改RecyclerView
的代码(它必须迎合其他类型的DialogFragment
)。松散耦合的实现将使您能够更改一个组件,而不必重写太多其他组件。
这就是为什么我不会尝试让您的代码按原样工作的原因,而是想向您展示另一种方式:
由于Adapter
是RecyclerView
的用户界面的一部分,因此Fragment
是与管理Fragment
相关的代码所属的地方。基本上可以将RecyclerView
作为Adapter
的内部类,但是如果代码更长一点,并且因为它强制执行“去耦”,我更喜欢将其作为独立类。 / p>
接口在良好的体系结构中起着非常重要的作用,因此Fragment
仍将使用接口来发送其数据。但这取决于实际实现该接口的类(此处为DialogFragment
),以便将该数据传递给任何感兴趣的第三方,例如Fragment
(RecyclerView.Adapter
可以具有自己的界面来发布重要事件,例如点击列表项)。
话虽如此,下面是一些代码片段:
Adapter
DialogFragment
public class ExerciseRoutine_Dialog extends DialogFragment {
private EditText Routine_name, Routine_split;
public interface RoutineDialogListener{
/**
* There is some new ExerciseRoutine_Information
*/
void sendInput(String name, String split);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.exercise_routine_dialog, container, false);
Routine_name = view.findViewById(R.id.ExerciseRoutine_DialogNameInput);
Routine_split = view.findViewById(R.id.ExerciseRoutine_DialogSplitInput);
TextView actionOK = view.findViewById(R.id.ExerciseRoutine_DialogAction_OK);
TextView actionCANCEL = view.findViewById(R.id.ExerciseRoutine_DialogAction_CANCEL);
actionCANCEL.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getDialog().dismiss();
}
});
actionOK.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String name = Routine_name.getText().toString();
String split = Routine_split.getText().toString();
if(!name.equals("") && !split.equals("")) {
// just send the input to the main Fragment
RoutineDialogListener listener = getListener();
if(listener != null) {
listener.sendInput(name, split);
}
}
getDialog().dismiss();
}
});
return view;
}
/**
* Tries to find a suitable listener, examining first the hosting Fragment (if any) and then the Activity.
* Will return null if this fails
* @return x
*/
private RoutineDialogListener getListener(){
RoutineDialogListener listener;
try{
Fragment onInputSelected_Fragment = getTargetFragment();
if (onInputSelected_Fragment != null){
listener = (RoutineDialogListener) onInputSelected_Fragment;
}
else {
Activity onInputSelected_Activity = getActivity();
listener = (RoutineDialogListener) onInputSelected_Activity;
}
return listener;
}catch(ClassCastException e){
Log.e("Custom Dialog", "onAttach: ClassCastException: " + e.getMessage());
}
return null;
}
}
:
Fragment