I have a main home activity which consists of 3 tabs at the bottom of the screen.
Inside this activity I have a fragment.
This fragment contains a view pager. This view pager is used to navigate between 2 activities:
1.Exercise Form = This displays a video for the exercise.
2.Exercise History = This shows all of the users recorded data on the exercise.
To obtain the exercise form video as well as the exercise history, I need to be able to access the ExerciseName from ProgressFagment2 (The text at the top of the screen) and pass this to the 2 child fragments (ExerciseHomeVideoFragment and ExerciseHistoryFragment)
How can I access the exerciseName in the child fragments?
ProgressFragment2 (Fragment Inside Activity)
public class Progress_Fragment2 extends Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.exercises_history_demo, container, false);
}
public void onViewCreated(View view, Bundle savedInstanceState) {
childExerciseName = getArguments().getString("ExerciseName");
TextView title_tv = getView().findViewById(R.id.textView_exerciseName8);
title_tv.setText(childExerciseName);
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());
// Set up the ViewPager with the sections adapter.
ViewPager mViewPager = (ViewPager) getView().findViewById(R.id.view_pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) getView().findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.top_navigation_two, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new ExerciseHomeVideoFragment();
break;
case 1:
fragment = new ExerciseHistoryFragment();
break;
}
return fragment;
}
#Override
public int getCount() {
// Show 2 total pages.
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Exercise Form";
case 1:
return "Exercise History";
}
return null;
}
}
}
ExerciseHomeVideoFragment (One of the 2 fragments inside viewPager) |Relevant code only
public class ExerciseHomeVideoFragment extends Fragment implements View.OnClickListener {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_exercise_info_home_version, container, false);
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void onViewCreated(View view, Bundle savedInstanceState) {
Progress_Fragment2 parentFrag = ((Progress_Fragment2)ExerciseHomeVideoFragment.this.getParentFragment());
youTubeBtn = getView().findViewById(R.id.youTubeSearchButton);
parent_tv = getView().findViewById(R.id.textView_exerciseName8);
childExerciseViewModel = ViewModelProviders.of(this).get(ChildExerciseViewModel.class);
//
// HOW CAN I ACCESS THE CHILDEXERCISE NAME???
//
// childExerciseName = getArguments().getString("ExerciseName"); // THIS DOESNT WORK
// exerciseNameTV.setText(childExerciseName + " Demo");
}
}
you can send data using Interface, set argument or newInstance
in your tab fragment
switch (position) {
case 0:
fragment = new ExerciseHomeVideoFragment().newInstance(childExerciseName);
break;
case 1:
fragment = new ExerciseHomeVideoFragment();
break;
}
ExerciseHomeVideoFragment
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class ExerciseHomeVideoFragment extends Fragment {
public static ExerciseHomeVideoFragment newInstance(String ExerciseName) {
Bundle args = new Bundle();
args.putString("ExerciseName", ExerciseName);
ExerciseHomeVideoFragment fragment = new ExerciseHomeVideoFragment();
fragment.setArguments(args);
return fragment;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_exercise_info_home_version, container, false);
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void onViewCreated(View view, Bundle savedInstanceState) {
TextView title_tv = getView().findViewById(R.id.textView_exerciseName8);
//
Bundle bundle = getArguments();
if(bundle!=null)
{
title_tv.setText(bundle.getString("ExerciseName"));
}
}
}
you can send model also, but the model should be implemented using Serializer
switch (position) {
case 0:
fragment = new ExerciseHomeVideoFragment().newInstance(childExerciseViewModel);
break;
case 1:
fragment = new ExerciseHomeVideoFragment();
break;
}
in fragment
public static ExerciseHomeVideoFragment newInstance(String ExerciseName,ChildExerciseViewModel childExerciseViewModel) {
Bundle args = new Bundle();
args.putString("ExerciseName", ExerciseName);
args.putSerializable("model", childExerciseViewModel);
ExerciseHomeVideoFragment fragment = new ExerciseHomeVideoFragment();
fragment.setArguments(args);
return fragment;
}
Bundle bundle = getArguments();
if(bundle!=null)
{
title_tv.setText(bundle.getString("ExerciseName"));
ChildExerciseViewModel model = (ChildExerciseViewModel) bundle.getSerializable("model");
title_tv.setText(model.gettourExerciseText());
}
I think it's a good idea to use better architecture. for example if you use a singleton class to store your data you will be able to use them without passing to the fragment. search about singleton.
Android has a new feature that has been released 3 months later. you can use setFragmentResultListener.
here is the documentation:
https://developer.android.com/reference/androidx/fragment/app/FragmentManager#setfragmentresultlistener
Related
I am trying to refresh the current fragment in the tabbed layout of my viewpager. I have one fragment (UserProgressFragment) that creates the ViewPager and sets the adapter (UserProgressAdapter) along with creating tabbed layout.
In my UserProgressAdapter, in the getItem() method I am returning two other fragments, (UserWeightTrackerFragment and UserCalorieCounterFragment) based on which tab i am on.
My issue is how do i refresh the fragment and update its content/view from the UserCalorieCounterFragment on a button click, because access to the viewpager and adapter are set in the UserProgressFragment? I have considered notifyDataChange for the adapter but i dont know how to call this from this class as it is set up on the UserProgressFragment class. The purpose of wanting to refresh this page is to update a specific view which is a chart, if context is needed.
I have attached the code below:
UserProgressFragment
public class UserProgressFragment extends Fragment{
public static UserProgressFragment newInstance() {
return new UserProgressFragment();
}
public UserProgressFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_user_progress, container, false);
ViewPager viewPager = view.findViewById(R.id.progress_viewpager);
viewPager.setAdapter(new UserProgressTabsAdapter(getChildFragmentManager()));
TabLayout tabLayout = view.findViewById(R.id.progress_sliding_tabs);
tabLayout.setupWithViewPager(viewPager, true);
return view;
}
}
UserProgressTabsAdapter
public class UserProgressTabsAdapter extends FragmentStatePagerAdapter {
private static final int PAGE_COUNT = 2;
private String tabTitles[] = new String[]{"Weight Tracker", "Calorie Counter"};
public UserProgressTabsAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return UserWeightTrackerFragment.newInstance(position);
case 1:
return UserCalorieCounterFragment.newInstance(position + 1);
}
return null;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
UserCalorieCounterFragment (need to refresh this one)
public class UserCalorieCounterFragment extends Fragment implements View.OnClickListener, AdapterView.OnItemSelectedListener {
public static final String ARG_PAGE = "ARG_PAGE";
public static UserCalorieCounterFragment newInstance(int page) {
Bundle args = new Bundle();
args.putInt(ARG_PAGE, page);
UserCalorieCounterFragment fragment = new UserCalorieCounterFragment();
fragment.setArguments(args);
return fragment;
}
public UserCalorieCounterFragment() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int mPage = getArguments().getInt(ARG_PAGE);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_user_calorie_counter, container, false);
Button mAddCalories = view.findViewById(R.id.btn_add_calorie);
mAddCalories.setOnClickListener(this);
return view;
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_add_calorie:
//REFRESH/UPDATE HERE
break;
}
}
You can create a public method in your fragment which contains the view pager which will contain the notifyDataSetChanged() function. And in the view pager fragment/item, you can call getParentFragment() and type cast it to your parent/first fragment and access that public method to notifyDataSetChanged().
Hello friends im developing android app with fragments in a viewpager but now i want to parse JSON data into the fragment.my question is how can i set number of fragments as the size of json data and insert the json data into the required fragment.please help me ive been searching for it on internet for hours but disappointment results so please help me.Thanks in advance!.
[{"c_id":13,"category_name":"PUBLICATIONS","imagename":"http://goringr.com/church_project/churchimagesnew/publications.jpg","ctype":"church"},{"c_id":14,"category_name":"YOUTH ASSOCIATION","imagename":"http://goringr.com/church_project/churchimagesnew/youthassociation.jpg","ctype":"church"}]
this is my json data and all i want is to display contents of object with c_id=13 in first fragment and display contents of object with c_id=14 in second fragment.
MainActivity.java
package project1.test;
import android.content.Intent;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
public static final String data = "hello";
FragmentPagerAdapter adapterViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Toolbar tool = (Toolbar)findViewById(R.id.tool);
// setSupportActionBar(tool);
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ViewPager vpPager = (ViewPager) findViewById(R.id.vpPager);
adapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
vpPager.setAdapter(adapterViewPager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.sample_actions, menu);
return true;
}
public static class MyPagerAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 3;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FirstFragment.newInstance(0, "Fragment1");
case 1:
return FirstFragment.newInstance(1, "Fragment2");
case 2:
return SecondFragment.newInstance(2, "Fragment3");
default:
return null;
}
}
// Returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
}
FirstFragment
public class FirstFragment extends Fragment {
// Store instance variables
private String title;
private int page;
// newInstance constructor for creating fragment with arguments
public static FirstFragment newInstance(int page, String title) {
FirstFragment fragmentFirst = new FirstFragment();
Bundle args = new Bundle();
args.putInt("someInt", page);
args.putString("someTitle", title);
fragmentFirst.setArguments(args);
return fragmentFirst;
}
// Store instance variables based on arguments passed
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
page = getArguments().getInt("someInt", 0);
title = getArguments().getString("someTitle");
}
// Inflate the view for the fragment based on layout XML
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
;
View view = inflater.inflate(R.layout.fragment_first, container, false);
// TextView tvLabel = (TextView) view.findViewById(R.id.tvLabel);
//// tvLabel.setText(page + " -- " + title);
CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout)view.findViewById(R.id.collapsing_toolbar1);
collapsingToolbarLayout.setTitle("black panther");
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Add your menu entries here
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.sample_actions, menu);
}
}
SecondFragment
public class SecondFragment extends Fragment {
// Store instance variables
private String title;
private int page;
Button tryit;
// newInstance constructor for creating fragment with arguments
public static SecondFragment newInstance(int page, String title) {
SecondFragment fragmentSecond = new SecondFragment();
Bundle args = new Bundle();
args.putInt("someInt", page);
args.putString("someTitle", title);
fragmentSecond.setArguments(args);
return fragmentSecond;
}
// Store instance variables based on arguments passed
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("someInt", 0);
title = getArguments().getString("someTitle");
}
// Inflate the view for the fragment based on layout XML
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_second, container,
false);
tryit = (Button) view.findViewById(R.id.tryit);
tryit.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(),ManagingProfile.class);
startActivity(intent);
}
});
// TextView tvLabel = (TextView) view.findViewById(R.id.tvLabel);
// tvLabel.setText(page + " -- " + title);
return view;
}
}
you can parse like this:
List<RidesData> ridesDatas; /* this is should be parcelable */
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(FragmentAbout.newInstance(ridesDatas), "ABOUT");
adapter.addFragment(FragmentPointOfInterest.newInstance(ridesDatas),"POI");
viewPager.setAdapter(adapter);
}
and set constructure to each fragment like this:
FragmentAbout.class
public static FragmentAbout newInstance(List<RidesData> ridesDatas) {
FragmentAbout fragmentAbout = new FragmentAbout();
Bundle arg = new Bundle();
arg.putParcelableArrayList("data", (ArrayList<? extends Parcelable>) ridesDatas);
fragmentAbout.setArguments(arg);
return fragmentAbout;
}
FragmentPointOfInterest.class
public static FragmentPointOfInterest newInstance(List<RidesData> ridesDatas) {
FragmentPointOfInterest fragmentPointOfInterest = new FragmentPointOfInterest();
Bundle arg = new Bundle();
arg.putParcelableArrayList("data", (ArrayList<? extends Parcelable>) ridesDatas);
fragmentPointOfInterest.setArguments(arg);
return fragmentPointOfInterest;
}
and get each data of json in onViewCreated() method of fragment like this:
you have 2 position of data in json.
[0] = c_id=13
[1] = c_id=14
so in first fragment set 0 position:
RidesData data = ridesData.get(0);
and in second Fragment set 1 postion:
RidesData data = ridesData.get(1);
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ridesData = new ArrayList<>();
ridesData = getArguments().getParcelableArrayList("data");
RidesData data = ridesData.get(1);
}
You have to make use of custom adapter to extract the json data and view holder to print the data.
refer this link
The idea: In my app, it has 15 lessons, each lesson containing 30 couplets a user can swipe through. And each fragment/couplet_page has inflated a layout that contains 3 text views. I'm using FragmentStatePagerAdapter.
I've learned that use switch case statements to create swipe views but the problem is, there are lots of fragments to be created and I know that there is a better solution for it that I don't know. I just wanna use one fragment and somehow change the text with setText method.
here's my one fragment object code
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class CoupletOneFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.couplet_one, container, false);
}
}
and here's the custom pager adapter
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
public class MyFragmentAdapter extends FragmentStatePagerAdapter {
public MyFragmentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new CoupletOneFragment();
case 1:
return new CoupletTwoFragment();
case 2:
return new CoupletThreeFragment();
case 3:
return new CoupletFourFragment();
case 4:
return new CoupletFiveFragment();
and so on...
default:
break;
}
return null;
}
#Override
public int getCount() {return 30;}
}
Try this way, in your state pager adapter use loop- size is number of fragments:
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
for (int i=0;i<size;i++){
adapter.addFragment(CoupletFiveFragment.newInstance(i));
}
viewPager.setAdapter(adapter);
Adapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment) {
mFragmentList.add(fragment);
}
}
Now your Fragment:
public static CoupletFiveFragment newInstance(int j) {
CoupletFiveFragment fragmentDemo = new CoupletFiveFragment();
Bundle args = new Bundle();
args.putInt("GET_LIST", j);
fragmentDemo.setArguments(args);
return fragmentDemo;
}
Get Value in Oncreate:
Int getINT=0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getINT = getArguments().getInt("GET_LIST");
}
Well I'm gonna answer my own question here
Updated fragment object code
public class FragmentChild extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
// INFLATE THE LAYOUT THAT EACH FRAGMENT OBJECT WILL HAVE, PUT IT IN A VIEW
View root = inflater.inflate(R.layout.couplets, container, false);
// RECEIVE THE BUNDLE DATA SENT (ARGUMENTS)
Bundle args = getArguments();
// CREATE AN ARRAY LIST OF STRINGS THAT WILL HOLD TEXT
ArrayList<String> someText = new ArrayList<>();
someText.add("one");
someText.add("two");
someText.add("three");
TextView txt = (TextView) root.findViewById(R.id.text_view);
txt.setText(someText.get(args.getInt("position")));
return root;
}
Updated custom pager adapter
class MyFragmentAdapter extends FragmentStatePagerAdapter {
MyFragmentAdapter(FragmentManager fm) {super(fm);}
#Override
public Fragment getItem(int position) {
Bundle args = new Bundle();
args.putInt("position", position);
Fragment fragment = new FragmentChild();
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return 3;
}
}
And finally host activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chapter_one);
// FIND THE VIEWPAGER AND SET THE CUSTOM ADAPTER TO IT TO PROVIDE CHILD PAGES
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
MyFragmentAdapter adapter = new MyFragmentAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
}
}
It was easy peasy!
I am using material design tabs as follows :
Following is my MainActivity.class :
public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabLayout = (TabLayout) findViewById(R.id.tabs);
viewPager = (ViewPager) findViewById(R.id.viewpager);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(this);
tabLayout.setupWithViewPager(viewPager);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
System.out.println("onPageSelected Called");
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
My ViewPagerAdapter is as follows :
public class ViewPagerAdapter extends FragmentPagerAdapter {
private static int count = 2;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentOne();
case 1:
return new FragmentTwo();
}
return null;
}
#Override
public int getCount() {
return count;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position)
{
case 0 :
return "Tab One";
case 1 :
return "Tab Two";
}
return null;
}
}
and here are my Fragments :
This is my first fragment name is FragmentOne :
public class FragmentOne extends Fragment {
private EditText editText;
private Button btnSendData;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("IN FRAGMENT ONE");
View view = inflater.inflate(R.layout.fragment_one,container,false);
editText = (EditText) view.findViewById(R.id.et_name);
btnSendData = (Button) view.findViewById(R.id.btn_send);
btnSendData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTwo fragment = new FragmentTwo();
Bundle bundle = new Bundle();
bundle.putString("username",editText.getText().toString());
fragment.setArguments(bundle);
getFragmentManager.beginTransaction.replace(R.id.frag_second,fragment).commit();
}
});
return view;
}
}
and here is another fragment with name FragmentTwo :
public class FragmentTwo extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("IN FRAGMENT TWO");
View view = inflater.inflate(R.layout.fragment_two,container,false);
Bundle bundle = getArguments();
if(bundle!= null)
{
String value = getArguments().getString("username");
}
return view;
}
#Override
public void onResume() {
super.onResume();
System.out.println("onResume gets called");
}
}
In the second fragment i am getting data buts its adding another view with previous one.
see the image :
so I want to pass data from FragmentOne to FragmentTwo in two scenario :
1. I want to pass the data when i click on button and
2. When I swipe to FragmentTwo data should be passed
Also when I try to swipe to FragmentTwo nothing gets called in FragmentTwo ? why is it so ?
Also when I click to second tab nothing gets called .
Please help me how should i pass data to FragmentTwo on button click ?
following are layout files:
here is fragment_one
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<EditText
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:id="#+id/et_name"
android:hint="Username"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:padding="16dp"
android:text="Send Data"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:id="#+id/btn_send"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
and second fragment , fragment_second.xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/second_frag"
android:gravity="center">
<TextView
android:textSize="24sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Fragment Two"
android:id="#+id/textView2" />
Each fragment is associated with the parent activity. so you can't directly communicate from one fragment to another fragment. You will need to go through Parent Activity using interface.
Check this docs : https://developer.android.com/training/basics/fragments/communicating.html
On button click pass the value to methods in your custom interface and access those methods in second fragment.
when I try to swipe to FragmentTwo nothing gets called in FragmentTwo
For this you need to implement fragment life cycle - https://developer.android.com/reference/android/app/Fragment.html
UPDATE
Done with some modification in you code, just look at the foll. code -
Manifex.xml
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
android:theme="#style/Theme.AppCompat.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
MainActivity.java
package com.app.onkar.tabdemo;
import android.support.v4.app.Fragment;
import android.support.design.widget.TabLayout;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = (ViewPager) findViewById(R.id.viewpager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentOne(), "ONE");
adapter.addFragment(new FragmentTwo(), "TWO");
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(this);
tabLayout.setupWithViewPager(viewPager);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
System.out.println("onPageSelected Called");
}
#Override
public void onPageScrollStateChanged(int state) {
}
public static class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
private static int count = 2;
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentOne();
case 1:
return new FragmentTwo();
}
return null;
}
#Override
public int getCount() {
return count;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Tab One";
case 1:
return "Tab Two";
}
return null;
}
}
}
FragmentOne.java
package com.app.onkar.tabdemo;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class FragmentOne extends Fragment {
private EditText editText;
private Button btnSendData;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("IN FRAGMENT ONE");
View view = inflater.inflate(R.layout.fragment_one,container,false);
editText = (EditText) view.findViewById(R.id.et_name);
btnSendData = (Button) view.findViewById(R.id.btn_send);
btnSendData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTwo fragment = new FragmentTwo();
Bundle bundle = new Bundle();
bundle.putString("username",editText.getText().toString());
fragment.setArguments(bundle);
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.second_frag,fragment).commit();
}
});
return view;
}
}
FragmentTwo.java
package com.app.onkar.tabdemo;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class FragmentTwo extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("IN FRAGMENT TWO");
View view = inflater.inflate(R.layout.fragment_two,container,false);
TextView txt2 = (TextView) view.findViewById(R.id.textView2);
Bundle bundle = getArguments();
if(bundle!= null)
{
String value = getArguments().getString("username");
txt2.setText(value);
}
return view;
}
#Override
public void onResume() {
super.onResume();
System.out.println("onResume gets called");
}
}
No change in Layout files. Just try above code - it is working exactly as you want. Hope it will help!
SCREENS
ViewPagerAdapter class
public class ViewPagerAdapter extends FragmentPagerAdapter {
private static int count = 2;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment fragmentone = new FragmentOne();
Bundle args = new Bundle();
args.putInt("code", 1);
fragmentone.setArguments(args);
return fragmentone;
break;
case 1:
Fragment fragmenttwo = new FragmentTwo();
Bundle args = new Bundle();
args.putInt("code", 2);
fragmenttwo.setArguments(args);
return fragmenttwo ;
break;
}
return null;
}
#Override
public int getCount() {
return count;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position)
{
case 0 :
return "Tab One";
case 1 :
return "Tab Two";
}
return null;
}
}
args is the bundle object, you can put String int and other values to use these values in fragment use below code in onCreateView method of Fragment.
int codeForthisFragment = getArguments().getInt("code");
for button click:
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment secondFragment = new FragmentTwo();
Bundle args = new Bundle();
args.putInt("code", 2);
secondFragment.setArguments(args);
ft.replace(R.id.content_frame, secondFragment);
ft.commit();
In the second fragment i am getting data buts its adding another view with previous one. see the image
With reference to the answer by #Roy Miller(https://stackoverflow.com/users/5255021/roy-miller),
you can solve it by doing the follwing changes:
In MainActivity.java ,replace the follwing switch:
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentOne();
case 1:
return new FragmentTwo();
}
return null;
}
With:
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return mFragmentList.get(0);
case 1:
return mFragmentList.get(1);
case 2:
return mFragmentList.get(2);
default:
return null;
}
}
And then, in FragmentOne.java
Replace this:
btnSendData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTwo fragment = new FragmentTwo();
Bundle bundle = new Bundle();
bundle.putString("username",editText.getText().toString());
fragment.setArguments(bundle);
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.second_frag,fragment).commit();
}
});
With:
btnSendData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*This one FragmentCollection is a Singleton class that contains list of fragments, set it during initialization itself(code is attached below this code)*/
FragmentCollection fragmentCollection=FragmentCollection.getInstance();
FragmentTwo fragment = (FragmentTwo) FragmentCollection.getmFragmentList().get(2); //getting the second fragment
fragment.setText(editText.getText().toString()); //add this method in fragment two
}
});
Now inside FragmentTwo.java
Add the method:
public void updateTextView(String data){
Log.d("TabTwo","Update Text view");
TextView txt = (TextView)view.findViewById(R.id.textView2);
txt.setText(data);
}
At last, the singleton class i mentioned above:
public class FragmentCollection {
static FragmentCollection fragmentCollection=new FragmentCollection();
private final List<Fragment> mFragmentList = new ArrayList<>();
private FragmentCollection(){}
public static FragmentCollection getInstance(){
if(fragmentCollection!=null) {
return fragmentCollection;
}else {
return new FragmentCollection();
}
}
public void setmFragmentList(List<Fragment> mFragmentList){
this.mFragmentList.addAll(mFragmentList);
}
public List<Fragment> getmFragmentList(){
return mFragmentList;
}
}
The issue of getting older views overlapping is because of initializing the fragment again and again
like new FragmentTwo(); in more than one place.
So here we put it in a list and access it so only a single fragment is altered.
I am not able to go to first fragment from Second fragment . I am using tab layout
This is my code
By clicking button from 2nd Fragment
Bundle bundle = new Bundle();
bundle.putString("uniqueList1", uniqueList.get(0));
bundle.putString("uniqueList2", uniqueList.get(1));
bundle.putString("kycUniquesNo", kycUniqueNum);
CustBasicFormFragement fragObj = new CustBasicFormFragement();
fragObj.setArguments(bundle);
In 1st Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding = DataBindingUtil.inflate(inflater, R.layout.cust_basic_form_fragment, container, false);
view = binding.getRoot();
if (getArguments() != null) {
string1 = getArguments().getString("uniqueList1");
string2 = getArguments().getString("uniqueList2");
kycUnique=getArguments().getString("kycUniquesNo");
System.out.print(string1);
System.out.print(string2);
System.out.print(kycUnique);
return view;
}
i used this turtorial: http://www.paulusworld.com/technical/android-navigationdrawer-sliding-tabs#comment-2793
to get a swipe view alongside my navigation drawer, but i can't quite figure out how to change the view
in the onCreateView i'm trying to do it with a switch statement but it says "method is not overwriting method from it's superclass
code for fragment:
public class StepFragment extends Fragment {
public static final String TAG = StepFragment.class.getSimpleName();
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
public static StepFragment newInstance() {
return new StepFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.step_fragment, container, false);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getChildFragmentManager());
mViewPager = (ViewPager) v.findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
return v;
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new TabbedContentFragment();
Bundle args = new Bundle();
args.putInt(TabbedContentFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.step_title1).toUpperCase(l);
case 1:
return getString(R.string.step_title2).toUpperCase(l);
case 2:
return getString(R.string.step_title3).toUpperCase(l);
}
return null;
}
}
public static class TabbedContentFragment extends Fragment {
public static final String ARG_SECTION_NUMBER = "section_number";
public TabbedContentFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState,int position) {
View view1 = inflater.inflate(R.layout.fragment_step,
container, false);
View view2 = inflater.inflate(R.layout.fragment_step1,
container, false);
switch (position) {
case 0:
return view1;
case 1:
return view2;
}
return null;
}
}
}
Your onCreateView is passing four arguments, the superclass method only takes 3. You need to remove the position arg.
Use the args Bundle that you're setting in getItem() to pass the position. In onCreateView(), get those args and pull the position from that Bundle.
EDIT:
Here's your getItem():
#Override
public Fragment getItem(int position) {
Fragment fragment = new TabbedContentFragment();
Bundle args = new Bundle();
args.putInt(TabbedContentFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
Since your switch statement in onCreateView is looking for a 0 or 1, go ahead and remove the "+ 1" from args.putInt():
#Override
public Fragment getItem(int position) {
Fragment fragment = new TabbedContentFragment();
Bundle args = new Bundle();
args.putInt(TabbedContentFragment.ARG_SECTION_NUMBER, position);
fragment.setArguments(args);
return fragment;
}
Now, in your fragment, you need to get the args and get the position from that:
public static class TabbedContentFragment extends Fragment {
public static final String ARG_SECTION_NUMBER = "section_number";
public TabbedContentFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle args = getArguments();
int position = args.getInt(ARG_SECTION_NUMBER, 0);
View view1 = inflater.inflate(R.layout.fragment_step,
container, false);
View view2 = inflater.inflate(R.layout.fragment_step1,
container, false);
switch (position) {
case 0:
return view1;
case 1:
return view2;
}
return null;
}
}