How to pass Arguments to Fragment from Activity
It's hard to say without seeing the logcat, but surely you are missing to call the commit()
method on the FragmentTransaction
. Also remember to set the arguments to the fragment before calling ft.commit()
.
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
mFragment = (LayoutFragment) getSupportFragmentManager().findFragmentByTag(mTag);
if (mFragment == null) {
Bundle bundle = new Bundle();
bundle.putInt("noTiles", 4);
mFragment = (LayoutFragment) LayoutFragment.newInstance(mLayoutId);
mFragment.setArguments(bundle);
//ft.add(R.id.content, mFragment, mTag).commit();
ft.add(R.id.content, mFragment, mTag);
} else {
ft.attach(mFragment);
}
mSelectedLayoutId = mFragment.getLayoutId();
}
Passing values from Activity to Fragment
You need to create a function in your Profile fragment called newInstance that creates the fragment and set the arguments through there, then returns the fragment with the arguments. Like this
public static Profile newInstance(String name){
Profile profile = new Profile();
Bundle bundle = new Bundle();
bundle.putString("name", name);
profile.setArguments(bundle);
return profile;
}
Then create the fragment in your activity like this
Profile profile = Profile.newInstance(gname);
And get the arguments how you have been doing in the onCreate in the fragment.
You also should be creating the Fragment in the activity you are using it in. So if it's in your home activity you will want to pass the data from the login activity, then build the fragment in the onCreate for the home activity.
Intent home = new Intent(this, HomeActivity.class);
intent.putExtra("name", gname);
startActivity(home);
in the HomeActivity
Bundle extras = getIntent().getExtras();
String gname = extras.getString("name");
Profile profile = Profile.newInstance(gname);
Passing Value from Activity to Fragment
You can go many ways but given your current implementation (using a newInstance), I'd go with using your parent activity as a mediator, going like this:
1) Create a BaseFragment class which your TestFragmentOne and TestFragmentTwo will extend and in there hold a reference to your parent Activity (here named "MainActivity"):
abstract class BaseFragment : Fragment() {
lateinit var ACTIVITY: MainActivity
override fun onAttach(context: Context) {
super.onAttach(context)
ACTIVITY = context as MainActivity
}
}
2) Then, in your Activity make sure you declare your variable as a field:
class MainActivity : AppCompatActivity() {
var textVariable = "This to be read from the fragments"
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
textVariable = "I can also change this text"
...
}
}
3) Then, from each fragment you can access your variable using the instance inherited from your BaseFragment:
class TestFragmentOne : BaseFragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val incomingText = ACTIVITY.textVariable
println("Incoming text: "+incomingText)
// You can also set the value of this variable to be read from
// another fragment later
ACTIVITY.textVariable = "Text set from TestFragmentOne"
}
}
Send data from activity to fragment in Android
From Activity you send data with intent as:
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
and in Fragment onCreateView method:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
How do I pass the variables of an activity to the fragments of a BottomNavigationView?
There is no direct access to HomeFragment from MainActivity in your case. BottomNavigation uses nested navigation architecture pattern with nested graphs.
More details here: Passing argument(s) to a nested Navigation architecture component graph
But you can use alternative way to pass data from Activity to Fragment using context.
Step 1 - Describe HomeFragmentData model:
data class HomeFragmentData(
val value: String
)
Step 2 - Describe HomeFragment interface:
interface IHomeFragment {
fun getHomeFragmentData(): HomeFragmentData
}
Step 3 - Implement interface to your Activity:
class MainActivity : AppCompatActivity(), IHomeFragment {
override fun getHomeFragmentData(): HomeFragmentData {
return HomeFragmentData(
value = "Home Fragment data"
)
}
// Rest of your code
}
Step 4 - Call function getHomeFragmentData() from HomeFragment using context:
class HomeFragment : Fragment() {
private var interactionListener: IHomeFragment? = null
override fun onAttach(context: Context) {
super.onAttach(context)
when(context) {
is IHomeFragment -> {
interactionListener = context
}
else -> throw RuntimeException("$context has to implement IHomeFragment")
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val root = inflater.inflate(R.layout.fragment_home, container, false)
val textView: TextView = root.findViewById(R.id.text_home)
interactionListener?.getHomeFragmentData().let {
textView.text = it?.value
}
return root
}
}
How to pass and get value from fragment and activity
Here is the Android Studio proposed solution (= when you create a Blank-Fragment with File -> New -> Fragment -> Fragment(Blank) and you check "include fragment factory methods").
Put this in your Fragment:
class MyFragment: Fragment {
...
companion object {
@JvmStatic
fun newInstance(isMyBoolean: Boolean) = MyFragment().apply {
arguments = Bundle().apply {
putBoolean("REPLACE WITH A STRING CONSTANT", isMyBoolean)
}
}
}
}
.apply
is a nice trick to set data when an object is created, or as they state here:
Calls the specified function [block] with
this
value as its receiver
and returnsthis
value.
Then in your Activity or Fragment do:
val fragment = MyFragment.newInstance(false)
... // transaction stuff happening here
and read the Arguments in your Fragment such as:
private var isMyBoolean = false
override fun onAttach(context: Context?) {
super.onAttach(context)
arguments?.getBoolean("REPLACE WITH A STRING CONSTANT")?.let {
isMyBoolean = it
}
}
Enjoy the magic of Kotlin!
Related Topics
How to Programmatically Tell If a Bluetooth Device Is Connected
How to Sign Android App With System Signature
How to Open the "Front Camera" on the Android Platform
Android Camera: Data Intent Returns Null
Android - How to Disable the Click of Home Button
How to Add a Fragment to an Activity with a Programmatically Created Content View
How to Start Genymotion Device
How to Add Stacktrace or Debug Option When Building Android Studio Project
How to Programmatically Add Views to Views
How to Make a Phone Call in Android and Come Back to My Activity When the Call Is Done
How to Find Serial Number of Android Device
How to Handle Dynamic Json in Retrofit
Open Application After Clicking on Notification
Error "The Connection to Adb Is Down, and a Severe Error Has Occurred."