Android Studio-从菜单项中的对话框片段更新RecyclerView

时间:2018-06-23 19:28:26

标签: android android-studio android-fragments android-recyclerview dialog

嘿,我真的需要您的帮助。我花了大约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;
}
}

1 个答案:

答案 0 :(得分:1)

您当前的方法似乎是将RecyclerView.Adapter传递给DialogFragment,然后尝试在现场插入新数据。我认为这是一个有问题的设置。该对话框的目的是为用户提供一些输入所需数据,时段的方法。不应将其与管理RecyclerView或其Adapter一起工作,因为那样一来,您的组件将非常紧密地耦合在一起:

想象一下,首先在实现中使用ListView,然后突然有人决定从应用中禁止每个ListView(也许出于性能原因),然后将它们全部换成{{1} } s。然后,您的方法将迫使您更改RecyclerView的代码(它必须迎合其他类型的DialogFragment)。松散耦合的实现将使您能够更改一个组件,而不必重写太多其他组件。

这就是为什么我不会尝试让您的代码按原样工作的原因,而是想向您展示另一种方式:

由于AdapterRecyclerView的用户界面的一部分,因此Fragment是与管理Fragment相关的代码所属的地方。基本上可以将RecyclerView作为Adapter的内部类,但是如果代码更长一点,并且因为它强制执行“去耦”,我更喜欢将其作为独立类。 / p>

接口在良好的体系结构中起着非常重要的作用,因此Fragment仍将使用接口来发送其数据。但这取决于实际实现该接口的类(此处为DialogFragment),以便将该数据传递给任何感兴趣的第三方,例如FragmentRecyclerView.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