简体   繁体   English

尚未为嵌套片段附加片段

[英]Fragment has not been attached yet for Nested fragment

I'm trying to display the bottom dialog fragment (AddNewHabit.java) when user clicked an item from the RecyclerView, but I kept getting the error that the fragment has not been attached yet.当用户从 RecyclerView 中单击一个项目时,我试图显示底部对话框片段 (AddNewHabit.java),但我一直收到该片段尚未附加的错误。 I don't know where or how should I attach it to make bottomSheetDialogFragment.show() work.我不知道应该在哪里或如何附加它以使 bottomSheetDialogFragment.show() 工作。

Logcat:日志猫:

2022-09-11 20:52:31.916 21228-21228/com.unicode.android.wodehabit E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.unicode.android.wodehabit, PID: 21228
java.lang.IllegalStateException: Fragment AddNewHabit{fdd5021} (ce46aa77-b5b3-43e6-9564-559dd68d8ad9) has not been attached yet.
    at androidx.fragment.app.Fragment.getChildFragmentManager(Fragment.java:1075)
    at com.unicode.android.wodehabit.HabitsAdapter.editHabit(HabitsAdapter.java:91)
    at com.unicode.android.wodehabit.HabitsAdapter$1.onClick(HabitsAdapter.java:50)
    at android.view.View.performClick(View.java:7448)
    at android.view.View.performClickInternal(View.java:7425)
    at android.view.View.access$3600(View.java:810)
    at android.view.View$PerformClick.run(View.java:28305)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7656)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Here's HabitsFragment:这是习惯片段:

public class HabitsFragment extends Fragment implements DialogCloseListener{
private List<HabitModel> mHabitList;
private RecyclerView mRecyclerView;
private HabitsAdapter mHabitsAdapter;
private ImageButton mAddTaskBtn;
private Spinner mDropdown;
private DataBaseHandler db;

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

public HabitsFragment() {
    // Required empty public constructor
}

/**
 * Use this factory method to create a new instance of
 * this fragment using the provided parameters.
 *
 * @param param1 Parameter 1.
 * @param param2 Parameter 2.
 * @return A new instance of fragment HabitsFragment.
 */
// TODO: Rename and change types and number of parameters
public static HabitsFragment newInstance(String param1, String param2) {
    HabitsFragment fragment = new HabitsFragment();
    Bundle args = new Bundle();
    args.putString(ARG_PARAM1, param1);
    args.putString(ARG_PARAM2, param2);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        mParam1 = getArguments().getString(ARG_PARAM1);
        mParam2 = getArguments().getString(ARG_PARAM2);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_habits, container, false);
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    db = new DataBaseHandler(getActivity());
    db.openDatabase();

    mAddTaskBtn = (ImageButton) view.findViewById(R.id.add_new_habit_btn);
    mAddTaskBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            AddNewHabit.newInstance().show(getChildFragmentManager(), AddNewHabit.TAG);
        }
    });

    mRecyclerView = (RecyclerView) view.findViewById(R.id.habit_recyclerview);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    mHabitsAdapter = new HabitsAdapter(db, getActivity());
    mRecyclerView.setAdapter(mHabitsAdapter);

    updateRecyclerView();

}

public void handleDialogClose(DialogInterface dialog){
    updateRecyclerView();
}

public void updateRecyclerView(){
    mHabitList = db.getAllHabits();
    Collections.reverse(mHabitList);
    mHabitsAdapter.setHabit(mHabitList);
    mHabitsAdapter.notifyDataSetChanged();
}
}

AddNewHabit.java:添加NewHabit.java:

public class AddNewHabit extends BottomSheetDialogFragment {
public static final String TAG = "com.unicode.android.wodehabit.action_bottom_dialog";

private EditText cueTxt, habitTxt, descriptionTxt;
private Button cancelBtn, addBtn;
private Spinner dropdown;
private DataBaseHandler db;

public static AddNewHabit newInstance() {
    return new AddNewHabit();
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(STYLE_NORMAL, R.style.DialogStyle);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.new_habit, container, false);
    //readjust bottom sheet dialog and move upward when we type something
    getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    return view;
}

//Define codes needed to execute functions in dialog fragment
@Override
public void onViewCreated(View view, Bundle saveInstanceState) {
    super.onViewCreated(view, saveInstanceState);
    cueTxt = (EditText) getView().findViewById(R.id.new_task_cue);
    habitTxt = (EditText) getView().findViewById(R.id.new_task_habit);
    descriptionTxt = (EditText) getView().findViewById(R.id.new_task_description);
    dropdown = (Spinner) getView().findViewById(R.id.new_task_preposition);
    cancelBtn = (Button) getView().findViewById(R.id.cancel_habit_button);
    addBtn = (Button) getView().findViewById(R.id.add_habit_button);

    //Spinner adapter
    String[] items = new String[]{"before", "during", "after"};
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
            android.R.layout.simple_spinner_item, items);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    dropdown.setAdapter(adapter);

    boolean isUpdate = false;

    final Bundle bundle = getArguments();
    if (bundle != null) {
        isUpdate = true;
        String cue = bundle.getString("cue");
        cueTxt.setText(cue);
        String habit = bundle.getString("habit");
        habitTxt.setText(habit);
        String description = bundle.getString("description");
        descriptionTxt.setText(description);

    }

    db = new DataBaseHandler(getActivity());
    db.openDatabase();

    cancelBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            getParentFragmentManager().beginTransaction().remove(AddNewHabit.this).commit();
        }
    });

    //final boolean finalIsUpdate = isUpdate;
    boolean finalIsUpdate = isUpdate;
    addBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String cue = cueTxt.getText().toString();
            String preposition = dropdown.getSelectedItem().toString();
            String habit = habitTxt.getText().toString();
            String description = descriptionTxt.getText().toString();
            String fullHabit = habit + " " + preposition + " " + cue;
            if(finalIsUpdate){
                db.updateHabit(bundle.getInt("id"), habit, description);
            }else{
                if (cue.isEmpty() || habit.isEmpty()) {
                    Toast.makeText(getActivity(), R.string.complete_toast, Toast.LENGTH_LONG).show();
                } else {
                    HabitModel habit1 = new HabitModel();
                    habit1.setTitle(fullHabit);
                    habit1.setDescription(description);
                    db.insertHabit(habit1);
                }
            }
            dismiss();
        }
    });
}


@Override
public void onDismiss(DialogInterface dialog){
    Activity activity = getActivity();
    if(activity instanceof DialogCloseListener){
        ((DialogCloseListener)activity).handleDialogClose(dialog);
    }
}
}

Here's HabitsAdapter.java:这是 HabitsAdapter.java:

public class HabitsAdapter extends RecyclerView.Adapter<HabitsAdapter.ViewHolder> {
private List<HabitModel> mHabitList;
private Activity mActivity;
private DataBaseHandler db;

public HabitsAdapter(DataBaseHandler db, Activity activity){
    this.db = db;
    this.mActivity = activity;
}


@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.habit_item, parent, false);

    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    db.openDatabase();

    HabitModel item = mHabitList.get(position);
    holder.mTitle.setText(item.getTitle());
    holder.mDescription.setText(item.getDescription());
    int pos = holder.getAdapterPosition();

    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            editHabit(pos);

        }
    });
}

@Override
public int getItemCount() {
    return mHabitList.size();
}

public static class ViewHolder extends RecyclerView.ViewHolder{
    TextView mTitle, mDescription;
    FloatingActionButton mFab;

    ViewHolder(View view){
        super(view);
        mTitle = (TextView) view.findViewById(R.id.habit_title);
        mDescription = (TextView) view.findViewById(R.id.habit_description);
        mFab = (FloatingActionButton) view.findViewById(R.id.check_off_button);

    }
}

public void setHabit(List<HabitModel> habitList){
    this.mHabitList = habitList;
    notifyDataSetChanged();
}

public Context getContext(){
    return mActivity;
}

public void editHabit(int position){
    HabitModel habit = mHabitList.get(position);
    Bundle bundle = new Bundle();
    bundle.putInt("id", habit.getId());
    bundle.putString("habit", habit.getTitle());
    bundle.putString("description", habit.getDescription());
    AddNewHabit fragment = new AddNewHabit();
    fragment.setArguments(bundle);
    //THE PROBLEM
    fragment.show(fragment.getChildFragmentManager(), AddNewHabit.TAG);
}

public void deleteHabit(int position){
    HabitModel habit = mHabitList.get(position);
    db.deleteHabit(habit.getId());
    mHabitList.remove(position);
    notifyItemRemoved(position);
}
}

Found the answer from https://stackoverflow.com/a/22971406/15433004https://stackoverflow.com/a/22971406/15433004找到答案

Replaced this code in HabitsAdapter:在 HabitsAdapter 中替换了这段代码:

 AddNewHabit fragment = new AddNewHabit();
 fragment.setArguments(bundle);
 fragment.show(fragment.getChildFragmentManager(), AddNewHabit.TAG);

To:至:

    FragmentActivity activity = (FragmentActivity)(getContext());
    FragmentManager fm = activity.getSupportFragmentManager();
    AddNewHabit fragment = new AddNewHabit();
    fragment.setArguments(bundle);
    fragment.show(fm, AddNewHabit.TAG);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM