如何初始化接口实例以与父片段内的子片段进行通信

时间:2017-09-21 09:01:56

标签: java android android-fragments

美好的一天,我有一个名为MainFragment的片段,来自MainActivity。在MainFragment内部,我有私人OnProgressUpdateListener progressListener;此界面实例可帮助我与ProgressDialog片段进行对话。

我能够在我的活动中初始化接口实例,但是当我尝试初始化ClassCastException中的接口实例时,我得到MainFragment

以下是我的课程:

--------------------------------------------------------------------------------
Interface
--------------------------------------------------------------------------------

public interface OnProgressUpdateListener
{
    void onProgressUpdate(String message);

    void onDismissDialog();
}

--------------------------------------------------------------------------------
Child Fragment to MainFragment
--------------------------------------------------------------------------------

public class ProgressbarDialog extends DialogFragment implements OnProgressUpdateListener
{
    TextView progressMessage;

    ProgressBar progressBar;

    View dialogView;

    LayoutInflater inflater;

    AlertDialog alertDialog;

    AlertDialog.Builder dialogBuilder;

    public ProgressbarDialog()
    {
    }

    public static ProgressbarDialog newInstance(String title, String message)
    {
        ProgressbarDialog fragment = new ProgressbarDialog();

        Bundle args = new Bundle();

        args.putCharSequence("title", title);

        args.putCharSequence("message", message);

        fragment.setArguments(args);

        return fragment;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        dialogBuilder = new AlertDialog.Builder(getActivity());

        inflater = getActivity().getLayoutInflater();

        dialogView = inflater.inflate(R.layout.content_progressdialog,null);

        dialogBuilder.setView(dialogView);

        progressBar = dialogView.findViewById(R.id.pbProgressSpinner);

        progressMessage = dialogView.findViewById(R.id.tvProgressMessage);

        dialogBuilder.setTitle(getArguments().getString("title"));

        progressBar.setIndeterminate(true);

        progressMessage.setText(getArguments().getString("message"));

        alertDialog = dialogBuilder.create();

        alertDialog.setCanceledOnTouchOutside(false);

        alertDialog.show();

        return alertDialog;
    }

    @Override
    public void onProgressUpdate(String message)
    {
        progressMessage.setText(message);
    }

    @Override
    public void onDismissDialog()
    {
        alertDialog.dismiss();
    }
}

--------------------------------------------------------------------------------
MainFragment - Parent Fragment To ProgressbarDialog
--------------------------------------------------------------------------------

public class MainFragment extends Fragment
{
    private View mainView;

    private CheckBox rememberMe;

    private boolean stayLoggedIn;

    private CountDownLatch latch;

    private FragmentManager manager;

    private OnMainListener mListener;

    private EditText email, password;

    private ProgressbarDialog progressDialog;

    private OnProgressUpdateListener progressListener;

    private final int REGISTER_CODE = 1, RESET_CODE = 2;

    private FloatingActionButton fabRegister, fabLogin, fabReset;

    public MainFragment()
    {}

    public static MainFragment newInstance()
    {
        MainFragment fragment = new MainFragment();

        Bundle args = new Bundle();

        fragment.setArguments(args);

        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        if (getArguments() != null)
        {}

        manager = getChildFragmentManager();

        progressDialog = ProgressbarDialog.newInstance("Authentication", "Connecting To Server, Please Wait...");
    }

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

        stayLoggedIn = false;

        rememberMe = mainView.findViewById(R.id.cbRememberMe);

        email = mainView.findViewById(R.id.edtLoginEmail);

        password = mainView.findViewById(R.id.edtLoginPassword);

        fabRegister = mainView.findViewById(R.id.fabRegister);

        fabLogin = mainView.findViewById(R.id.fabLogin);

        fabReset = mainView.findViewById(R.id.fabReset);

        return mainView;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
    {
        super.onViewCreated(view, savedInstanceState);

        email.setTag("Account Email Required!");

        password.setTag("Account Password Required!");
    }

    @Override
    public void onStart()
    {
        super.onStart();

        rememberMe.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

                stayLoggedIn = b;
            }
        });

        fabRegister.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                mListener.onFABInteraction(REGISTER_CODE);
            }
        });

        fabLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view)
            {
                onLoginRequest();
            }
        });

        fabReset.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view)
            {
                mListener.onFABInteraction(RESET_CODE);
            }
        });

    }

    @Override
    public void onAttach(Context context)
    {
        super.onAttach(context);

        try
        {
            if (context instanceof OnMainListener)
            {
                mListener = (OnMainListener) context;
            }
            else
            {
                throw new RuntimeException(context.toString()
                        + " must implement OnMainListener");
            }
        }
        catch (Exception e)
        {
            Log.e(MainFragment.class.getName(), e.getMessage());
        }
    }

    **@Override
    public void onAttachFragment(Fragment childFragment) {
        super.onAttachFragment(childFragment);
        if(childFragment instanceof OnProgressUpdateListener)
        {
            progressListener = (OnProgressUpdateListener) childFragment;

//This code is never executed
        }
    }**

    @Override
    public void onDetach()
    {
        super.onDetach();

        mListener = null;
    }

    interface OnMainListener
    {
        void onLoginSuccess(BackendlessUser user);

        void onFABInteraction(int option);
    }

    private class OnAuthentication extends AsyncTask<String, String, BackendlessUser>
    {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            latch = new CountDownLatch(1);

            progressDialog.show(manager, MainFragment.class.getName());

代码失败,抛出空指针异常,因为没有初始化progressListener接口实例。

progressListener.onProgressUpdate("Authenticating User, Please Wait...");
        }

        @Override
        protected void onProgressUpdate(String... values)
        {
            super.onProgressUpdate(values);

            progressListener.onProgressUpdate(values[0]);
        }

        @Override
        protected BackendlessUser doInBackground(String... strings)
        {
            try
            {
                Backendless.UserService.login(
                        Utility.getText(email),
                        Utility.getText(password),
                        onLoginCallback, stayLoggedIn);

                publishProgress("Validating Credentials, Please Wait...");

                latch.await();
            }
            catch (InterruptedException e)
            {
                publishProgress(e.getMessage());
            }

            return Utility.loginUser;
        }

        @Override
        protected void onPostExecute(BackendlessUser user)
        {
            super.onPostExecute(user);

            Utility.clearViews(email, password, rememberMe);

            progressListener.onDismissDialog();

            if(user != null)
            {
                if(((MainActivity)getActivity()).onRoleValidation(user))
                {
                    mListener.onLoginSuccess(user);
                }
                else
                {
                    //send a push notification to master channel

                    Utility.sendNotification(getActivity(),
                            "New Application User",
                            "New Registration",
                            "New User Awaiting Role Assignment", "Master",
                            "Role Assignment Pending For User :"
                                    + user.getEmail()
                                    + ":" + user.getProperty("name").toString()
                                    + " " + user.getProperty("surname").toString());
                }
            }
        }
    }

    private void onLoginRequest()
    {
        if(Utility.hasText(email, password))
        {
            if(Utility.isEmailValid(Utility.getText(email)))
            {
                new OnAuthentication().
                        execute(Utility.getText(email),
                                Utility.getText(password));
            }
            else
            {
                Utility.showToast(getActivity(), "Invalid Email");

                Utility.clearViews(email);
            }
        }
    }

    private AsyncCallback<BackendlessUser> onLoginCallback = new AsyncCallback<BackendlessUser>()
    {
        @Override
        public void handleResponse(BackendlessUser backendlessUser)
        {
            latch.countDown();

            Utility.loginUser = backendlessUser;

            Log.i(MainFragment.class.getName(), "Login Successful!\n" + backendlessUser.getUserId());
        }

        @Override
        public void handleFault(BackendlessFault backendlessFault)
        {
            latch.countDown();

            progressListener.onProgressUpdate("Login Unsuccessful!");

            Log.e(MainFragment.class.getName(), "Login Failed!\n" + backendlessFault.getMessage());
        }
    };
}

0 个答案:

没有答案