In a class i am adding a Fragment programatically.
This Fragment contains a Button, which i want to have an onClick implementation.
Here is the class i have:
public class ShareProduct extends SherlockFragmentActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.share_product);
FragmentManager fragmentManager = getSupportFragmentManager();
final FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
ProductFragment1 fragment = new ProductFragment1();
fragmentTransaction.add(R.id.share_product_parent, fragment);
fragmentTransaction.commit();
Button done_button = (Button) fragment.getView().findViewById(
R.id.done_product_1);
done_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
ProductFragment2 fragment = new ProductFragment2();
fragmentTransaction
.replace(R.id.share_product_parent, fragment);
fragmentTransaction.commit();
}
});
}
}
and my ProductFragment1 class is:
public class ProductFragment1 extends SherlockFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater
.inflate(R.layout.share_product_1, container, false);
return view;
}
}
and the layout my main class uses is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/share_product_parent"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="right|center_vertical"
android:orientation="horizontal" >
</RelativeLayout>
and the layout my ProductFragment1 uses is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/tv1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="25dp" />
<EditText
android:id="#+id/et1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/tv1"
android:textSize="25dp" />
<Button
android:id="#+id/done_product_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/et1"
android:text="Done" />
</RelativeLayout>
The problem is:
I am getting a NullPointerException at this line in my main class:
Button done_button = (Button) fragment.getView().findViewById(R.id.done_product_1);
done_button.setOnClickListener ....
when i searched for what getView() on a fragment returns. I found out that it returns the view from onCreateView();
I checked it doesn't return null.
Thank You
You are on the wrong track here. You get the NPE because the Fragments views is not created yet. Fragments also have a lifecycle just like Activities.
What you should be doing is assigning the OnClickListener inside your Fragments onViewCreated() method. And from there... you should create a callback and notify your hosting Activity of the event.
Related
I am trying to change the fragment when I click on a button. The button is inside a fragment and I want to go to another fragment. This code is not giving any error but not changing to desired fragment. It is just showing the background of container. Please help me why it is just showing the color of container and not changing to new fragment.
Here is my first Fragment-
public class IntroFragment1 extends Fragment {
public IntroFragment1() {
// Required empty public constructor
}
public static IntroFragment1 newInstance() {
return new IntroFragment1();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_intro1, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
/**
* Button to go to next tab in tutorial
* */
Button nextScreen = getView().findViewById(R.id.nextTabButtonIntro);
nextScreen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (vb1 != null) {
vb1.vibrate(300);
}
FragmentTransaction transaction = getFragmentManager().beginTransaction();
Fragment frag = IntroFragment2.newInstance();
transaction.replace(R.id.containerIntroScreen, frag);
transaction.commit();
}
});
}//End of onViewCreated
}
This is the XML of first Fragment. The next Button should take me to next fragment-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimaryDark"
android:orientation="vertical"
android:weightSum="1"
tools:context="com.example.fitbitsampleapp.AppIntroTabbedView.IntroFragment1">
<TextView
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="casual"
android:text="Track your daily activities. Stay healthy, Stay smart."
android:textSize="26dp" />
<Button
android:id="#+id/skipIntoButton"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="#drawable/background_button"
android:fontFamily="casual"
android:text="skip"
android:textAllCaps="true"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Large"
android:textColor="#000" />
<Button
android:id="#+id/nextTabButtonIntro"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="#drawable/background_button"
android:fontFamily="casual"
android:text="next"
android:textAllCaps="true"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Large"
android:textColor="#000" />
</LinearLayout>
This is the fragment, I want to go to-
public class IntroFragment2 extends Fragment {
public IntroFragment2() {
// Required empty public constructor
}
public static android.support.v4.app.Fragment newInstance() {
IntroFragment2 fragment = new IntroFragment2();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_intro2, container, false);
}
The XML of the 2nd Fragment-
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorAccent"
tools:context="com.example.fitbitsampleapp.AppIntroTabbedView.IntroFragment2">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:text="2nd fragment" />
</RelativeLayout>
This is the layout of activity which has the fragments-
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.fitbitsampleapp.AppIntroTabbedView.IntroScreen">
<android.support.v4.view.ViewPager
android:background="#00F111"
android:id="#+id/containerIntroScreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
So initially the app opens with 1st transaction as expected. However when I click on next button in fragment 1, it should take me to fragment 2. But it just shows the Background color of ViewPager after the Fragment Transaction.
EDIT:
Here is my Main Activity as well which has the fragments-
public class IntroScreen extends AppCompatActivity {
public static Vibrator vb1;
public Button nextScreen;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intro_screen);
/***/
vb1 = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
/**
* Create the adapter that will return a fragment
* for each of the N primary sections of the activity.
* */
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
/** Set up the ViewPager with the sections adapter.*/
ViewPager mViewPager = findViewById(R.id.containerIntroScreen);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
switch (position) {
case 0:
return IntroFragment1.newInstance();
case 1:
return IntroFragment2.newInstance();
default:
return IntroFragment2.newInstance();
}
}
#Override
public int getCount() {
return 2;
}
}
}
SOLVED BY #MikeM. in the comments above.
Since I was already using a ViewPager, All that was required was to give the correct item number to my ViewPager.
int THE_POSITION_OF_THE_FRAGMENT_IN_VIEW_PAGER = 1;
mViewPager.setCurrentItem(THE_POSITION_OF_THE_FRAGMENT_IN_VIEW_PAGER);
Trying to Communicating FragmentA to FragmentB, doing is taking numeric value from fragmentA adding them and displaying result in fragmentB using interface, but I got nullpointerException, I have look many times in the code but seems everything is fine but getting nullpointerException showing line 34 in FragmentA
listener.setResult(result+" ");
Here's My FragmentA
public class FragmentA extends Fragment{
MyFragmentInterface listener;
Button buton;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view =inflater.inflate(R.layout.fragment_a,container,false);
final EditText editText= (EditText) view.findViewById(R.id.edit_text1);
final EditText editText2= (EditText) view.findViewById(R.id.edit_text2);
buton= (Button) view.findViewById(R.id.button);
buton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int num1=Integer.parseInt(editText.getText().toString());
int num2=Integer.parseInt(editText2.getText().toString());
int result=num1+num2;
listener.setResult(result+" ");
}
});
return view;
}
#Override
public void onAttach(Context context) {
listener= (MyFragmentInterface) context;
super.onAttach(context);
}
}
Here's my fragment_a.xml
<?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="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/edit_text1"
android:inputType="number"
android:textSize="30sp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:id="#+id/edit_text2"
android:textSize="30sp"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Calculate"
android:id="#+id/button"
android:background="#null"
android:textAllCaps="false"/>
</LinearLayout>
FragmentB.java
public class FragmentB extends Fragment {
TextView textView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
textView= (TextView) getActivity().findViewById(R.id.textview);
return inflater.inflate(R.layout.fragment_b,container,false);
}
public void putresult(String r){
textView.setText(r);
}
}
fragment_b.xml
<?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="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:id="#+id/textview"
android:text="Text will appear here"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity implements MyFragmentInterface {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentA fragmentA=new FragmentA();
FragmentManager fragmentManager=getFragmentManager();
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.linear1,fragmentA);
fragmentTransaction.commit();
FragmentB fragmentB=new FragmentB();
FragmentManager fragmentManager1=getFragmentManager();
FragmentTransaction fragmentTransaction1=fragmentManager1.beginTransaction();
fragmentTransaction1.addToBackStack(null);
fragmentTransaction1.replace(R.id.linear2,fragmentB);
fragmentTransaction1.commit();
}
#Override
public void setResult(String result) {
FragmentB fragmentnew=new FragmentB();
fragmentnew= (FragmentB) getFragmentManager().findFragmentById(R.id.linear2);
fragmentnew.putresult(result);
}
}
MyFragmentInterface.java
public interface MyFragmentInterface {
public void setResult(String result);
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="queendevelopers.com.communicate.MainActivity"
android:weightSum="2"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="#+id/linear1"
android:orientation="vertical" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="#+id/linear2"
android:orientation="vertical" />
</LinearLayout>
error log:
08-16 16:11:42.307 7630-7630/queendevelopers.com.communicate E/AndroidRuntime: FATAL EXCEPTION: main
Process: queendevelopers.com.communicate, PID: 7630
java.lang.NullPointerException: Attempt to invoke interface method 'void queendevelopers.com.communicate.MyFragmentInterface.setResult(java.lang.String)' on a null object reference
at queendevelopers.com.communicate.FragmentA$1.onClick(FragmentA.java:34)
at android.view.View.performClick(View.java:4832)
at android.view.View$PerformClick.run(View.java:19844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5319)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1016)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
To expand on the comment I made that solved the problem:
The original issue was not to do with your interface callback (this was not the root cause of the NullPointerException).
When the callback method setResult(String result) was invoked this line :
fragmentnew.putresult(result); was causing the null pointer because, in the method putresult in your fragment there is a null reference to your textView (textView.setText(r);).
For every Activity you can have an associated view heirarchy (your XML file), this is set by setContentView() in onCreate(). Now if you try and reference any #+id widgets from the XML layout you can cast relevant object type : TextView, EditText, ListView. Fragments (which are attached to a hosting Activity) can also have their own layouts, this is inflated in onCreateView(). Your final code should look something like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b,container,false);
textView = (TextView) view.findViewById(R.id.textview);
return view;
}
Your view object now contains your view hierarchy for the inflated XML Layout, from which you can access all widgets.
The line of code that was incorrect was:
textView = (TextView) getActivity().findViewById(R.id.textview);
The reason being you are using the convenience method getActivity() this will return the hosting Activity reference - thus you now will have access to the hosting Activity - used a lot for gaining a Context of other purposes, however your view id reference is invalid because it is in the view hierarchy of your inflated layout in your fragment.
Try this method inside your Fragment
#Override
public void onAttach(Context context) {
super.onAttach(context);
listener = (MyFragmentInterface) getActivity();
}
try this
(((MyFragmentInterface)getActivity()).setResult(result+" ");
Change in Fragment A:
from:
buton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int num1=Integer.parseInt(editText.getText().toString());
int num2=Integer.parseInt(editText2.getText().toString());
int result=num1+num2;
listener.setResult(result+" ");
}
});
To
buton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int num1=Integer.parseInt(editText.getText().toString());
int num2=Integer.parseInt(editText2.getText().toString());
int result=num1+num2;
((MainActivity) getActivity()).setResult(result+" ");
}
});
Because I think your listener object is not initialised before being used so try this answer please.
I am facing some issues for fragment in Android.
I completed a implementation of ViewPager using two fragment class with its xml layout, An MainActivity and An Adapter.
First Fragment : Linear Layout is Parent as well in second fragment, Linear Layout is parent. I have a button in my first fragment, i want to replace first fragment means switch fragment from first to second.
I am using ViewPager. Kindly Look on my source code.
PagerActivity.java
public class PagerActivity extends FragmentActivity {
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pager);
mViewPager=(ViewPager)findViewById(R.id.viewpager);
/** set the adapter for ViewPager */
mViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
// mViewPager.notify();
}
}
PagerAdapter.java
public class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
/** Show a Fragment based on the position of the current screen */
if (position == 0) {
return new Welcome();
}else{
return new Locate();
}
}
#Override
public int getCount() {
return 2;
}
}
Welcome.java
Fragment 1
public class Welcome extends Fragment implements GlobalInterFace, View.OnClickListener{
private Button welcomeBtn;
private View v;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_welcome, container, false);
welcomeBtn=(Button)v.findViewById(R.id.welcomeBtn);
findViewById();
setOnClickListener();
return v;
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.welcomeBtn:{
Log.e("click", "click");
Fragment fragment = new Locate();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.parent_linear, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
break;
}
}
}
Locate.java
Fragment 2
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_welcome_pager_two, container, false);
locateMe=(Button)v.findViewById(R.id.locateBtn);
locateMe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getActivity(), SignUpActivity.class);
startActivity(i);
((Activity) getActivity()).overridePendingTransition(0,0);
}
});
return v;
}
welcome xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/parent_linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/splash_color"
android:weightSum="100">
<RelativeLayout
android:id="#+id/rel1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50">
<com.rey.material.widget.ImageView
android:id="#+id/welcome_Image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/welcome"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/welcomeRelativeTwo"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:padding="#dimen/universal_margin4"
>
<com.rey.material.widget.TextView
android:id="#+id/Ready"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/welcome_ready"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textSize="#dimen/universal_margin2"
android:layout_centerInParent="true"
/>
<com.rey.material.widget.TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/welcome_descrition"
android:layout_below="#+id/Ready"
android:textAlignment="center"
android:layout_centerHorizontal="true"
android:layout_marginTop="#dimen/universal_margin"
/>
<com.rey.material.widget.Button
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/welcomeBtn"
app:rd_enable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/description"
android:text="#string/welcome_btntext"
android:textColor="#color/splash_color"
android:background="#color/colorAccent"
android:layout_marginTop="#dimen/universal_margin2"
/>
</RelativeLayout>
<!-- Your RelativeLayout Items -->
</LinearLayout>
Locate.xml
same as welcome layout only layout id is changed.
When I click on WelcomeBtn, the fragment replacement is not working.mentioned this one in my source code in Welcome.java
please help me.
Your parent parent_linearis instance of LinearLayout if you want to put fragment inside this view you should change your LinearLayout to FrameLayout something like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/parent_linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/splash_color">
//... your other layout goes here
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
And change following part of your code:
fragmentTransaction.replace(R.id.fragment_container, fragment);
I am trying to do a very basic example with Fragments.
Structure : Fragment1 -> Fragment1Activity, Fragment2 -> Fragment2Activity.
Both activities have a STATIC Fragment in it.
Here are the XMLs:
activity_for_fragment_1.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.xx.fragmentstutorial1.Fragment1"
tools:context="com.xx.fragmentstutorial1.Fragment1Activity"/>
fragment1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textview_fragment_1"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="0.60"
android:text="This is Fragment 1"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="#+id/edittext_fragment_1_text"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="0.20"
android:text="Type your message here..." >
<requestFocus />
</EditText>
<Button
android:id="#+id/button_fragment_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Click Me" />
</LinearLayout>
activity_for_fragment_2.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.xx.fragmentstutorial1.Fragment2"
tools:context="com.xx.fragmentstutorial1.Fragment2Activity"/>
fragment_2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textview_fragment_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="This is Fragment 2"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textview_fragment_2_result"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="I will display text from \nFragment 1"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
Now, I have an Edittext and button in the fragment_1. When I click on the button, I want to get the text entered in EditText and set it to the textview(textview_fragment_2_result) in fragment_2
I was able to achieve this, but, I am not very convinced, that the approach I took was good enough. Please look at the java code below..
Fragment1Activity.java
public class Fragment1Activity extends SherlockFragmentActivity implements Fragment1.ButtonClickListener{
Fragment1 fragment1;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_for_fragment_1);
System.out.println("onCreate Fragment1Activity");
fragment1 = (Fragment1) getSupportFragmentManager().findFragmentById(R.id.fragment_1);
}
#Override
public void onButtonClick(String message) {
System.out.println("onButtonClick Fragment1Activity");
startActivity(new Intent(this, Fragment2Activity.class).putExtra("message", message));
}
}
Fragment1.java
public class Fragment1 extends SherlockFragment {
EditText message;
Button clickme;
ButtonClickListener listener;
public interface ButtonClickListener{
public void onButtonClick(String message);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof ButtonClickListener)
listener = (ButtonClickListener) activity;
else {
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
System.out.println("onCreateView Fragment1");
View view = inflater.inflate(R.layout.fragment_1, container, false);
message = (EditText) view.findViewById(R.id.edittext_fragment_1_text);
clickme = (Button) view.findViewById(R.id.button_fragment_1);
clickme.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (!message.getText().toString().equalsIgnoreCase("")) {
System.out.println("Message in Fragment1 = "+message.getText().toString());
listener.onButtonClick(message.getText().toString());
} else {
Toast.makeText(getActivity(),
"Please enter some message...", Toast.LENGTH_LONG)
.show();
}
}
});
return view;
}
}
Fragment2Activity.java
public class Fragment2Activity extends SherlockFragmentActivity {
Fragment2 fragment2;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_for_fragment_2);
fragment2 = (Fragment2) getSupportFragmentManager().findFragmentById(R.id.fragment_2);
fragment2.setMessage(getIntent().getExtras().getString("message").toString());
}
}
Fragment2.java
public class Fragment2 extends SherlockFragment {
String msg;
TextView textview;
public Fragment2() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_2, container, false);
textview = (TextView) view
.findViewById(R.id.textview_fragment_2_result);
textview.setText(msg);
return view;
}
public void setMessage(String message) {
msg = message;
textview.setText(msg);
}
}
I have set the text for textview in setMessage() of Fragment2.java, which I think is not a good approach. If i comment that out, I don't see any text in the textview of Fragment2.
Can someone help me out, on how to pass values between two static fragments correctly.
You should go with interface
Follow the Diagram Here :
Communication Between Two Fragment is Done Via Activity using Interface
Fragment A-------------------------->Activity-------------------->Fragment B
(defines Interface) (Implement interface) (pass it other Fragment B)
Hope this could help
Check This Out
What you have is mostly good. The part of transferring the data from Fragment1 to Activity1 is good. Once the data gets to Activity2, you are setting it in Fragment2. I would change this part a little.
In Activity2:
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_for_fragment_2);
fragment2 = (Fragment2) getSupportFragmentManager().findFragmentById(R.id.fragment_2);
fragment2.setArguments(getIntent().getExtras());
}
and in Fragment2.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle bundle = getArguments();
String message = bundle.getString("message");
View view = inflater.inflate(R.layout.fragment_2, container, false);
textview = (TextView) view
.findViewById(R.id.textview_fragment_2_result);
textview.setText(message);
return view;
}
Your approach seems correct. The connection between your Fragment1 and Activity1 is just like in the fragments guideline. Your fragment1 shouldn't know about fragment2 therefore it's OK to pass the responsibility to the fragment's container/parent - activity1 - that knows what to do with the data. This time again your approach is correct - activity1 starts it's slave/child etc. and is responsible to start it with correct data (passed through the intent extras). And then again you have a correct approach - when your activity2 is created you populate it's views with the appropriate content/data (the message) that was meant to be displayed in this activity and given to it by the "parent" activity.
this is my first fragment which open a fragment through xml layout
public class ListFrag extends SherlockFragment implements OnItemClickListener
{
Context c;
List<ReferalRow> referal_RowItems;
DoctorDaoImpl doctorDao;
DoctorServiceImpl service;
DoctorValidator doctorValidator;
View layoutView;
ListView doctoListView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
layoutView = inflater.inflate(R.layout.activity_refer_mangmnt, null);
return layoutView;
}
and this is my activity_refer_mangmnt.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="5dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="2"
android:padding="2dp">
<ListView
android:id="#+id/listView_refer_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:dividerHeight="1dp"
android:divider="#android:color/black"
android:choiceMode="singleChoice"
android:listSelector="#drawable/list_selector" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/rightpanel_back">
<fragment
android:id="#+id/detail_fragment"
android:tag="detailfrag"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.app1.DetailsFrag" />
</LinearLayout>
`</LinearLayout>
and this is my DetailFrag class
public class DetailsFrag extends SherlockFragment
{
ExpandableListView detailList;
TextView tvMessage;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
contentView = inflater.inflate(R.layout.activity_refer_view, null);
detailList = (ExpandableListView) contentView.findViewById(R.id.ep_detail_view);
tvMessage = (TextView)contentView.findViewById(R.id.tv_textView);
return contentView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
if(id==0)
{
detailList.setVisibility(View.GONE);
tvMessage.setText("Click on the item on the left panel to view the details");
}
else
{
detailList.setVisibility(View.VISIBLE);
tvMessage.setVisibility(View.GONE);
}
and this is my onItem click listener in LIstFrag
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment lastFrag = getFragmentManager().findFragmentByTag("detailfrag");
if(lastFrag!=null)
ft.remove(lastFrag);
Fragment fragment = Fragment.instantiate(c, DoctorDetailsFrag.class.getName(),arguments);
ft.replace(R.id.detail_fragment, fragment);
ft.commit();
i need when first time i want to display a message in the right panel after click on the item in the list i want to disappear that message. but here the message is not remove from the fragment. its displayed in the backgrnd of new fragment. y it is?
Try:
ft.addToBackStack(null)
after you call: ft.remove(lastFrag);
Perhaps this link can help you to understand this transaction:
http://developer.android.com/guide/components/fragments.html#Transactions
Another way is to to reuse your lastFrag when it's not null. Then you need a method in your DetailFrag that is called from your clickListener.