Reputation: 1159
I have a problem passing arguments down to the fragment from my main activity. getArguments method returns null but at the same time the fragment displays the arguments I'm trying to pass but in a different position. I'm sure it has to do with the container I'm replacing on the replace method.
My main activity:
public class MainActivity extends AppCompatActivity {
private final String FRAGMENT_TAG = "fragment_tag";
public static final String USER_NAME = "userName";
public static final String USER_PASSWORD = "userPassword";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
User user = getIntent().getParcelableExtra(LoginActivityFragment.SERVER_MESSAGE);
Bundle bundle = new Bundle();
bundle.putString(USER_NAME, user.getUser_name());
bundle.putString(USER_PASSWORD, user.getUser_password());
if (user != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
MainActivityFragment fragment = (MainActivityFragment) getSupportFragmentManager()
.findFragmentByTag(FRAGMENT_TAG);
if (fragment != null) {
ft.replace(android.R.id.content, fragment);
ft.commit();
} else {
MainActivityFragment newFragment = new MainActivityFragment();
ft.replace(android.R.id.content, newFragment, FRAGMENT_TAG);
newFragment.setArguments(bundle);
ft.commit();
}
}
}
}
My MainActivityFragment:
public class MainActivityFragment extends Fragment {
private final String ERROR = "Error";
public MainActivityFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
TextView username = (TextView) rootView.findViewById(R.id.username_test);
TextView password = (TextView) rootView.findViewById(R.id.pass_test);
Bundle bundle = getArguments();
try {
username.setText(bundle.getString(MainActivity.USER_NAME));
password.setText(bundle.getString(MainActivity.USER_PASSWORD));
} catch (Exception e) {
Log.e(ERROR, "Error: " + e.getMessage());
}
return rootView;
}
}
MainActivity Layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.msc.ebla.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay">
<SearchView
android:layout_width="match_parent"
android:layout_height="wrap_content">
</SearchView>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
content_main Layout
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment"
android:name="com.msc.ebla.MainActivityFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:layout="@layout/fragment_main" />
MainActivityFragment Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.msc.ebla.MainActivityFragment"
tools:showIn="@layout/activity_main">
<TextView
android:id="@+id/username_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="user"/>
<TextView
android:id="@+id/pass_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="pass"/>
<ListView
android:id="@android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
And here is a screenshot of the emulator when I'm passing testName and testPass as arguments:
Upvotes: 0
Views: 1486
Reputation: 8231
It looks as though you are loading two Fragment
s - one static, one dynamic. The static Fragment
you declare in xml
, and in this one getArguments()
will always return null
. The dynamic Fragment
however should not.
I'd suggest you only use dynamic fragments. Replace:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment"
android:name="com.msc.ebla.MainActivityFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:layout="@layout/fragment_main" />
With
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:layout="@layout/fragment_main" />
And in your MainActivity
, replace any reference to android.R.id.content
with R.id.fragment_container
Edit:
By the way, I'd recommend using the newInstance()
method to pass arguments to your Fragment
s as it's more reliable. Add this method declaration to MainActivityFragment
:
public static MainActivityFragment newInstance(String userName, String userPassword) {
Bundle args = new Bundle();
args.putString(USER_NAME_KEY, userName);
args.putString(USER_PASSWORD_KEY, userPassword);
MainActivityFragment frag = new MainActivityFragment();
frag.setArguments(args);
return frag;
}
And instead of using new MainActivityFragment()
to create a new instance, use MainActivityFragment.newInstance("user_name", "user_password)
. There's a bit more info on it here
Upvotes: 2
Reputation: 2683
You should set argument BEFORE calling replace() and commit(). So, change the code to something like this:
MainActivityFragment newFragment = new MainActivityFragment();
newFragment.setArguments(bundle);
ft.replace(android.R.id.content, newFragment, FRAGMENT_TAG);
ft.commit();
Your content_main Layout is on the same level as AppBar layout. You have to put it **inside AppBar layout.**Like this:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay">
<SearchView
android:layout_width="match_parent"
android:layout_height="wrap_content">
</SearchView>
</android.support.v7.widget.Toolbar>
<include layout="@layout/content_main" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
Upvotes: 0