I have created a FragmentActivity of 2 tabs. This is a very basic Tab example from Android Developer tutorial using FragmentActivity and FragmentPagerAdapter Code Here
public class FragmentPagerSupport extends FragmentActivity implements
ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
static final int NUM_ITEMS = 10;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_pager);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
...........
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
Bundle args = new Bundle();
switch (position) {
case 0:
fragment = new Fragment01();
args.putInt(Fragment01.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
break;
case 1:
fragment = new Fragment02();
args.putInt(Fragment02.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
break;
return fragment;
}
}
Then I have created 2 different fragments for 2 tabs:
public static class Fragment01 extends Fragment {
private EditText mName;
private EditText mEmail1;
public static final String ARG_SECTION_NUMBER = "2";
public Fragment01() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_customer_add, container, false);
mName = (EditText) v.findViewById(R.id.customer_add_name);
mEmail = (EditText) v.findViewById(R.id.customer_add_email);
View confirmButton = v.findViewById(R.id.customer_add_button);
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
......................
}
});
}
}
Now in the 2nd tab I need to show the input value of Name and Email from 1st tab and on confirm from 2nd tab need to save in database. But here I stuck. I am not getting an idea how I can keep data from first tab? Please help.
One approach could be to use Singleton DP. There will be only one object having Name, Email etc. as fields. Set Name and Email fields using setters when you are in first fragment and access them using getters in second fragment.
On confirm, you can insert entire object into database.
Related
Intro
Hi guys, currently I am working on a question-form app. In the MainActivity users can add an item after which a QuestionListActivity opens. Clicking on the first item in that list opens the Main2Activity. This activity exists of 3 fragments which all include one question (Edittext). The data implemented by the user in the fragments is saveable. After answering and saving questions, each form appears in the MainActivity as a list. Clicking on these items brings them back to the QuestionListActivity after which clicking on the first item should open the fragments again with their saved data already shown.
Problem
After saving the fragments, the string to the MainActivity is succesfull, eg. the Title as set by saving the first fragment (which asks for the name of the form). Therefore, the saving to my Utilities class was succesfull. The problem is, clicking on a saved item in the MainActivity and then on the first item in the QuestionList to open the Main2Activity (fragments with questions), opens the fragments but with empty EditText fields where the saved data should be shown to view them or make changes.
Question
How is it possible to show the saved data inside multiple fragments instead of in just one activity and what am I doing wrong? And is it recommended to use the same format when using 8 questions (one fragment per question)?
(I couldn't find the right question to use on StackOverFlow, because almost every question about this subject is about the instance state ed. but this isn't a problem in my project)
Codes
Here is my Main2Activity and one fragment(Frag1). The other fragment I have setup the same way as Frag1. I am probably doing something wrong in the fragment java classes but I am unsure what. Hopefully, someone can help me.
public class Main2Activity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private String mNoteFileName;
private Note mLoadedNote;
private EditText title, question2, question3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
title = findViewById(R.id.note_et_title1);
question2 = findViewById(R.id.note_et_question2);
question3 = findViewById(R.id.note_et_question3);
String title;
String question2 ;
String question3;
mNoteFileName = getIntent().getStringExtra("NOTE_FILE");
if(mNoteFileName !=null && !mNoteFileName.isEmpty()) {
mLoadedNote = Utilities.getNoteByName(this, mNoteFileName);
if(mLoadedNote !=null) {
title = mLoadedNote.getTitle();
question2 = mLoadedNote.getQuestion2();
question3 = mLoadedNote.getQuestion3();
}
}
List<Fragment> fragments = new ArrayList<>();
fragments.add(Frag1.newInstance(title));
fragments.add(Frag2.newInstance(question2));
fragments.add(Frag3.newInstance(question3));
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(),fragments);
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_note_new, menu);
return true;
}
private void saveNote() {
Note note;
if(title.getText().toString().trim().isEmpty()){
Toast.makeText(this, "Please enter a title", Toast.LENGTH_SHORT).show();
}
if(mLoadedNote ==null) {
note = new Note(System.currentTimeMillis(), title.getText().toString(), question2.getText().toString(), question3.getText().toString());
}else {
note = new Note(mLoadedNote.getDateTime(), title.getText().toString(), question2.getText().toString(), question3.getText().toString());
}
if (Utilities.saveNote(this, note)){
Toast.makeText(this, "saved", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "not enough space", Toast.LENGTH_SHORT).show();
}
finish();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_note_save:
saveNote();
break;
}
return true;
}
public static class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main2, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragments;
public SectionsPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
mFragments = fragments;
}
#Override
public Fragment getItem(final int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
}
}
public class Frag1 extends Fragment {
private static final String EXTRA_TEXT = "text";
private EditText mEtTitle;
public static Frag1 newInstance(String message) {
Bundle args = new Bundle();
args.putString(EXTRA_TEXT, message);
Frag1 fragment = new Frag1();
fragment.setArguments(args);
return fragment;
}
public Frag1 () {
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag1_layout, container, false);
mEtTitle = (EditText) view.findViewById(R.id.note_et_title1);
Bundle bundle = getArguments();
if (bundle != null) {
mEtTitle.setText(bundle.getString(EXTRA_TEXT));
}
return view;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_green_light">
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:text="Vraag 1, bv naam" />
<EditText
android:id="#+id/note_et_title1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:ems="10"
android:gravity="top"
android:inputType="textMultiLine" />
I would recommend you to slighlty change your current approach.
First create helper method newInstance in each fragment which will return the instance of that fragment. For example Frag1
public class Frag1 extends Fragment {
private static final String EXTRA_TEXT = "text";
private EditText mEtTitle;
public static Frag1 newInstance(String message) {
Bundle args = new Bundle();
args.putString(EXTRA_TEXT, message);
Frag1 fragment = new Frag1();
fragment.setArguments(args);
return fragment;
}
public Frag1 () {
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag1_layout, container, false);
mEtTitle = (EditText) view.findViewById(R.id.note_et_title1);
Bundle bundle = getArguments();
if (bundle != null) {
mEtTitle.setText(bundle.getString(EXTRA_TEXT));
}
return view;
}
}
In SectionsPagerAdapter pass the list of Fragment.
For the reference hereby modified SectionsPagerAdapter.
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragments;
public SectionsPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
mFragments = fragments;
}
#Override
public Fragment getItem(final int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
}
Then change the call
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(),<List of Fragments>);
Hereby sharing modified Activity#onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
String title = "";
String question2 = "";
String question3 = "";
mNoteFileName = getIntent().getStringExtra("NOTE_FILE");
if(mNoteFileName !=null && !mNoteFileName.isEmpty()) {
mLoadedNote = Utilities.getNoteByName(this, mNoteFileName);
if(mLoadedNote !=null) {
title = mLoadedNote.getTitle();
question2 = mLoadedNote.getQuestion2();
question3 = mLoadedNote.getQuestion3();
}
}
List<Fragment> fragments = new ArrayList<>();
fragments.add(Frag1.newInstance(title));
fragments.add(Frag2.newInstance(question2));
fragments.add(Frag3.newInstance(question3));
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(),fragments);
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
}
You should use Shared Preferences or Database to save your data and show it.
enter image description here
Before reading the question, please refer to image.
I am using viewpager to show the fragment.
Problem
In the fragment, I have used two edittext lets say editText1, editText2 now the problem is how I will get the editText data. I can only get the editText values when user click on next button but the next button is outside of fragment. How do I access the editText outside the fragment.
Before downvoting the question, let me know the reason so that I can improve my question.
Fragment java class
// newInstance constructor for creating fragment with arguments
public static BpDetails newInstance(int page) {
BpDetails fragmentFirst = new BpDetails();
Bundle args = new Bundle();
args.putInt("someInt", page);
fragmentFirst.setArguments(args);
return fragmentFirst;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("someInt", 0);
}
// Inflate the view for the fragment based on layout XML
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.bp_details, container, false);
Log.i("View ",view.toString());
Log.i("DOB is ",Long.toString(Constants.dob));
systolic =(EditText) view.findViewById(R.id.systolic);
diastolic =(EditText) view.findViewById(R.id.diastolic);
return view;
}
ViewPager Activity
vpPager = (ViewPager) findViewById(R.id.view_pager);
adapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
vpPager.setAdapter(adapterViewPager);
Fragment fragment=adapterViewPager.getItem(prevPage);
if (fragment.getClass().equals(BpDetails.class)){
Log.i("Call ","Yes");
}
findViewById(R.id.btn_prev).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// checking for last page
// if last page home screen will be launched
int current = getItem(-1);
if (current!=0)
prevPage=current-1;
if (current < 4) {
// move to next screen
vpPager.setCurrentItem(current);
} else {
//final reached.
}
}
});
findViewById(R.id.btn_next).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// checking for last page
// if last page home screen will be launched
int current = getItem(+1);
if (current!=0)
prevPage=current-1;
System.out.println("Prev page "+prevPage);
if (current < 4) {
// move to next screen
Fragment prevFragment=adapterViewPager.getItem(prevPage);
} else {
//final reached.
}
}
});
}
private int getItem(int i) {
return vpPager.getCurrentItem() + i;
}
public static class MyPagerAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 4;
private static int mSelectedPosition;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
//mSelectedPosition=selectedPosition;
}
// 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: // Fragment # 0 - This will show FirstFragment
return BasicDetails.newInstance(0);
case 1:
return BpDetails.newInstance(1);
case 2:
return BslDetails.newInstance(2);
case 3:
return Summary.newInstance(3);
default:
return null;
}
}
}
Create two getters inside your fragment like this.
public String getSystolic(){
return this.systolic.getText().toString();
}
public String getDiastolic(){
return this.diastolic.getText().toString();
}
BpDetails fr = (BpDetails)myAdapter.getItem(myViewPager.getCurrentItem());
String systolicString = fr.getSystolic();
I had a similar issue. .getItem() instantiates a new Fragment, so upon calling myAdapter.getItem(...) you would be getting null for all elements in the Fragment, but not null for the Fragment.
When I fixed this, what I had to do was create another method inside of MyPagerAdapter called getInstantiatedFragment:
public Fragment getInstantiatedFragment(int position)
{
return fragments.get(position);
}
fragments is a new field for the class:
private ArrayList<Fragment> fragments = new ArrayList<>();
I would override getItem() (as you have done already) and change it to:
#Override
public Fragment getItem(int position)
{
switch (position) {
case 0:
BasicDetails basicDetails = BasicDetails.newInstance(0);
fragments.add(basicDetails);
return basicDetails;
...
}
where you're adding the fragment to fragments before returning, then you would call:
BpDetails fr = (BpDetails)myAdapter.getInstantiatedItem(myViewPager.getCurrentItem());
to get the instance of the created fragment and then call
String systolicString = fr.getSystolic();
if you're using the previous answer's method.
This is so that you can keep track of the instantiated fragments in fragments. I'm sure there are better ways.
HERE IS THE VIDEO:
https://www.youtube.com/watch?v=eush2bY0XlQ&feature=youtu.be&hd=1
So here is the plot :
1) I have a navigation drawer.
2) By Clicking on one of the list item a tab layout (fragment) is inflated .
3) So I get a tab layout (with 6 tabs) working besides navigation drawer i.e navigation drawer and tab_layout can be used simultaneously.
4) Content of every tab is a Different fragement.
Problem :
When I launch the application and click the list-item with the tab fragment the content of the tab_fragment is inflated normally.
But when i click it again all the content of the first and second tab dissappear.
And reappear only when when i swipe till the third tab and swipe back again .
In simple words ,
On Calling the static new Instance method of Tab_Fragment for the first time is works fine .
On Calling it again the content of the first and second tab disappear and reappear
only when I swipe till the 3rd tab and come back.
I know it sounds weird.
Code:
My Tab_Fragment To Create it I call its New Instance From MainActivity.
public class Tab_Activity extends Fragment {
private final Handler handler = new Handler();
public PagerSlidingTabStrip tabs;
private ViewPager pager;
private MyPagerAdapter adapter;
public final static String TAG = Tab_Activity.class.getSimpleName();
public Tab_Activity() {
// TODO Auto-generated constructor stub
}
public static Tab_Activity newInstance() {
return new Tab_Activity();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.tab_layout, container, false);
}
#Override
public void onViewCreated(View v, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(v, savedInstanceState);
tabs = (PagerSlidingTabStrip) v.findViewById(R.id.tabs);
pager = (ViewPager) v.findViewById(R.id.pager);
adapter = new MyPagerAdapter(getActivity().getSupportFragmentManager());
pager.setAdapter(adapter);
final int pageMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources()
.getDisplayMetrics());
pager.setPageMargin(pageMargin);
tabs.setViewPager(pager);
tabs.setIndicatorColorResource(R.color.grey);
tabs.setTextColorResource(R.color.black);
}
public class MyPagerAdapter extends FragmentPagerAdapter {
private final String[] TITLES = { " ELECTRONICS ", " IT ", " COMPUTER "," EXTC ", "INSTRUMENTATION"," MCA " };
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return TITLES[position];
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public Fragment getItem(int position) {
return Courses.newInstance(position);
}
}
}
The Courses Fragment :
public class Courses extends Fragment {
LinearLayout ll ;
private static final String ARG_POSITION = "position";
public static PagerSlidingTabStrip tab ;
private int position;
public static Courses newInstance(int position) {
Courses f = new Courses();
Bundle b = new Bundle();
b.putInt(ARG_POSITION, position);
f.setArguments(b);
return f;
}
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
position = getArguments().getInt(ARG_POSITION);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.dept_main,container,false);
}
#Override
public void onViewCreated(View v, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(v, savedInstanceState);
// generate ID's :
TextView h_name = (TextView) v.findViewById(R.id.tv_dept_name);
TextView f_info = (TextView) v.findViewById(R.id.tv_dept_info);
TextView h_vision = (TextView) v.findViewById(R.id.header_vision);
TextView f_vision = (TextView) v.findViewById(R.id.footer_vision);
TextView h_mission = (TextView) v.findViewById(R.id.header_mission);
TextView f_mission = (TextView) v.findViewById(R.id.footer_mission);
TextView h_eoe = (TextView) v.findViewById(R.id.header_EOE);
TextView f_eoe = (TextView) v.findViewById(R.id.footer_EOE);
TextView h_intake = (TextView) v.findViewById(R.id.header_intake);
TextView f_intake = (TextView) v.findViewById(R.id.footer_intake);
h_intake.setText(R.string.h_intake);
h_mission.setText(R.string.h_mission);
h_vision.setText(R.string.h_vision);
h_eoe.setText(R.string.h_eoe);
switch(position){
case 0 :
//Electronics
h_name.setText("Electronics");
f_info.setText(R.string.ug_course);
f_vision.setText(R.string.v_etrx);
f_mission.setText(R.string.m_etrx);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_etrx);
break ;
case 1 :
h_name.setText("Information Technology");
f_info.setText(R.string.ug_course);
f_vision.setText(R.string.v_it);
f_mission.setText(R.string.m_it);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_it);
break ;
case 2 :
h_name.setText("Computer Science");
f_info.setText(R.string.ug_course);
f_vision.setText(R.string.v_coms);
f_mission.setText(R.string.m_coms);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_coms);
break ;
case 3 :
h_name.setText("Electronics And Telecommunication");
f_info.setText(R.string.ug_course);
f_vision.setText(R.string.v_extc);
f_mission.setText(R.string.m_extc);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_extc);
break ;
case 4 :
h_name.setText("Instrumentation");
f_info.setText(R.string.ug_course);
f_vision.setText(R.string.v_it);
f_mission.setText(R.string.m_it);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_it);
break ;
case 5 :
h_name.setText("Master of Computer Applications");
f_info.setText("Post Graduation Course.(PG)");
f_vision.setText(R.string.v_mca);
f_mission.setText(R.string.m_mca);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_mca);
break;
}
}
}
(Comment for any clarifications ! )
Found My Answer ==> https://stackoverflow.com/a/12582529/3475933
Only Changed FragmenPagerAdapter to FragmentStatePagerAdapter and eveything worked fine.
Hope it helps .!
I have a supported fragment activity which will load diff fragments. The fragment has some textView with id = "score" and I want to get its handle but findViewById for score's textView returns null. Why so?
textView is placed in fragment
public class MyActivity extends extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks{
private TextView scoreBoardTextView = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
scoreBoardTextView = (TextView) findViewById(R.id.score); //this returns null
}
#Override
public void onNavigationDrawerItemSelected(int position) {
//set fragment
}
}
Note:
Directly accessing fragment's views outside fragment is not a good idea. You should use fragment callback interfaces to handle such cases and avoid bugs. The following way works but it is not recommended as it is not a good practice.
If you want to access the TextView of Fragment inside its parent Activity then you should define a method inside your Fragment class like this:
public class MyFragment extends Fragment {
TextView mTextView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main, container, false);
mTextView = (TextView) view.findViewById(R.id.textView1);
return view;
}
public void setTextViewText(String value){
mTextView.setText(value);
}
}
Now you can use this inside your Activity like this:
myFragment.setTextViewText("foo");
here myFragment is of type MyFragment.
If you want to access the whole TextView then you can define a method like this inside MyFragment.java:
public TextView getTextView1(){
return mTextView;
}
By this you can access the TextView itself.
Hope this Helps. :)
It is possible with following way:
Keep reference of inflated view in the Fragment like this :
public class MyFragment extends SherlockFragment{
MainMenuActivity activity;
public View view;
public MyFragment(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if ( getActivity() instanceof MainMenuActivity){
activity = (MainMenuActivity) getActivity();
}
view = inflater.inflate(R.layout.aboutus, container, false);
return view;
}
}
Create a function in the Activity, like this:
public class MainMenuActivity extends SherlockFragmentActivity {
SherlockFragment fragment = null;
public void switchContent(SherlockFragment fragment) {
this.fragment = fragment;
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.mainmenu, fragment)
.commit();
invalidateOptionsMenu();
}
Its purpose is to keep reference of current fragment. Whenever you wanna switch fragment, you call above function, like this (from fragment):
activity.switchContent( new MyFragment_2());
Now you've current fragment reference. So you can directly access Fragment's views in Activity like this: this.fragment.view
You have no need of reference of Fragment view to get its components in Activity. As you can directly access layout components of a Fragment in parent Activity.
Simply you can access any component by this
findViewById(R.id.child_of_fragment_layout);
In order to access the TextView or Button or whatever in your fragment you need to do the following:
public class BlankFragment extends Fragment {
public View view;
public TextView textView;
public Button button;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view =inflater.inflate(R.layout.fragment_blank, container, false);
textView = (TextView)view.getRootView().findViewById(R.id.textView_fragment1);
return view;
}
public void changeTextOfFragment(String text){
textView.setText(text);
view.setBackgroundResource(R.color.colorPrimaryDark);
}
Once that is done in your MainActivity or any other where you want to access your TextView from your Fragment you should make sure to set up the fragment in your OnCreate() method other ways it will most likely throw nullPointer. So your activity where you want to change the TextView should look smth like this:
public class MainActivity extends AppCompatActivity {
private Button button1;
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
BlankFragment blankFragment = new BlankFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button)findViewById(R.id.button1);
changeFragment();
fragmentManager = getFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment1,blankFragment);
fragmentTransaction.commit();
}
private void changeFragment(){
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
blankFragment.changeTextOfFragment("Enter here the text which you want to be displayed on your Updated Fragment");
}
});
}
Hope this helps :)
You can access with getView method of Fragment class.
For example You have a TextView in Your MyFragment with id of "text_view" In Your Activity make a Fragment of Yours:
MyFragment myFragment = new MyFragment();
And when You need a child just call getView and then find Your childView.
View view = myFragment.getView();
if (view !=null) {
view.findViewById(R.id.text_view).setText("Child Accessed :D");
}
Note: if you want the root view of your fragment, then myFragment.getView(); is simply enough.
Just put in fragment instead of putting in activity:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_new_work_order,
container, false);
TextView scoreBoardTextView = (TextView) rootView.findViewById(R.id.score);
return rootView;
}
Only doing this:
((Your_Activity) this.getActivity()).YouyActivityElements;
If your TextView placed inside Fragment that case you cannot access TextView inside your Fragment Parent Activity you can set the interface for intercommunication between Fragment and Activity and send Data when you click on TextView or anyother thing which you want to happend
You can't access Fragment element in Parent Activity, But You can pass values to your Fragment by following way.
in your onNavigationDrawerItemSelected method of MyActivity do the following
int myScore = 100;
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.container,
MyFragment.newInstance(myScore)).commit();
}
And in MyFragment class create a method called newInstance like following
private static final String SCORE = "score";
public static MyFragment newInstance(int score) {
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putInt(SCORE, score);
fragment.setArguments(args);
return fragment;
}
And in MyFragment's onCreateView() method
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
TextView textView = (TextView) rootView
.findViewById(R.id.score);
textView.setText(Integer.toString(getArguments().getInt(
SCORE)));
return rootView;
}
That's All, I hope this will help you. If not please let me know.
The score textView is in the layout of fragment, it's not in the layout of the MyActivity, i.e. R.layout.activity_home. So you could find the score textview in that fragment once you inflate the corresponding layout file.
It returns null cause the TextView is an element of the Fragment, not the Activity.
Please note that the idea of using Fragment is to encapsulate a module inside the Fragment, which means the Activity should not have direct access to it's properties. Consider moving your logic where you get the TextView reference inside the Fragment
Simply declare TextView as public in fragment, initialize it by findViewById() in fragment's onCreateView(). Now by using the Fragment Object which you added in activity you can access TextView.
You need to call method findViewById from your fragment view.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
scoreBoardTextView = (TextView) mNavigationDrawerFragment.getView().findViewById(R.id.score);
}
This way works for me.
I suggest you to make the textview part of your activity layout. Alternately you can have the textview as a separete fragment. Have a look at my question here. Its similar to yours but in reverse direction. Here's a stripped down version of code I used in my project. The explanation are along the code.
The Activity Class
public class MainActivity extends ActionBarActivity {
PlaceFragment fragment;
TextView fragmentsTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Bundle bundle = new Bundle();
bundle.putString("score", "1000");
fragment = PlaceFragment.newInstance(bundle);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container, fragment);
ft.addToBackStack(null);
ft.commit();
// method 1
// fragment is added some ways to access views
// get the reference of fragment's textview
if (fragment.getTextView() != null) {
fragmentsTextView = fragment.getTextView();
}
// method 2
// using static method dont use in production code
// PlaceFragment.textViewInFragment.setText("2000");
// method 3
// let the fragment handle update its own text this is the recommended
// way wait until fragment transaction is complete before calling
//fragment.updateText("2000");
}
}
The fragment class:
public class PlaceFragment extends Fragment {
public TextView textViewInFragment;// to access via object.field same to
// string.length
// public static TextView textViewInFragment;//to access via
// PlaceFragment.textView dont try this in production code
public PlaceFragment() {
}
public static PlaceFragment newInstance(Bundle bundle) {
PlaceFragment fragment = new PlaceFragment();
fragment.setArguments(bundle);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment_place, container, false);
textViewInFragment = (TextView) view
.findViewById(R.id.textViewInFragment);
return view;
}
#Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
if (getArguments() != null) {
textViewInFragment.setText(getArguments().getString("score"));
}
}
public TextView getTextView() {
if (textViewInFragment != null) {
return textViewInFragment;// returns instance of inflated textview
}
return null;// return null and check null
}
public void updateText(String text) {
textViewInFragment.setText(text);// this is recommended way to alter
// view property of fragment in
// activity
}
}
Communication from activity to fragment is straight forward. This is because activity contains fragment. Keep the fragment object and access its property via setters and getters or the public fields inside it. But communication from fragment to activity requires an interface.
why you don't access it directly from your FragmentPagerAdapter,
SubAccountFragment subAccountFragment = (SubAccountFragment) mSectionsPagerAdapter.getItem(1);
subAccountFragment.requestConnectPressed(view);
and here is the full example:
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Locale;
public class TabsActivity extends ActionBarActivity implements ActionBar.TabListener {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs);
// Set up the action bar.
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
ActionBar.Tab tab = actionBar.newTab();
View tabView = this.getLayoutInflater().inflate(R.layout.activity_tab, null);
ImageView icon = (ImageView) tabView.findViewById(R.id.tab_icon);
icon.setImageDrawable(getResources().getDrawable(mSectionsPagerAdapter.getPageIcon(i)));
TextView title = (TextView) tabView.findViewById(R.id.tab_title);
title.setText(mSectionsPagerAdapter.getPageTitle(i));
tab.setCustomView(tabView);
tab.setTabListener(this);
actionBar.addTab(tab);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_tabs, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_logout) {
finish();
gotoLogin();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public ProfileFragment profileFragment;
public SubAccountFragment subAccountFragment;
public ChatFragment chatFragment;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
profileFragment = new ProfileFragment();
subAccountFragment = new SubAccountFragment();
chatFragment = new ChatFragment();
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return profileFragment;
case 1:
return subAccountFragment;
case 2:
return chatFragment;
}
return null;
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
public int getPageIcon(int position) {
switch (position) {
case 0:
return R.drawable.tab_icon_0;
case 1:
return R.drawable.tab_icon_1;
case 2:
return R.drawable.tab_icon_2;
}
return 0;
}
}
public void gotoLogin() {
Intent intent = new Intent(this, LoginActivity.class);
this.startActivity(intent);
}
public void requestConnectPressed(View view){
SubAccountFragment subAccountFragment = (SubAccountFragment) mSectionsPagerAdapter.getItem(1);
subAccountFragment.requestConnectPressed(view);
}
}
If the view is already inflated (e.g. visible) on the screen then you can just use findViewById(R.id.yourTextView) within the activity as normal and it will return the handle to the text view or null if the view was not found.
I just use methods to access fragment views from parent activity, because we create a new fragment class object to insert the fragment. So I do like this.
class BrowserFragment : Fragment(), Serializable {
private lateinit var webView: NestedScrollWebView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
webView = view.findViewById(R.id.web_view)
}
fun getWebView(): WebView {
return webView
}
}
In MainActivity
val browserFragment = BrowserFragment()
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.add(R.id.browser_fragment_placeholder, browserFragment)
fragmentTransaction.commit()
val webView = browserFragment.getWebView()
I have 2 fragments (tabs) that share some data. When one changes the data, I'd like to have that reflected on the other tab. I researched this on stackOverflow and I think the relevant answer has to do with a .notifyDataSetChanged() call, but I can't make it work. Here's the relevant code...
public class EnterCourseData extends FragmentActivity implements ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Pars", "Handicaps" };
private int courseNumber, teeNumber;
private Tee tee;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_tees);
// Initilization
Intent mIntent = getIntent();
courseNumber = mIntent.getIntExtra("courseNumber",0);
Course course = Global.getCourse(courseNumber);
teeNumber = mIntent.getIntExtra("teeNumber",0);
tee = course.getTee(teeNumber);
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager(), courseNumber, teeNumber);
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
and further down, here is the onClick method that necessitates the refresh...
public void savePars(View view){
tee.setSlope(Integer.parseInt(((EditText) findViewById(R.id.enter_tee_slope)).getText().toString()));
tee.setRating(Double.parseDouble(((EditText) findViewById(R.id.enter_tee_rating)).getText().toString()));
mAdapter.notifyDataSetChanged();
}
Here is the TabsPagerAdapter...
public class TabsPagerAdapter extends FragmentPagerAdapter {
int courseNumber, teeNumber;
public TabsPagerAdapter(FragmentManager fm, int courseNumber, int teeNumber) {
super(fm);
this.courseNumber = courseNumber;
this.teeNumber = teeNumber;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Par Entry activity
Fragment parFragment = new ParFragment();
Bundle args = new Bundle();
args.putInt(ParFragment.ARG_COURSE_NUMBER, courseNumber);
args.putInt(ParFragment.ARG_TEE_NUMBER, teeNumber);
parFragment.setArguments(args);
return parFragment;
case 1:
// Handicap Entry fragment activity
Fragment hcpFragment = new HandicapFragment();
args = new Bundle();
args.putInt(HandicapFragment.ARG_COURSE_NUMBER, courseNumber);
args.putInt(HandicapFragment.ARG_TEE_NUMBER, teeNumber);
hcpFragment.setArguments(args);
return hcpFragment;
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 2;
}
}
Here is one Fragment...
public class ParFragment extends Fragment {
public static final String ARG_COURSE_NUMBER = "courseNumber", ARG_TEE_NUMBER = "teeNumber";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_par, container, false);
Bundle args = getArguments();
Course course = Global.getCourse(args.getInt(ARG_COURSE_NUMBER));
((TextView) rootView.findViewById(R.id.display_course_name)).setText(course.getName());
Tee tee = course.getTee(args.getInt(ARG_TEE_NUMBER));
((TextView) rootView.findViewById(R.id.display_tee_name)).setText(tee.getTeeName());
((TextView) rootView.findViewById(R.id.enter_tee_slope)).setText(Integer.toString(tee.getSlope()));
((TextView) rootView.findViewById(R.id.enter_tee_rating)).setText(Double.toString(tee.getRating()));
return rootView;
}
}
And here is the other...
public class HandicapFragment extends Fragment {
public static final String ARG_COURSE_NUMBER = "courseNumber", ARG_TEE_NUMBER = "teeNumber";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_handicap, container, false);
Bundle args = getArguments();
Course course = Global.getCourse(args.getInt(ARG_COURSE_NUMBER));
((TextView) rootView.findViewById(R.id.display_course_name)).setText(course.getName());
Tee tee = course.getTee(args.getInt(ARG_TEE_NUMBER));
((TextView) rootView.findViewById(R.id.display_tee_name)).setText(tee.getTeeName());
((TextView) rootView.findViewById(R.id.enter_tee_slope)).setText(Integer.toString(tee.getSlope()));
((TextView) rootView.findViewById(R.id.enter_tee_rating)).setText(Double.toString(tee.getRating()));
return rootView;
}
}
When the button is clicked, I want to save the values and I want these values to show up on the other fragment.
Help a noob out.
Thanks
You need to communicate between fragments, but a fragment cannot directly communicate with other fragment, all the communication should be done through the activity which holds these fragments.
The steps to follow are :
Define an Interface in the fragment where you have implemented the onClickListener (let it be Fragment A)
Implement the Interface in the activity which holds these fragments
In the method overridden, retrieve the fragment instance from the viewpager adapter and deliver a message to Fragment B by calling it's public methods.
refer this answer to retrieve fragment instance from adapter
For more details about Communicating with Other Fragments, refer here
So there is a trick: just let the fragments have the object reference of one another and call the other's function to load data when you handle the onClickListener of the button.
E.g:
protected void onClickListener(View view) {
if (view == myButton) {
// Do other stuffs here
fragment1.reloadData();
}
}
P/S : I re-post this as answer to have the code formatter.