在现有片段中打开片段(主细节设计)

时间:2014-12-03 10:47:17

标签: android android-fragments nullpointerexception master-detail oncreate

:)

我在Android中的主详情视图中打开现有片段中的另一个片段时遇到问题。我尝试了各种解决方案,但没有任何帮助。 我有一个listview作为菜单,我可以点击不同的项目。通过单击它们,将打开右侧片段。在一个特殊片段中,我想实现一个按钮,该按钮应该用另一个片段替换现有片段,但这不起作用。我添加了一个toast,看看onclick方法是否有效,它确实有效,只是片段开关不能完成他的工作。任何人都可以帮助我或给我任何提示,我即将惊慌失措! :d

private Button btnLogin;

btnLogin = new Button(getActivity());
btnLogin.setLayoutParams(params);
btnLogin.setText("Login");

btnLogin.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View rootView) {
            Toast toast = Toast.makeText(getActivity(), "register",
                    Toast.LENGTH_SHORT);
            toast.show();

            Fragment fragment = new FragmentApps();
            FragmentTransaction transaction = getFragmentManager()
                    .beginTransaction();

            // if(addToBack)
            transaction.addToBackStack(null);

            transaction.replace(R.id.fragment_item_detail_1, fragment).commit();
        }
    });

这是我收到的错误消息:

12-03 11:30:06.839: E/AndroidRuntime(9464): FATAL EXCEPTION: main
12-03 11:30:06.839: E/AndroidRuntime(9464): Process: at.test.app, PID: 9464
12-03 11:30:06.839: E/AndroidRuntime(9464): java.lang.NullPointerException: Attempt to invoke         virtual method 'boolean android.os.Bundle.containsKey(java.lang.String)' on a null object reference
12-03 11:30:06.839: E/AndroidRuntime(9464):     at     at.test.app.apps.FragmentApps.onCreate(FragmentApps.java:49)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at android.app.Fragment.performCreate(Fragment.java:2031)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:863)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at android.app.BackStackRecord.run(BackStackRecord.java:833)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at android.app.FragmentManagerImpl$1.run(FragmentManager.java:447)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at android.os.Handler.handleCallback(Handler.java:739)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at android.os.Handler.dispatchMessage(Handler.java:95)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at android.os.Looper.loop(Looper.java:135)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at android.app.ActivityThread.main(ActivityThread.java:5221)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at java.lang.reflect.Method.invoke(Native Method)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at java.lang.reflect.Method.invoke(Method.java:372)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
12-03 11:30:06.839: E/AndroidRuntime(9464):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

提前感谢您的帮助!

编辑 - >整个代码:     包at.test.app.login;

import android.os.Bundle;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;


/**
 * A fragment representing a single Item detail screen. This fragment is either
 * contained in a {@link ItemListActivity} in two-pane mode (on tablets) or a
 * {@link ItemDetailActivity} on handsets.
 */
public class FragmentTest extends Fragment {

    private LinearLayout linearLayout;
    private TextView sample;
    private Button btnLogin;

    /**
     * The fragment argument representing the item ID that this fragment
     * represents.
     */
    public static final String ARG_ITEM_ID = "item_id";

    /**
     * The dummy content this fragment is presenting.
     */
    private ItemContent.Item mItem;

    /**
     * Mandatory empty constructor for the fragment manager to instantiate the
     * fragment (e.g. upon screen orientation changes).
     */
    public FragmentTest() {
    }

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

        getActivity().setTitle(getResources().getString(R.string.apps_titel));

        if (getArguments().containsKey(ARG_ITEM_ID)) {
            // Load the dummy content specified by the fragment
            // arguments. In a real-world scenario, use a Loader
            // to load content from a content provider.
            mItem = ItemContent.ITEM_MAP.get(getArguments().getString(
                    ARG_ITEM_ID));
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_item_detail,
                container, false);

        linearLayout = (LinearLayout) rootView.findViewById(R.id.fragment_item_detail_1);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                android.widget.LinearLayout.LayoutParams.FILL_PARENT,
                android.widget.LinearLayout.LayoutParams.WRAP_CONTENT);
        sample = new TextView(getActivity());
        sample.setText(getResources().getString(R.string.apps_titel));

        btnLogin = new Button(getActivity());
        btnLogin.setLayoutParams(params);
        btnLogin.setText("Login");


        linearLayout.addView(sample);
        linearLayout.addView(btnLogin);

        btnLogin.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View rootView) {
                Toast toast = Toast.makeText(getActivity(), "register",
                        Toast.LENGTH_SHORT);
                toast.show();

                Fragment fragment = new FragmentApps();
                FragmentTransaction transaction = getChildFragmentManager()
                        .beginTransaction();

                // if(addToBack)
                transaction.addToBackStack(null);

                transaction.replace(R.id.fragment_item_detail_1, fragment).commit();


                // Intent i = new Intent(getActivity(),
                // FragmentRegister.class);
                // startActivity(i);
                // getActivity().finish();
            }
        });

        return rootView;
    }
}

2 个答案:

答案 0 :(得分:0)

使用getChildFragmentManager()代替getFragmentManager

答案 1 :(得分:0)

我自己找到了答案:

在mainActivity中我添加了一个引用

    private void setDetailFragment(String id, int fragmentToReplace,
        boolean addToBack) {
        Bundle arguments = new Bundle();
        arguments.putString(ItemDetailFragment.ARG_ITEM_ID, id);

        Fragment fragment = new ItemDetailFragment();
        if (id.equals("register")){
            fragment = new FragmentRegister();
        } else if (id.equals("dashboard")){
            fragment = new FragmentDashboard();
        }
        fragment.setArguments(arguments);

        FragmentTransaction transaction = getFragmentManager()
                .beginTransaction();
        transaction.addToBackStack(null);
        transaction.replace(fragmentToReplace, fragment).commit();

    }
在LoginFragment中我添加了这个函数:

     @Override
     public void onAttach(Activity activity) {
        super.onAttach(activity);

        if (!(activity instanceof Callbacks)) {
            throw new IllegalStateException(
                    "Activity must implement fragment's callbacks.");
        }

        mCallbacks = (Callbacks) activity;
     }

,按钮如下所示:

    btnLogin.setOnClickListener(new View.OnClickListener() {

        public void onClick(View view) {
            mCallbacks.onItemSelected("dashboard");
        }
    });