【问题标题】:Error launching activity from fragment android从片段android启动活动时出错
【发布时间】:2017-02-22 01:04:01
【问题描述】:

我的 MainActivity 中有 3 个片段,我想从 MainActivity 中的片段之一切换到 Activity2,但我的尝试总是失败。当我按下第三个片段中的“确定”按钮将我连接到 Activity2 时,我的应用程序崩溃了。我正在编写在一个教程中找到的代码。先感谢您!

public class ProfileFragment extends Fragment implements View.OnClickListener {

    private TextView tv_name,tv_email,tv_message;
    private SharedPreferences pref;
    private AppCompatButton btn_change_password,btn_logout, btn_ok;
    private EditText et_old_password,et_new_password;
    private AlertDialog dialog;
    private ProgressBar progress;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_profile,container,false);
        initViews(view);
        return view;

    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {

        pref = getActivity().getPreferences(0);
        tv_name.setText("Здравей, "+pref.getString(Constants.NAME,"")+"!");
        tv_email.setText(pref.getString(Constants.EMAIL,""));
        btn_ok=(AppCompatButton)view.findViewById(R.id.btn_ok);
        btn_ok.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(getActivity(),activity2.class);
                startActivity(intent);
            }
        });



    }

    private void initViews(View view){

        tv_name = (TextView)view.findViewById(R.id.tv_name);
        tv_email = (TextView)view.findViewById(R.id.tv_email);
        btn_change_password = (AppCompatButton)view.findViewById(R.id.btn_chg_password);
        btn_logout = (AppCompatButton)view.findViewById(R.id.btn_logout);
        btn_ok=(AppCompatButton)view.findViewById(R.id.btn_ok);
        btn_change_password.setOnClickListener(this);
        btn_logout.setOnClickListener(this);


    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){

            case R.id.btn_chg_password:
                showDialog(); //I deleted this method from the code, it doesnt have a lot in common with my question
                break;
            case R.id.btn_logout:
                logout();
                break;
}

    private void logout() {
        SharedPreferences.Editor editor = pref.edit();
        editor.putBoolean(Constants.IS_LOGGED_IN,false);
        editor.putString(Constants.EMAIL,"");
        editor.putString(Constants.NAME,"");
        editor.putString(Constants.UNIQUE_ID,"");
        editor.apply();
        goToLogin();
    }

    private void goToLogin(){

        Fragment login = new LoginFragment();
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.replace(R.id.fragment_frame,login);
        ft.commit();
    }


}

【问题讨论】:

  • 你得到什么错误,你在清单中声明了activity2吗?
  • 你能显示 R.layout.fragment_profile 吗?
  • 你的片段已经实现了 onclick 监听器在开关条件下添加这个case R.id.btn_logout: Intent intent=new Intent(getActivity(),activity2.class); startActivity(intent); break;

标签: android android-layout android-studio android-fragments android-activity


【解决方案1】:

在 startActivity() 之前添加 getActivity 作为上下文 还要添加 NewTask 标志。

Intent intent = new Intent(getActivity(), activity2.class);
intent.addflags(intent.flag_activity_new_task);
getActivity().startActivity(intent);

【讨论】:

  • @Victoria 所以发送错误日志可能还有其他崩溃的原因。
  • 谢谢你,我设法找到了我的错误,它不在你的代码中,它在 activity2.class 中,一切正常 :)
【解决方案2】:

您无法在片段中调用方法goToLogin(),您需要在包含此片段的活动中调用,因为您的片段不包含布局fragment_frame,它在您的活动中。

如果您想在片段中调用此方法,请将方法 goToLogin() 移动到 yourActivity 并像这样在片段中调用:

if(getActivity() instanceOf yourActivity) {
       ((youActivity) getActivity()).goToLogin();
}

【讨论】:

    【解决方案3】:

    该错误可能是因为您没有在 AndroidManifest.xml 中注册 Activity2。

    但是要从 FragmentActivity 进行通信,您应该使用 MainActivity 作为它的入口。虽然它看起来有点矫枉过正,但它会减轻您未来更大项目的维护。

    您可以为此使用界面

    在您的 ProfileFragment 中定义并创建一个接口:

    public class ProfileFragment extends Fragment implements View.OnClickListener {
    
        OnProfileListener mCallback;
    
        // Container Activity must implement this interface
        public interface OnProfileListener {
            public void onProfileButtonOkClicked();
        }
    
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
    
            // This makes sure that the container activity has implemented
            // the callback interface. If not, it throws an exception
            try {
                mCallback = (OnProfileListener) activity;
            } catch (ClassCastException e) {
                throw new ClassCastException(activity.toString()
                        + " must implement OnProfileListener");
            }
        }
    
        ...
        ...
    }
    

    然后在你的按钮点击方法中调用接口:

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        ...
        btn_ok=(AppCompatButton)view.findViewById(R.id.btn_ok);
        btn_ok.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCallback.onProfileButtonOkClicked();
            }
        });
        ...
    }
    

    最后,您需要实现 MainActivity 的接口:

    public static class MainActivity extends Activity
            implements ProfileFragment.OnProfileListener{
        ...
    
        // When button ok in ProfileFragment clicked, this method will be called.
        public void onProfileButtonOkClicked() {
            // we can call the Activity here now.
            Intent intent=new Intent(this, activity2.class);
            startActivity(intent);
        }
    }
    

    更多详情,请阅读Communicating with Other Fragments


    更新

    对于 API 级别 >= 23 中已弃用的 onAttach(),您可以改用以下代码:

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnProfileListener) {
            mCallback = (OnProfileListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnProfileListener");
        }
    }
    

    【讨论】:

    • 它说 onAttach 在我使用 Activity 时已被弃用。当我尝试使用 Context 时,我的应用程序在启动时崩溃可能是因为它是 API16,而 Context 需要 API23。我完全困惑了......请帮帮我
    • @Victoria:我已经更新了代码。 android 团队在 API 级别 >= 23 中已弃用 onAttach() 方法。
    • 谢谢,但我终于设法解决了这个问题,方法是在 Intent intent = new Intent(getActivity(), Activity2.class); 中使用 getActivity() 而不是 this
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 2016-07-07
    • 1970-01-01
    • 2016-10-30
    相关资源
    最近更新 更多