I tried to make a small app practicing inter-fragment communication. Each time the button in the top-left fragment is clicked, the counter in the base fragment updates and displays the number of clicks.
I tried to use the onSaveInstanceState() method to preserve data so that upon rotations of the screen, the accumulated number of clicks could still be correctly presented. And by using the Log, I've seen the data being preserved during rotation, however, I do not understand why even though I set the content of the TextView using the preserved data, it would revert to the state as if the fragment was being first created.
Here's my code:
package com.example.fragmenttrial;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends ActionBarActivity implements Communicator {
private static final String DT = "Activity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(DT, "onCreate()");
HelloFragment fragment1 = new HelloFragment();
TrialFragment fragment2 = new TrialFragment();
BaseFragment fragment3 = new BaseFragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.hello_placeholder, fragment1, "myHelloFragment");
transaction.replace(R.id.trial_placeholder, fragment2, "myTrialFragment");
transaction.replace(R.id.base_placeholder, fragment3, "myBaseFragment");
transaction.commit();
}
protected void onStart() {
Log.e(DT,"onStart()");
super.onStart();
}
protected void onPause() {
Log.e(DT, "onPause()");
super.onPause();
}
protected void onResume() {
Log.e(DT, "onResume()");
super.onResume();
}
protected void onRestart() {
Log.e(DT, "onRestart()");
super.onRestart();
}
protected void onStop() {
Log.e(DT, "onStop()");
super.onStop();
}
protected void onDestroy() {
Log.e(DT, "onDestroy()");
super.onDestroy();
}
protected void onSaveInstanceState(Bundle bundle) {
Log.e(DT, "onSaveInstanceState()");
super.onSaveInstanceState(bundle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.e(DT, "onCreateOptionsMenu()");
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, 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.
Log.e(DT, "onOptionsItemSelected");
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void respond(int times) {
// TODO Auto-generated method stub
BaseFragment fragment = (BaseFragment) getSupportFragmentManager().findFragmentById(R.id.base_placeholder);
fragment.changeData(times);
if(times == 10) {
SimpleFragment mFrag = new SimpleFragment();
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
trans.replace(R.id.trial_placeholder, mFrag);
trans.commit();
}
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.fragmenttrial.MainActivity"
tools:ignore="MergeRootFrame"
android:background="#0000FF">
<LinearLayout
android:id="#+id/my_linear"
android:layout_height="0dp"
android:layout_width="fill_parent"
android:layout_weight="1"
android:orientation="horizontal">
<RelativeLayout
android:id="#+id/hello_placeholder"
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:background="#F2E0F7"
/>
<RelativeLayout
android:id="#+id/trial_placeholder"
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:background="#FFFF00"
/>
</LinearLayout>
<RelativeLayout
android:id="#+id/base_placeholder"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1"
android:background="#DF013A"
/>
</LinearLayout>
Top left fragment(HelloFragment.java)
package com.example.fragmenttrial;
import javax.security.auth.login.LoginException;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
public class HelloFragment extends Fragment implements View.OnClickListener {
private int times = 0;
Communicator comm;
public static final String FT = "Fragment";
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(FT, "onCreateView()-hello");
View v = inflater.inflate(R.layout.hello_frag, container, false);
Button b = (Button) v.findViewById(R.id.button);
b.setOnClickListener(this);
return v;
}
public void onCreate(Bundle savedInstanceState) {
Log.i(FT, "onCreate()-hello");
super.onCreate(savedInstanceState);
if(savedInstanceState == null) {
//first time of creation
} else {
times = savedInstanceState.getInt("counter");
}
}
public void onSaveInstanceState(Bundle outState) {
Log.i(FT, "onSaveInstanceState()-hello");
super.onSaveInstanceState(outState);
outState.putInt("counter", times);
}
#Override
public void onClick(View v) {
times++;
comm.respond(times);
}
public void onAttach(Activity activity) {
Log.i(FT, "onAttach()-hello");
super.onAttach(activity);
comm = (Communicator) activity;
}
public void onActivityCreated(Bundle savedInstanceState) {
Log.i(FT, "onActivityCreated()-hello");
super.onActivityCreated(savedInstanceState);
}
public void onViewStateRestored(Bundle savedInstanceState) {
Log.i(FT, "onViewStateRestored()-hello");
super.onViewStateRestored(savedInstanceState);
}
public void onStart() {
Log.i(FT, "onStart()-hello");
super.onStart();
}
public void onResume() {
Log.i(FT, "onResume()-hello");
super.onResume();
}
public void onPause() {
Log.i(FT, "onPause()-hello");
super.onPause();
}
public void onStop() {
Log.i(FT, "onStop()-hello");
super.onStop();
}
public void onDestroy() {
Log.i(FT, "onDestroy()-hello");
super.onDestroy();
}
public void onDestroyView() {
Log.i(FT, "onDestroyView()-hello");
super.onDestroyView();
}
public void onDetach() {
Log.i(FT,"onDetach()-hello");
super.onDetach();
}
}
hello_frag.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#DA81F5"
android:text="Hello world!"
android:textColor="#ffffff"
android:onClick="onClick"/>
</RelativeLayout>
BaseFragment.java
package com.example.fragmenttrial;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class BaseFragment extends Fragment {
int counter;
TextView textView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(HelloFragment.FT, "onCreateView()-Base");
View v = inflater.inflate(R.layout.base_frag, container, false);
textView = (TextView) v.findViewById(R.id.text);
if(savedInstanceState == null) {
//first time being created
} else {
counter = savedInstanceState.getInt("counter");
System.out.println(counter);
textView.setText("Button was clicked: " + counter + " times.");
System.out.println(textView.getText().toString());
}
return v;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
public void changeData(int data) {
counter = data;
textView.setText("Button was clicked: " + data + " times.");
}
public void onSaveInstanceState(Bundle outState) {
Log.i(HelloFragment.FT,"onSaveInstanceState()-Base");
super.onSaveInstanceState(outState);
outState.putInt("counter", counter);
}
}
base_frag.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0B4C5F">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Number of clicks: "
android:textColor="#000000"
android:background="#android:color/transparent"/>
</RelativeLayout>
And the log cat after rotating:
06-20 12:03:10.929: E/Activity(7185): onPause()
06-20 12:03:10.929: I/Fragment(7185): onPause()-hello
06-20 12:03:10.929: E/Activity(7185): onSaveInstanceState()
06-20 12:03:10.976: I/Fragment(7185): onSaveInstanceState()-hello
06-20 12:03:10.980: I/Fragment(7185): onSaveInstanceState()-Base
06-20 12:03:10.984: E/Activity(7185): onStop()
06-20 12:03:10.984: I/Fragment(7185): onStop()-hello
06-20 12:03:10.984: E/Activity(7185): onDestroy()
06-20 12:03:10.984: I/Fragment(7185): onDestroyView()-hello
06-20 12:03:10.988: I/Fragment(7185): onDestroy()-hello
06-20 12:03:10.988: I/Fragment(7185): onDetach()-hello
06-20 12:03:11.113: I/Fragment(7185): onAttach()-hello
06-20 12:03:11.113: I/Fragment(7185): onCreate()-hello
06-20 12:03:11.207: E/Activity(7185): onCreate()
06-20 12:03:11.211: E/Activity(7185): onStart()
06-20 12:03:11.211: I/Fragment(7185): onCreateView()-hello
06-20 12:03:11.218: I/Fragment(7185): onActivityCreated()-hello
06-20 12:03:11.218: I/Fragment(7185): onViewStateRestored()-hello
06-20 12:03:11.242: I/Fragment(7185): onCreateView()-Base
06-20 12:03:11.250: D/dalvikvm(7185): GC_CONCURRENT freed 153K, 3% free 8277K/8519K, paused 30ms+22ms, total 101ms
06-20 12:03:11.254: I/System.out(7185): 3
06-20 12:03:11.254: I/System.out(7185): Button was clicked: 3 times.
06-20 12:03:11.254: I/Fragment(7185): onDestroyView()-hello
06-20 12:03:11.254: I/Fragment(7185): onDestroy()-hello
06-20 12:03:11.254: I/Fragment(7185): onDetach()-hello
06-20 12:03:11.257: I/Fragment(7185): onAttach()-hello
06-20 12:03:11.257: I/Fragment(7185): onCreate()-hello
06-20 12:03:11.257: I/Fragment(7185): onCreateView()-hello
06-20 12:03:11.261: I/Fragment(7185): onActivityCreated()-hello
06-20 12:03:11.261: I/Fragment(7185): onViewStateRestored()-hello
06-20 12:03:11.261: I/Fragment(7185): onCreateView()-Base
06-20 12:03:11.269: I/Fragment(7185): onStart()-hello
06-20 12:03:11.269: E/Activity(7185): onCreateOptionsMenu()
06-20 12:03:11.273: E/Activity(7185): onResume()
06-20 12:03:11.273: I/Fragment(7185): onResume()-hello
It's seen that in the middle the textview text field was changed. However, when displayed it changes back to the initial state "Number of clicks: " as defined in the XML.
Related
In portrait, it gives null point exceptioin when the list item is clicked but landscape works just fine... In AnotherAcitivity.java Fragment f2 gets null while debugged...
package com.example.myfragmentqadvancedel;
import com.example.myfragmentqadvancedel.FragmentA.Communicator;
import android.os.Bundle;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
public class MainActivity extends Activity implements Communicator{
FragmentA f1;
FragmentB f2;
FragmentManager manager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = getFragmentManager();
f1=(FragmentA) manager.findFragmentById(R.id.fragment1);
f1.setCommunicator(this);
}
#Override
public void respond(int index) {
f2=(FragmentB) manager.findFragmentById(R.id.fragment2);
if (f2!=null && f2.isVisible()) {
f2.changeData(index );
}else {
Intent intent = new Intent(this,AnotherActivity.class);
intent.putExtra("index", index);
startActivity(intent);
}
}
}
FragmentA
package com.example.myfragmentqadvancedel;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class FragmentA extends Fragment implements OnItemClickListener {
ListView list;
Communicator communicator;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment_a, container,false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
list=(ListView) getActivity().findViewById(R.id.listView1);
ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(), R.array.chapters, android.R.layout.simple_list_item_1);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
}
public void setCommunicator(Communicator communicator) {
this.communicator = communicator;
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int i, long arg3) {
communicator.respond(i);
}
public interface Communicator{
public void respond(int index);
}
}
AnotherActivity.java
package com.example.myfragmentqadvancedel;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
public class AnotherActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another);
Intent intent = getIntent();
int index=intent.getIntExtra("index", 0);
FragmentB f2= (FragmentB) getFragmentManager().findFragmentById(R.id.fragment2);
if(f2!=null) <-- f2 gets null, index gets +ve value as checked in debugger
f2.changeData(index);
}
}
FragmentB
package com.example.myfragmentqadvancedel;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class FragmentB extends Fragment{
TextView text;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container,false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
text=(TextView) getActivity().findViewById(R.id.textView1);
}
public void changeData(int index){
String[] descriptions = getResources().getStringArray(R.array.description);
text.setText(descriptions[index]);
}
}
logcat
05-27 16:40:37.866: E/AndroidRuntime(961): FATAL EXCEPTION: main
05-27 16:40:37.866: E/AndroidRuntime(961): java.lang.NullPointerException
05-27 16:40:37.866: E/AndroidRuntime(961): at com.example.myfragmentqadvance.MainActivity.respond(MainActivity.java:26)
05-27 16:40:37.866: E/AndroidRuntime(961): at com.example.myfragmentqadvance.Fragment1.onItemClick(Fragment1.java:42)
05-27 16:40:37.866: E/AndroidRuntime(961): at android.widget.AdapterView.performItemClick(AdapterView.java:298)
05-27 16:40:37.866: E/AndroidRuntime(961): at android.widget.AbsListView.performItemClick(AbsListView.java:1100)
activity_main.xml
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<fragment
android:id="#+id/fragment1"
android:name="com.example.myfragmentqadvancedel.FragmentA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
fragment_a.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"
android:background="#0f0">
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
fragment_b.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"
android:background="#00f" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="#fff"/>
</LinearLayout>
activity_another.xml
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".AnotherActivity" >
<fragment
android:id="#+id/fragment2"
android:name="com.example.myfragmentqadvancedel.FragmentB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="38dp" />
</RelativeLayout>
Your interface in Fragment A seems to be Null. Instead of setting the Interface after finding fragment by id, you should use onAttach(Activity activity) method. Here you can force your parent Activity to implement this interface. Check out the code below.
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
/* Check if the Activity implemented Callbacks from this Fragment */
try {
communicator = (Communicator) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement " + this.getClass().getSimpleName() + "Callbacks");
}
}
when i keep the code frm onCreate to onStart of AnotherActivity , it works... dont know whats the prob to put them in onCreate
public class AnotherActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another);
}
#Override
protected void onStart() {
super.onStart();
Intent intent = getIntent();
int index=intent.getIntExtra("index", 0);
FragmentB f2= (FragmentB) getFragmentManager().findFragmentById(R.id.fragment2);
if(f2!=null)
f2.changeData(index);
}
}
There is one activity MainActivity.
there are two fragmnet
FragmentOne
FragmentTwo
Q.1 - initially first fragment loaded with activity.
and all the method related to this fragment called(like onAttach, oncreate, onCreateview, onViewCreated, onActivityCreated).
but when i click on button2(see above xml). it will not call on pause of the already loaded fragment, it will again start
new fragment with start(onAttach, oncreate, onCreateview, onViewCreated, onActivityCreated). so how this work?
Q.2 - IS it necessary to always
define android:name="com.example.fragexample.FragmentOne" class name with fragment when making defining fragment tab?
This is my main Activity layout
<?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" >
<Button
android:id="#+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Fragment No.1"
android:onClick="selectFrag" />
<Button
android:id="#+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="selectFrag"
android:text="Fragment No.2" />
<Button
android:id="#+id/btn_go_to_next_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Go To Home Activity"
android:onClick="goToNextActivity"
/>
<fragment
android:name="com.example.fragexample.FragmentOne"
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Fragment One Code
package com.example.fragexample;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentOne extends Fragment {
public static String FragmentOneTag = "FragmentOne";
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
//Inflate the layout for this fragment
//Toast.makeText(getActivity(), "FragmentOne - "+container+" bundle -- "+savedInstanceState, Toast.LENGTH_LONG).show();
Log.i(FragmentOneTag, "onCreateView: "+"inflater -- "+inflater+" container -- "+container+" bundle -- "+savedInstanceState);
//Log.i(FragmentOneTag, "inflater -- "+inflater+" container -- "+container+" bundle -- "+savedInstanceState);
return inflater.inflate(R.layout.fragment_one, container, false);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.i(FragmentOneTag, "onAttach"+" Activity:"+activity);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(FragmentOneTag, "onCreate: savedInstanceState:"+savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i(FragmentOneTag, "onActivityCreated"+" savedInstanceState"+savedInstanceState);
}
#Override
public void onStart() {
super.onStart();
Log.i(FragmentOneTag, "onStart");
}
#Override
public void onResume() {
super.onResume();
Log.i(FragmentOneTag, "onResume");
}
#Override
public void onPause() {
super.onPause();
Log.i(FragmentOneTag, "onPause");
}
#Override
public void onStop() {
super.onStop();
Log.i(FragmentOneTag, "onStop");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(FragmentOneTag, "onDestroy");
}
#Override
public void onDestroyView() {
super.onDestroyView();
Log.i(FragmentOneTag, "onDestroyView");
}
#Override
public void onDetach() {
super.onDetach();
Log.i(FragmentOneTag, "onDetach");
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.i(FragmentOneTag, "onViewCreated "+"view:"+view+" savedInstanceState:"+savedInstanceState);
}
}
Fragment Two Code
package com.example.fragexample;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentTwo extends Fragment{
private static String FragmentTWOTag = "FragmentTwo";
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
Log.i(FragmentTWOTag, "onCreateView");
// Toast.makeText(getActivity(),"inflater -- "+inflater+" FragmentTWo - "+container+" bundle -- "+savedInstanceState, Toast.LENGTH_LONG).show();
Log.i("FragmentTwo", "inflater -- "+inflater+" container -- "+container+" bundle -- "+savedInstanceState);
return inflater.inflate(
R.layout.fragment_two, container, false);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.i(FragmentTWOTag, "onAttach");
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(FragmentTWOTag, "onCreate");
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i(FragmentTWOTag, "onActivityCreated");
}
#Override
public void onStart() {
super.onStart();
Log.i(FragmentTWOTag, "onStart");
}
#Override
public void onResume() {
super.onResume();
Log.i(FragmentTWOTag, "onResume");
}
#Override
public void onPause() {
super.onPause();
Log.i(FragmentTWOTag, "onPause");
}
#Override
public void onStop() {
super.onStop();
Log.i(FragmentTWOTag, "onStop");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(FragmentTWOTag, "onDestroy");
}
#Override
public void onDestroyView() {
super.onDestroyView();
Log.i(FragmentTWOTag, "onDestroyView");
}
#Override
public void onDetach() {
super.onDetach();
Log.i(FragmentTWOTag, "onDetach");
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
Log.i(FragmentTWOTag, "onViewCreated");
}
}
i am showing intial screen with first fragment.
first screen have two options button
Fragment No.1 and Fragment No.2
click on Fragment No.1 will load first fragment
click on Fragment No.2 will load second fragment
please guide me how its working.
Thanks In advance.
I am getting an error that I have not been able to figure out after weeks of trying.
I am trying to do an example of a fragment that opens another dialog fragment when i click a button.
The dialog fragment has an edittext view that i am trying to use to enter a name and then when i click ok the fragment is suppose to use an interface to complete a callback to the calling fragment and then to take the text from the edittext and use it to update the text in a textview in the first fragment's layout, but no matter what i do it will not work.
I have run out of ideas of what is wrong and how to fix it. any help would be greatly appreciated.
the compiler says line 72 gives the error in DialogFragment (NullPointerException)
(I put a // line 72 comment on that line)
mListener.setsNewUsername(etEnteredName.getText().toString());// line 72
main activity
package com.example.fragments;
import android.os.Bundle;
import android.app.Activity;
import android.app.DialogFragment;
import android.widget.TextView;
public class FragmentsActivity extends Activity
implements SignInDialogFragment.MyDialogListener{
String sNewUsername = new String("[Enter Username]");
public void setsNewUsername(String sNewUsername) {
this.sNewUsername = sNewUsername;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public void onDialogPositiveClick(DialogFragment dialog) {
TextView textViewFrag1 =(TextView)dialog.getActivity().findViewById(R.id.textViewFragment1);
textViewFrag1.setText("Hello" + sNewUsername);
}
#Override
public void onDialogNegativeClick(DialogFragment dialog) {
}
}
main fragment
package com.example.fragments;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
public class Fragment1 extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
Log.d("Fragment 1", "onCreateView");
return inflater.inflate(R.layout.fragment1, container,false);
}
public void onAttach(Activity activity){
super.onAttach(activity);
Log.d("Fragment 1", "onAttach");
}
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Log.d("Fragment 1", "onCreate");
}
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
Log.d("Fragment 1", "onActivityCreated");
}
public void onStart(){
super.onStart();
Button btnShowSignin = (Button)getActivity().findViewById(R.id.btnShowSignInDialog);
btnShowSignin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SignInDialogFragment signinDialog = new SignInDialogFragment();
signinDialog.show(getFragmentManager(), null);
}
});
Log.d("Fragment 1", "onStart");
}
public void onResume(){
super.onResume();
Log.d("Fragment 1", "onResume");
}
#Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.d("Fragment 1", "onPause");
}
public void onStop(){
super.onStop();
Log.d("Fragment 1", "onStop");
}
public void onDestroyView(){
super.onDestroyView();
Log.d("Fragment 1", "onDestroyView");
}
public void onDestroy(){
super.onDestroy();
Log.d("Fragment 1", "onDestroy");
}
public void onDetach(){
super.onDetach();
Log.d("Fragment 1", "onDetach");
}
}
dialog fragment
package com.example.fragments;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
public class SignInDialogFragment extends DialogFragment {
View dialogView;
EditText etEnteredName;
String enteredUserName = new String("My Name");
public String getEnteredUserName() {
return enteredUserName;
}
public void setEnteredUserName(String enteredUserName) {
this.enteredUserName = enteredUserName;
}
public interface MyDialogListener {
public void setsNewUsername(String string);
public void onDialogPositiveClick(DialogFragment dialog);
public void onDialogNegativeClick(DialogFragment dialog);
}
MyDialogListener mListener;
public void onAttach(Activity activity) {
super.onAttach(activity);
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
mListener = (MyDialogListener) activity;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString()
+ " must implement NoticeDialogListener");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return super.onCreateView(inflater, container, savedInstanceState);
}
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
builder.setView(inflater.inflate(R.layout.signin, null))
.setPositiveButton("SignIn", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
etEnteredName = (EditText)getActivity().findViewById(R.id.username);
mListener.setsNewUsername(etEnteredName.getText().toString()); // line 72
mListener.onDialogPositiveClick(SignInDialogFragment.this);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
return builder.create();
}
#Override
public void dismiss() {
// TODO Auto-generated method stub
super.dismiss();
}
#Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
}
#Override
public void onDetach() {
// TODO Auto-generated method stub
super.onDetach();
}
#Override
public void onDismiss(DialogInterface dialog) {
// TODO Auto-generated method stub
super.onDismiss(dialog);
}
#Override
public void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<fragment
android:name="com.example.fragments.Fragment1"
android:id="#+id/fragment1"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"
/>
</LinearLayout>
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"
android:background="#00FF00">
<TextView
android:id="#+id/textViewFragment1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="SignIn Dialog Text Here"
android:textColor="#000000"
android:textSize="25sp"
/>
<Button
android:id="#+id/btnShowSignInDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show SignIn Dialog"
android:textColor="#000000"
android:onClick="onClick"
/>
</LinearLayout>
signin.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<EditText
android:id="#+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="4dp"
/>
</LinearLayout>
Change this
etEnteredName = (EditText)getActivity().findViewById(R.id.username);
to
View v = inflater.inflate(R.layout.signin,null);
etEnteredName = (EditText)v.findViewById(R.id.username);
You need to use the inflated view object to initialize your EditText. EditText is in R.layout.signin. findViewById looks for a view with the id mentioned in the current inflated layout.
Declare View v; as a instance variable.
Then
v = inflater.inflate(R.layout.signin,null);
builder.setView(v);
Then
etEnteredName = (EditText)v.findViewById(R.id.username);
I get the error
Unable to start activity ComponentInfo{de.androidbuch.activiti/de.androidbuch.activiti.task.Activity}: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
i read Error inflating class fragment in Android android,
Error inflating class fragment
but it does not work for me
package com.example.fragments;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
public class MainActivity extends FragmentActivity {
String LOG_TAG = "myLogs";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(LOG_TAG, "MainActivity onCreate");
}
protected void onStart() {
super.onStart();
Log.d(LOG_TAG, "MainActivity onStart");
}
protected void onResume() {
super.onResume();
Log.d(LOG_TAG, "MainActivity onResume");
}
protected void onPause() {
super.onPause();
Log.d(LOG_TAG, "MainActivity onPause");
}
protected void onStop() {
super.onStop();
Log.d(LOG_TAG, "MainActivity onStop");
}
protected void onDestroy() {
super.onDestroy();
Log.d(LOG_TAG, "MainActivity onDestroy");
}
}
Fragment 1
package com.example.fragments;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Frag1 extends Fragment {
final String LOG_TAG = "myLogs";
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.d(LOG_TAG, "Fragment1 onAttach");
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(LOG_TAG, "Fragment1 onCreate");
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.frag1, null);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(LOG_TAG, "Fragment1 onActivityCreated");
Log.d(LOG_TAG, "Fragment1 onCreateView");
}
public void onStart() {
super.onStart();
Log.d(LOG_TAG, "Fragment1 onStart");
}
public void onResume() {
super.onResume();
Log.d(LOG_TAG, "Fragment1 onResume");
}
public void onPause() {
super.onPause();
Log.d(LOG_TAG, "Fragment1 onPause");
}
public void onStop() {
super.onStop();
Log.d(LOG_TAG, "Fragment1 onStop");
}
public void onDestroyView() {
super.onDestroyView();
Log.d(LOG_TAG, "Fragment1 onDestroyView");
}
public void onDestroy() {
super.onDestroy();
Log.d(LOG_TAG, "Fragment1 onDestroy");
}
public void onDetach() {
super.onDetach();
Log.d(LOG_TAG, "Fragment1 onDetach");
}
}
Fragment 2
package com.example.fragments;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Frag2 extends Fragment {
final String LOG_TAG = "myLogs";
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.d(LOG_TAG, "Fragment1 onAttach");
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(LOG_TAG, "Fragment1 onCreate");
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(LOG_TAG, "Fragment1 onCreateView");
return inflater.inflate(R.layout.frag2, null);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(LOG_TAG, "Fragment1 onActivityCreated");
}
public void onStart() {
super.onStart();
Log.d(LOG_TAG, "Fragment1 onStart");
}
public void onResume() {
super.onResume();
Log.d(LOG_TAG, "Fragment1 onResume");
}
public void onPause() {
super.onPause();
Log.d(LOG_TAG, "Fragment1 onPause");
}
public void onStop() {
super.onStop();
Log.d(LOG_TAG, "Fragment1 onStop");
}
public void onDestroyView() {
super.onDestroyView();
Log.d(LOG_TAG, "Fragment1 onDestroyView");
}
public void onDestroy() {
super.onDestroy();
Log.d(LOG_TAG, "Fragment1 onDestroy");
}
public void onDetach() {
super.onDetach();
Log.d(LOG_TAG, "Fragment1 onDetach");
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<fragment
android:name="ru.startandroid.develop.p1041fragmentlifecycle.Fragment1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
</fragment>
<fragment
android:name="ru.startandroid.develop.p1041fragmentlifecycle.Fragment2"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
</fragment>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="frag1_text" >
</TextView>
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="frag2_text" >
</TextView>
When you use
android:name="ru.startandroid.develop.p1041fragmentlifecycle.Fragment1"
you need to provide the package name. From your frag1.java file the package name is package com.example.fragments; So for the xml file you would want to use
android:name="com.example.fragments.Frag1"
or just for short:
android:name=".Frag1"
See this for more details.
I am working with the android support library, to be able to use fragments from Froyo, and the Sherlock extension, to show an ActionBar.
I have a fragment which shows three textViews and a button, and I want to be able to change the button text dinamically, depending on the content of the Intent. The problem is that when I call button.setText(String text), a second button appears. However, I've called button.getId() when clicking on each of them, and the Id is the same. I don't have a clue of why this is happening, so I'd appreciate some help.
The app is run on a Samsung Galaxy S, with Android 2.3.3. I can't upload a screen capture because I don't have enough reputation yet :(
This is the code:
FRAGMENT
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import com.actionbarsherlock.app.SherlockFragment;
import com.parse.ParseUser;
import com.tiempoderodar.egdf.EGDF_App;
import com.tiempoderodar.egdf.R;
import com.tiempoderodar.egdf.security.Constants;
/**
* #author Daniel Leal López
*
*/
public class ChapterDetailsFragment extends SherlockFragment{
private Button b;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("ChapterDetailsFragment", "Created");
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ParseUser user = EGDF_App.getUser();
b = (Button) getSherlockActivity().findViewById(R.id.buttonWatchChapter);
if (user != null){
String chapterNumber = "";
Bundle extras = getSherlockActivity().getIntent().getExtras();
String s = extras.getString(Constants.CHAPTER_NUMBER_PARSE);
if((s != null)&&(!s.equals(""))){
// tvNumber.setText(s);
chapterNumber = "Chapter_" + s;
Log.i("Properties", s);
}
String seen = user.getString(chapterNumber);
if((seen != null)&&(!seen.equals(""))&&(seen.equals(Constants.USER_CHAPTER_SEEN))){
b.setText("Second text: "+getString(R.string.watch_chapter_button_text));
Log.i("BUTTON CHANGED", "Text changed to watch");
}
else if((seen != null)&&(!seen.equals(""))&&(seen.equals(Constants.USER_CHAPTER_NOT_SEEN))){
b.setText("Second text: " + getString(R.string.buy_chapter_button_text));
Log.i("BUTTON CHANGED", "Text changed to buy");
}else{
Log.w("DEV ERROR", "Chapter text not obtained");
}
}else{
Log.w("DEV ERROR", "ParseUser is null in EGDF_App!!!");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.chapter_details, container, false);
return view;
}
public void setText(String item) {
getSherlockActivity().getSupportActionBar().setTitle(item);
}
public void setButtonText(String text){
b.setText(text);
}
}
Activity
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.actionbarsherlock.app.SherlockFragmentActivity;
public class ChapterDetailsActivity extends SherlockFragmentActivity {
private Bundle extras;
MediaPlayer mMediaPlayer;
private String chapterNumber;
private boolean isChapterSeen;
// private int duration;
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Theme_Sherlock_Light_DarkActionBar);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chapter_details);
if (savedInstanceState == null) {
// During initial setup, plug in the details fragment.
ChapterDetailsFragment details = new ChapterDetailsFragment();
details.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction().add(
android.R.id.content, details).commit();
}
}
public void watchChapter(View view){
Log.i("Button", "Watch chapter button PRESSED");
Button b = (Button) view;
Log.d("BUTTON PARENT VIEW", b.getParent().getClass().getName());
Log.d("BUTTON ID", String.valueOf(b.getId()));
String loadChapter = getString(R.string.load_chapter_button_text);
String watchChapter = getString(R.string.watch_chapter_button_text);
String buyChapter = getString(R.string.buy_chapter_button_text);
}
#Override
protected void onPause() {
Log.i("Activity lifecycle", "On pause called");
super.onPause();
}
#Override
protected void onStop() {
Log.i("Activity lifecycle", "On stop called");
super.onStop();
}
#Override
protected void onDestroy() {
Log.i("Activity lifecycle", "On destroy called");
super.onDestroy();
EGDF_App.releaseMediaPlayer();
}
#Override
protected void onResume() {
Log.i("Activity lifecycle", "On resume called");
super.onResume();
}
#Override
protected void onStart() {
Log.i("Activity lifecycle", "On start called");
super.onStart();
}
}
Activity layout
<?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" >
<fragment
android:id="#+id/chapterDetailsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.tiempoderodar.egdf.content.ChapterDetailsFragment" />
</LinearLayout>
Fragment Layout
<?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/textViewChapterNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="30dip" />
<TextView
android:id="#+id/textViewChapterSeason"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="30dip" />
<TextView
android:id="#+id/textViewChapterSinopsis"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="30dip" />
<TextView
android:id="#+id/textViewChapterCredits"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="30dip" />
<Button
android:id="#+id/buttonWatchChapter"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="#string/watch_chapter_button_text"
android:layout_gravity="center"
android:onClick="watchChapter"/>
</LinearLayout>
Thanks!
I think I might have found the problem. I was calling
b = (Button) getSherlockActivity().findViewById(R.id.button);
but it should be
b = (Button) getView().findViewById(R.id.button);
With that change it works correctly