I'm new in android. I have a navigation drawer where i used recyclerview for the item. I have three tabs representing three fragments in a viewpager. My problem is that i can not open a fragment by clicking recycler view item. And another problem is that I tried FragmentTransaction but don't know how to get the fragment id. Please help me i'm stuck on it.You can give me any tutorial link.
Here is my code...
In my recyclerview adapter i have tried:
public void onBindViewHolder(MyViewHandler holder, int position) {
final Information current = data.get(position);
holder.title.setText(current.title);
holder.icon.setImageResource(current.iconId);
holder.title.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
fragmentJump(current);
}
});
}
private void fragmentJump(Information mItemSelected) {
mFragment = new FragmentIncome();
mBundle = new Bundle();
mBundle.putParcelable("item_selected_key", mItemSelected);// here my Information class is not parcelable how to solve it?
mFragment.setArguments(mBundle);
switchContent(R.id.frag1, mFragment);/// Here how to get the fragment id in R.id.frag1 of viewpager
}
public void switchContent(int id, Fragment fragment) {
if (mContext == null)
return;
if (mContext instanceof MainActivity) {
MainActivity mainActivity = (MainActivity) mContext;
Fragment frag = fragment;
mainActivity.switchContent(id, frag);
}
}
And in the MainActivity i have created this method:
public void switchContent(int id, Fragment fragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(id, fragment, fragment.toString());
ft.addToBackStack(null);
ft.commit();
}
I have followed this link how to open a different fragment on recyclerview OnClick
You can do this by using interface callback when a recyclerview item is clicked:
You could do this:
class NavdrawerRecyclerAdapter extends RecyclerView.Adapter<> {
private OnFragmentInteractionListener mListener;
public NavdrawerRecyclerAdapter(OnFragmentInteractionListener listener){
mListner = listner;
}
//call and pass position inside onClick
public void onRecyclerItemClicked(int pos){
mListener.openFragment(pos);
}
public interface OnFragmentInteractionListener{
public void openFragment(int pos);
}}
Now your mainactivity which has tablayouts implement this interface.
public class MainActivity extends AppCompatActivity implements NavdrawerRecyclerAdapter.OnFragmentInteractionListener{
NavdrawerRecyclerAdapter adapter = new NavdrawerRecyclerAdapter(this);
#override
openFragment(int position){
TabLayout.Tab tab = tabLayout.getTabAt(position);
tab.select();
}
}
Try it and tell me if this works.
Related
This one is a bit hard to explain and demonstrate. I will try my best.
I have two fragments ItemListFragment and ItemViewFragment : a fragment with a recycleview and listing inside the recycleview and a fragment displaying a single item respectively.
In the ItemListFragment, there is RecyclerViewClickListener to handle clicks on items of the list.
The implementation is as followed:
public class ItemListFragment extends Fragment {
private OnFragmentListClickListener onClickListener = null;
public interface OnFragmentListClickListener {
void OnFragmentListClick(ItemModel Item);
}
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
class RecyclerViewClickListenerImpl implements RecyclerViewClickListener {
#Override
public void onClick(View view, int position) {
if (onClickListener != null) {
onClickListener.OnFragmentListClick(adapter.getItem(position));
}
}
adapter = new ItemListAdapter(getActivity(), ItemModelList, new RecyclerViewClickListenerImpl());
mRecyclerView = getActivity().findViewById(R.id.recycler_view);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setAdapter(adapter);
.
.
.
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
Toast.makeText(getActivity(), "onAttach", Toast.LENGTH_SHORT).show();
if (context instanceof OnFragmentListClickListener) {
onClickListener = (OnFragmentListClickListener) context;
}
}
.
.
.
}
The list contains thumbnail (loaded with Glide) and a text for each time.
When I add this fragment in my activity implementing the ItemListFragment.OnFragmentListClickListener interface, everything works fine using the code below:
public class MainActivity extends AppCompatActivity
implements ItemListFragment.OnFragmentListClickListener {
.
.
.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ItemListFragment fragment_list = ItemListFragment.newInstance();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment_list);
fragmentTransaction.commit();
}
#Override
public void OnFragmentListClick(CameraModel camera) {
// handle the list click
}
.
.
.
}
Things get weird when I try to add a second fragment (ItemViewFragment) in my activity as followed:
When there is a second fragment, the RecyclerViewClickListener's onClick on the ItemListFragment is not called anymore:
class RecyclerViewClickListenerImpl implements RecyclerViewClickListener {
#Override
public void onClick(View view, int position) {
if (onClickListener != null) {
onClickListener.OnFragmentListClick(adapter.getItem(position));
}
}
Also, certain thmbnails in the ItemListFragment stopped working when a second fragment has been added in the activity.
This is a weird one... I tried using fragmentTransaction.add instead of fragmentTransaction.add also and all kind of combinations...
You want put your onClick in item of recycle view. You should do every thing of item (like: load image, make event for view,... ) in ViewHolder class. Beacause that's easier to view source code in your activity or fragment. You can references my ViewHolder class with this link. It will help you.
I'm trying to make an app where I've a RecyclerView with the options to remove the objects and add random numbers. What I'm trying to do is show a fragment when any member of the recycler view list is clicked. I'm getting the error " java.lang.IllegalStateException: Activity has been destroyed".
I'm pretty shure I'm doing something very wrong.
What I tried to do is putting a call to the change fragment method on my AnimalsAdapter class. I'm letting the code below and a github link.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.berna.recyclerviewtp2, PID: 18705
java.lang.IllegalStateException: Activity has been destroyed
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2114)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:683)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:637)
at com.example.berna.recyclerviewtp2.MainActivity.changeFragment(MainActivity.java:148)
at com.example.berna.recyclerviewtp2.AnimalsAdapter$1.onClick(AnimalsAdapter.java:81)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
My Code Main class changeFragment:
public void changeFragment(View view){
Fragment fragment;
FragmentOne fragmentOne = new FragmentOne();
fragment = fragmentOne;
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment,fragment);
ft.addToBackStack(null);
ft.commit();
FragmentOne class code:
public class FragmentOne extends Fragment {
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstaceState){
//Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank,container,false);
}
}
Click Listener code:
// Set a click listener for TextView
holder.mTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new MainActivity().changeFragment(view);
//String animal = mDataSet.get(position);
//Toast.makeText(mContext,animal,Toast.LENGTH_SHORT).show();
}
});
What I have to do to achieve the fragment when pressing the recyclerview member?
Original code I'm using to try what I'm trying
Github link for complete project
You should never instantiate your activity this way: new MainActivity().changeFragment(view);, it will never initialise properly. So it's either you delegate the listener, or find another work around for the callback.
For example, create an interface for callback:
interface ItemClickListener {
void onItemClick(View v);
}
Let your MainActivity implements the interface:
public class MainActivity extends Activity implements ItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
mAdapter = new AnimalsAdapter(mContext, animalsList, this);
// ...
}
#Override
public void onItemClick(View view) {
changeFragment(view);
}
}
Then allow your adapter to take ItemClickListener as a parameter:
private ItemClickListener callback;
public AnimalAdapter(Context context, List<String> data, ItemClickListener callback) {
this.callback = callback;
And let your holder.mTextView to forward the callback (back to activity):
holder.mTextView.setOnClickListener(callback::onItemClick);
You should create fragment after activity created, that is a basic knowledge about activity life cycle.
holder.mTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(your_current_activity, MainActivity.class);
intent.putExtras(extras);
startActivity(intent);
}
});
then replace fragment in onCreate() of MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_activity_layout);
changeFragment(null); //because we don't using parameter view
}
If you have any problem else, please comment below.
You need two changes in your code.
1. Create an interface for click listener.
2. If you want to replace fragment then you need one more Layout in XML
We solve the first issue.
1. Create an interface for click listener.
Below are some change you need to do in your adapter,
Create Interface in your adapter
public interface RecyclerItemInteraction {
void onChangeFragmentClick();
}
The second change will pass this interface.
Deeclare gloabal variable
private RecyclerItemInteraction mInteraction;
public AnimalsAdapter(Context context,List list,RecyclerItemInteraction interaction){
mDataSet = list;
mContext = context;
mInteraction = interaction;
}
Replace this below line
new MainActivity().changeFragment(view); : Remove it
if (mInteraction!=null)mInteraction.onChangeFragmentClick(); add this line.
Now Go to your MainActivity and add below line
mAdapter = new AnimalsAdapter(mContext, animalsList,this);
You can see that add third parameter this.
Now override this method and enjoy your day.
#Override
public void onChangeFragmentClick() {
Fragment fragment;
FragmentOne fragmentOne = new FragmentOne();
fragment = fragmentOne;
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container,fragment);
ft.addToBackStack(null);
ft.commit();
}
If you want to replace fragment then you need one more Layout in XML
Add this line to your main_activity.xml layout.
I am using a SlidingTabLayout to implement the sliding tabs. The problem is, when backing from a fragment to the tab fragment, it disappears.
I am going to show the application flow to make things more clear.
First, I call an Activity whithin a Fragment:
public class ScreenSlidePageFragment extends Fragment{
...
public View onCreateView(args...){
...
gridView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
switch(position){
case 0:
Intent intent = new Intent(getActivity(), FrequencyActivity.class);
startActivity(intent);
break;
}
}
}
...
}
}
The code of the FrequencyActivity is below:
public class FrequencyActivity extends AppCompatActivity{
...
protected void onCreate(Bundle savedInstance){
...
toolbar.setNavigationOnClickListener(new OnClickListener(){
#Override
public void onClick(View view){
onBackPressed();
}
});
}
final FragmentManager fm = getSupportFragmentManager();
Fragment fragment = Fragment.instantiate(getBaseContext(), "com.example.Fragment.FragmentFrequency");
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.home, fragment, "FragFrequency");
fragmentTransaction.addToBackStack("frequency");
fragmentTransaction.commit();
fm.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
finish(); //When there is no back stack, finish the activity
} else {
//Testing purpose
int top = fm.getBackStackEntryCount();
Log.d("BACKSTACK", "Backstack count: " + String.valueOf(top));
Log.d("BACKSTACK", "Backstack name: " + fm.getBackStackEntryAt(top - 1).getName());
}
}
});
}
The FragmentFrequency is the one which contains the SlidingTabLayout, the code can be seen below:
public class FragmentFrequency extends Fragment{
...
//Creates ViewPager adapter
adapter = new ViewPagerAdapter(activity.getSupportFragmentManager(), titles, numOfTabs);
//ViewPager
viewPager = (ViewPager) layout.findViewById(R.id.pager);
viewPager.setAdapter(adapter);
//SlidingTabLayout code
...
}
And finally, the ViewPagerAdapter which loads the Fragments of the tabs
public class ViewPagerAdapter extends FragmentStatePagerAdapter{
...
#Override
public Fragment getItem(int position){
if(position == 0)
return new FragmentTab1();
else
return new FragmentTab2();
}
...
}
For example when the first tab is selected, the FragmentTab1 is loaded, which contains:
Fragment f = Fragment.instantiate(getActivity(), "com.example.Fragment.FragmentLaunchingFrequency");
FragmentTransaction tx = getActivity().getSupportFragmentManager().beginTransaction();
tx.replace(R.id.home, f, "FragLaunchingFrequency");
tx.addToBackStack("launchingfrequency");
tx.commit();
The problem is, when the back action is done, the FrequencyActivity loses the reference of the Fragment and it shows a blank. Also, the sliding tabs stop working properly.
Does anyone know how to fix this? I am really out of alternatives.
Thanks
I think you have 2 major questions in your post. Perhaps make another post for the other question.
For now, I can address your question "The problem is, when the back action is done, the FrequencyActivity loses the reference of the Fragment and it shows a blank".
Your code:
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.home, fragment, "FragFrequency");
fragmentTransaction.addToBackStack("frequency");
fragmentTransaction.commit();
fm.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
...
Notes:
You cannot call addToBackStack() and use OnBackStackChangedListener() in the same FragmentManager. This seems complicated.
Code suggestions:
Remove the use of addOnBackStackChangedListener() and see what happens.
Specific code suggestion:
fm.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
finish(); //When there is no back stack, finish the activity
} else {
// Call FragmentManager.findFragmentByTag(String tag)
// Call FragmentTransaction.show() after getting the Fragment.
}
}
});
Note: Notice the else block manages the Fragment instead of depending on the BackStack (addToBackStack method).
I understand that this is quite a common issue, and I have referred to many different other questions but I still can't get this to work.
My activity implements a view pager with two tabs and in each tab is a listview. I have a adapter for my view pager which links the two fragments and in each fragment, a adapter to link the data to the listview.
In my activity menu, I have a menu which creates an edittext in an alertdialog for me to input new fields into one of the listview in one of the fragment.
My activity (contains a viewpager)
protected void onCreate(Bundle savedInstanceState)
{
...
subAdapter = new SubAdapter(getSupportFragmentManager(), data);
((ViewPager) findViewById(R.id.viewPager)).setAdapter(subGroupAdapter);
}
My viewpager adapter
public class SubAdapter extends FragmentPagerAdapter
{
public SubGroupAdapter(FragmentManager fm, data data)
{
super(fm);
}
#Override
public Fragment getItem(int position)
{
Bundle bundle = new Bundle();
bundle.putString("data", data);
switch (position)
{
case 0:
Fragment1 frag1 = new Fragment1();
frag1.setArguments(bundle);
return frag1;
case 1:
Fragment2 frag2 = new Fragment2();
frag2.setArguments(bundle);
return frag2;
}
return null;
}//some other methods below
Fragment1 / Fragment2 (both fragments have a listview)
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
frag1Adapter = new frag1Adapter(this, data);
((ListView) getView().findViewById(R.id.listView)).setAdapter(frag1Adapter);
}
Custom listview adapter for both listviews in both fragments
public class ExpenseAdapter extends BaseAdapter implements OnClickListener
{ ... }
As I mentioned earlier, I can input a new entry into either listview from the activity action bar button. However, the listview does not get updated and I can't reference the listview adapter to call notifydatasetchanged() from the activity.
What is the best way I can proceed from here onwards? thank you so much!
I have tried exploring using interfaces, tags but can't get it to work currently.
What you should do is create a public method for your Fragment1 and Fragment2 like so:
define in your Activity:
Fragment1 frag1;
Fragment2 frag2;
then your ViewPager:
public class SubAdapter extends FragmentPagerAdapter
{
public SubGroupAdapter(FragmentManager fm, data data)
{
super(fm);
}
#Override
public Fragment getItem(int position)
{
Bundle bundle = new Bundle();
bundle.putString("data", data);
switch (position)
{
case 0:
frag1 = new Fragment1();
frag1.setArguments(bundle);
return frag1;
case 1:
frag2 = new Fragment2();
frag2.setArguments(bundle);
return frag2;
}
return null;
}
}
Put this method in Fragment1.java :
public void updateFragment1ListView(){
if(adapter != null){
adapter.notifyDataSetChanged();
}
}
and from your activity call:
if(frag1 != null){
frag1.updateFragment1ListView();
}
obviously change the names for your adapter if its not called adapter...
Just do the same for Fragment2.java as well
I would recommend creating an interface. Here's an Example:
public interface UpdateListFragmentInterface {
void updateList();
}
Then in the Activity, add the delegate as a property:
UpdateListFragmentInterface yourDelegate;
Wherever you create the Fragment within the Activity, assign the Fragment as the delegate:
// Set up and create your fragment.
(if yourFragment instanceof UpdateListFragmentInterface) {
yourDelegate = yourFragment;
}
Then in the Fragment, implement the interface:
public class YourListFragment extends android.support.v4.app.ListFragment implements UpdateListFragmentInterface {
// Constructors and other methods for the ListFragment up here.
// Override the interface method
public void updateList() {
//Update the list here.
}
}
Then finally, from within your Activity, when you need to update the list, simply call the delegate:
yourDelegate.updateList();
EDIT:
Sorry, I think you actually need to create a public method in your activity that is something like:
public void setUpdateListFragmentDelegate(UpdateListFragmentDelegate delegate) {
this.delegate = delegate
}
Then in the on attach of the List Fragment you will assign it there:
if (context instance of YourActivity) {
((YourActivity)context.setUpdateListFragmentDelegate(this);
}
I have a Fragment FR1 that contains several Nested Fragments; FRa, FRb, FRc. These Nested Fragments are changed by pressing Buttons on FR1's layout. Each of the Nested Fragments have several input fields within them; which include things like EditTexts, NumberPickers, and Spinners. When my user goes through and fills in all the values for the Nested Fragments, FR1 (the parent fragment) has a submit button.
How can I then, retrieve my values from my Nested Fragments and bring them into FR1.
All Views are declared and programmatically handled within each Nested Fragment.
The parent Fragment, FR1 handles the transaction of the Nested Fragments.
I hope this question is clear enough and I am not sure if code is necessary to post but if someone feels otherwise I can do so.
EDIT 1:
Here is how I add my Nested Fragments:
tempRangeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getChildFragmentManager().beginTransaction()
.add(R.id.settings_fragment_tertiary_nest, tempFrag)
.commit();
}
});
scheduleButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getChildFragmentManager().beginTransaction()
.add(R.id.settings_fragment_tertiary_nest, scheduleFrag)
.commit();
}
});
alertsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getChildFragmentManager().beginTransaction()
.add(R.id.settings_fragment_tertiary_nest, alertsFrag)
.commit();
}
});
submitProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
constructNewProfile();
}
});
where my constructNewProfile() method needs the values from my Nested Fragments.
public Fragment tempFrag = fragment_profile_settings_temperature
.newInstance();
public Fragment scheduleFrag= fragment_profile_settings_schedules
.newInstance();
public Fragment alertsFrag = fragment_profile_settings_alerts
.newInstance();
The above refers to the fields of the parent fragment; and how they are initially instantiated.
The best way is use an interface:
Declare an interface in the nest fragment
// Container Activity or Fragment must implement this interface
public interface OnPlayerSelectionSetListener
{
public void onPlayerSelectionSet(List<Player> players_ist);
}
Attach the interface to parent fragment
// In the child fragment.
public void onAttachToParentFragment(Fragment fragment)
{
try
{
mOnPlayerSelectionSetListener = (OnPlayerSelectionSetListener)fragment;
}
catch (ClassCastException e)
{
throw new ClassCastException(
fragment.toString() + " must implement OnPlayerSelectionSetListener");
}
}
#Override
public void onCreate(Bundle savedInstanceState)
{
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
onAttachToParentFragment(getParentFragment());
// ...
}
Call the listener on button click.
// In the child fragment.
#Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.tv_submit:
if (mOnPlayerSelectionSetListener != null)
{
mOnPlayerSelectionSetListener.onPlayerSelectionSet(selectedPlayers);
}
break;
}
}
Have your parent fragment implement the interface.
public class Fragment_Parent extends Fragment implements Nested_Fragment.OnPlayerSelectionSetListener
{
// ...
#Override
public void onPlayerSelectionSet(final List<Player> players_list)
{
FragmentManager fragmentManager = getChildFragmentManager();
SomeOtherNestFrag someOtherNestFrag = (SomeOtherNestFrag)fragmentManager.findFragmentByTag("Some fragment tag");
//Tag of your fragment which you should use when you add
if(someOtherNestFrag != null)
{
// your some other frag need to provide some data back based on views.
SomeData somedata = someOtherNestFrag.getSomeData();
// it can be a string, or int, or some custom java object.
}
}
}
Add Tag when you do fragment transaction so you can look it up afterward to call its method. FragmentTransaction
This is the proper way to handle communication between fragment and nest fragment, it's almost the same for activity and fragment.
http://developer.android.com/guide/components/fragments.html#EventCallbacks
There is actually another official way, it's using activity result, but this one is good enough and common.
Instead of using interface, you can call the child fragment through below:
( (YourFragmentName) getParentFragment() ).yourMethodName();
The best way to pass data between fragments is using Interface. Here's what you need to do:
In you nested fragment:
public interface OnDataPass {
public void OnDataPass(int i);
}
OnDataPass dataPasser;
#Override
public void onAttach(Activity a) {
super.onAttach(a);
dataPasser = (OnDataPass) a;
}
public void passData(int i) {
dataPasser.OnDataPass(i);
}
In your parent fragment:
public class Fragment_Parent extends Fragment implements OnDataPass {
...
#Override
public void OnDataPass(int i) {
this.input = i;
}
btnOk.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("0");
((Fragment_Fr1) fragment).passData();
}
}
}
You can use share data between fragments.
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getSelected().observe(this, item -> {
// Update the UI.
});
}
}
More Info ViewModel Architecture
You can use getChildFragmentManager() and find nested fragments, get them and run some methods to retrieve input values
Check for instanceOf before getting parent fragment which is better:
if (getParentFragment() instanceof ParentFragmentName) {
getParentFragment().Your_parent_fragment_method();
}
Passing data between fragments can be done with FragmentManager. Starting with Fragment 1.3.0-alpha04, we can use setFragmentResultListener() and setFragmentResult() API to share data between fragments.
Official Documentation
Too late to ans bt i can suggest create EditText object in child fragment
EditText tx;
in Oncreateview Initialize it. then create another class for bridge like
public class bridge{
public static EditText text = null;
}
Now in parent fragment get its refrence.
EditText childedtx = bridge.text;
now on click method get value
onclick(view v){
childedtx.getText().tostring();
}
Tested in my project and its work like charm.