当前位置: 首页 > 知识库问答 >
问题:

多个活动/片段的自定义对话框界面

应瀚
2023-03-14

我是android studio的新手,我正在尝试实现一个对话框片段,以便在单击按钮或单击工具栏操作添加按钮时弹出。它将数据从对话框发送到一个片段或一个活动(试图了解它是如何为这两个对象工作的)。我的dialog类有一个接口,当我在片段中实现它时,它工作得非常好,但是活动有点不同。我使用接口将数据传递给活动,然后使用Bundle将数据从活动传输到片段。我相信错误发生在onAttach中,因为我已经获取了targetFragment();

有可能让多个活动/片段实现一个接口吗?如果是这样的话,我如何处理接口中的活动和片段、onAttach以及数据的发送?

提前感谢大家,下面是我的custom_dialog类的代码,以及一个附加到活动的片段。目标是按下片段中的按钮或活动上的工具栏来打开一个对话框,并从用户那里获得输入,该输入将被传输以显示。

错误:

Process: com.example.andrewg.dialogfragment, PID: 13335
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.andrewg.dialogfragment.MyCustomDialog$OnInputSelected.sendInput(java.lang.String)' on a null object reference
    at com.example.andrewg.dialogfragment.MyCustomDialog$2.onClick(MyCustomDialog.java:58)
    at android.view.View.performClick(View.java:6597)
    at android.view.View.performClickInternal(View.java:6574)
    at android.view.View.access$3100(View.java:778)
    at android.view.View$PerformClick.run(View.java:25881)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6649)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)

主要活动:

public class MainActivity extends AppCompatActivity implements 
MyCustomDialog.OnInputSelected{

public String dialogInput;
FragmentManager fragmentManager;

@Override
public void sendInput(String input) {
    dialogInput = input;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    fragmentManager = getSupportFragmentManager();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    //Inflate the menu, this adds items to the action bar if it is present
    getMenuInflater().inflate(R.menu.menu, menu);

    //Redundant
    MenuItem actionMenuItem = menu.findItem(R.id.action_add);
    actionMenuItem.setOnMenuItemClickListener(new 
MenuItem.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem menuItem) {
            return false;
        }
    });
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    //Handle action bar clicks here. The action bar will automatically handle clicks on the home/up button
    //so long as you specify a parent activity in AndroidManifest.xml

    switch(item.getItemId()){

        case R.id.action_add:
            MyCustomDialog dialog = new MyCustomDialog();
            dialog.show(getSupportFragmentManager(), "MyCustomDialog");

            //Trying to pass dialog input into an intent to send to the 
fragment
            /*Intent intent = new Intent(getApplicationContext(), 
MainFragment.class);
            intent.putExtra("Dialog Input", dialogInput);
            startActivity(intent);*/
            //Trying Bundle to pass data, dialog input between activity and 
fragment
            Bundle bundle = new Bundle();
            bundle.putString("Dialog Input", dialogInput);
            //Set Fragment class arguments
            MainFragment fragment = new MainFragment();
            fragment.setArguments(bundle); //set argument bundle to fragment

            fragmentManager.beginTransaction().replace(R.id.MainFragment,fragment).commit(); //now replace Mainfragment


            Toast.makeText(this, "Action_Add Clicked Successfully", 
Toast.LENGTH_SHORT).show();
    }

    return super.onOptionsItemSelected(item);
}
}

主片段:

public class MainFragment extends Fragment implements 
MyCustomDialog.OnInputSelected{

TextView InputDisplay;
Button OpenDialog;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_main, container, false);

    InputDisplay = view.findViewById(R.id.InputDisplay);
    OpenDialog = view.findViewById(R.id.Open_Dialog);

    //Getting Main Activity dialog information with Bundle, that was received from toolbar add
    Bundle bundle = getArguments();
    if(bundle != null){
        String dialogInput = bundle.toString();
        InputDisplay.setText(dialogInput);
    }
    //String dialogInput = this.getArguments().getString("Dialog Input");

    OpenDialog.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Log.d("MainFragment", "onClick: opening dialog");

            MyCustomDialog customDialog = new MyCustomDialog();
            customDialog.setTargetFragment(MainFragment.this, 1);
            customDialog.show(getFragmentManager(), "MyCustomDialog");
        }
    });

    return view;
}

@Override
public void sendInput(String input) {
    InputDisplay.setText(input);
}
}

自定义对话框:我为Nanatach的activity添加了第二个接口变量以使用getActivity(),但它似乎不正确。

public class MyCustomDialog extends DialogFragment {

private EditText Input;
private TextView ActionOK, ActionCANCEL;

public OnInputSelected onInputSelected_Fragment;
public OnInputSelected onInputSelected_Activity;

public interface OnInputSelected{
    void sendInput(String input);
}

@Override
public void onAttach(Context context) {
    try{
        onInputSelected_Fragment = (OnInputSelected) getTargetFragment();
        onInputSelected_Activity = (OnInputSelected) getActivity();
    }catch(ClassCastException e){
        Log.e("Custom Dialog", "onAttach: ClassCastException: " + e.getMessage());
    }
    super.onAttach(context);
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.dialog_my_custom, container, false);

    Input = view.findViewById(R.id.Input);
    ActionOK = view.findViewById(R.id.Action_OK);
    ActionCANCEL = view.findViewById(R.id.Action_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) {
            onInputSelected_Fragment.sendInput(Input.getText().toString());
            onInputSelected_Activity.sendInput(Input.getText().toString());

            getDialog().dismiss();
        }
    });

    return view;
}
}

共有1个答案

邵阳德
2023-03-14

有可能让多个活动/片段实现单个接口吗?

是的,它是。你只需要意识到getActive()将返回null如果DialogFrature没有附加到一个活动,而是附加到另一个片段返回null如果没有目标片段,例如,当您直接从您的活动显示对话框时,因此没有调用setTargetFrature()

由于将null转换为任何内容都不会导致异常,所以在实际调用接口方法之前,您所要做的就是在代码中进行null检查。

但是,因为您将不会有一个目标片段和一个活动显示相同的实例,您可以更改您的代码,只做一个字段

private OnInputSelected onInputSelected;

然后在onAttach()中检查哪一个是空的-活动或目标片段,并一次性正确设置onInputSelected

try{
    Fragment onInputSelected_Fragment = getTargetFragment();
    Activity onInputSelected_Activity = getActivity();
    if (onInputSelected_Fragment != null){
        onInputSelected = (OnInputSelected)onInputSelected_Fragment;
    }
    else {
        onInputSelected = (OnInputSelected)onInputSelected_Activity;
    }
    // throw RuntimeException here if onInputSelected still is null
    //
}catch(ClassCastException e){
    Log.e("Custom Dialog", "onAttach: ClassCastException: " + e.getMessage());
}

请注意,如果在显示来自片段的对话框时忘记设置目标Fragment,则onInputSelected可能为空。这将是一个编程错误,因此在这种情况下,可能需要抛出运行时异常。如果你的应用程序通过了这一点,那么你已经实现了界面,任务完成了。

在你的onClark()中,你可以简单地写

onInputSelected.sendInput(Input.getText().toString());

 类似资料:
  • 我读了DialogFragment,然后把它做成这样的一对一。 在另一个SherlockFragment中,我接下来制作: 但是doPositiveClick()、doNegativeClick()方法希望是静态的,这对我来说不好。

  • 我是初学者在android。我正在创建一个自定义对话框,它工作正常。但是这个对话框不移动。如何移动这个自定义对话框。例如在窗口中包含记事本,油漆等。当你点击这个(记事本,油漆等)标题栏你可以移动的位置。如果可能请发送信息如何移动对话框。否则如果不可能发送原因。请回复你的答案和意见是有价值的我。谢谢。

  • 本文向大家介绍Android 自定义对话框 showSetPwdDialog,包括了Android 自定义对话框 showSetPwdDialog的使用技巧和注意事项,需要的朋友参考一下 样式如下所示: 布局: layout   dialog_set_pwd.xml 状态选择器: drawable   btn_blue_selector.xml   btn_white_selector.xml 引

  • 在我的应用程序中,我使用了一个活动和两个片段。该应用程序使用带有容器的布局,因此片段是通过事务添加的。第一个片段包含列表视图,另一个片段包含列表视图项的详细视图。两个片段都使用setRetainInstance(true)。片段是通过替换事务添加的,并设置了addToBackStack(null)。列表片段包含一个实例变量,其中包含列表的一些信息。现在我正在切换到详细并按回,实例变量为null。我

  • 我是Android新手,正在开发自定义警报对话框 我想打开另一个对话框,点击编辑按钮,代码如下 但我得到了一个异常,我的日志cat输出如下 就连我的红色十字按钮也可以正常工作,我已经多次使用相同的代码用TextView显示AlertDialog,但我不知道代码出了什么问题。非常感谢您的帮助。提前谢谢。 现在我得到了我想要的,但是编辑和保存都有重叠。我想隐藏编辑(蓝色按钮)并使保存按钮清晰可见。

  • 我有一个带有的自定义对话框。在我的上,我有一个按钮,当我按下它时,对话框就会显示出来,我可以从中选择日期。我希望选定的日期显示在我的中的上。我的代码如下: 这是我的主上包含的对话框的代码: 我从中获取日、月和年,并使用 在我的片段中,我使用下面的代码调用我的对话框: 当我运行我的应用程序时,我在以下行中得到一个nullPointerException: 我做错了什么?提前致谢