问题
:)
I'm having a problem with opening another fragment from an existing fragment in a master detail view in Android. I've tried various solutions, but nothing helped. I have a listview as a menu, where I can click on different items. By clicking on them, the right fragment will be opened. In one special fragment, I want to implement a button which should replace the existing fragment with another one, but this doesn't work. I've added a toast to see if the onclick method works, it does work, just the fragment switch won't do his job. Can anyone please help me or give me any hints, I'm about to freak out soon! :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();
}
});
This is the error message I get:
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)
Thanks in advance for any help!
edit -> the whole code: package 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;
}
}
回答1:
Use getChildFragmentManager()
instead of getFragmentManager
回答2:
i have found the answer on my own:
in the mainActivity i add a reference
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();
}
in the LoginFragment i add this function:
@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;
}
and the button looks like this:
btnLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mCallbacks.onItemSelected("dashboard");
}
});
来源:https://stackoverflow.com/questions/27269683/opening-a-fragment-in-an-existing-fragment-master-detail-design