Fragment Transaction inside worker thread - android

Basically i tried doing a fragment transaction inside a background thread, and i get can't perform this action after onSavedInstanceState. This is what i have done:
I have an activity with two fragments, Fragment A (Contains UI all elements) and Fragment B(contains progress bar) . When the activity is created fragment A is added so the user sees UI elements(Buttons and Edittexts). Then when a button is clicked in Fragment A, (1) a background task is started in the parent activity, and (2) Fragment A is replaced with Fragment B. All this works fine.
But when the task is finished if the task was successful i would like to start a new activity and if it fails i want the current fragment to be replaced with the original one. I have no problem with starting the activity, but when i try to do the fragment transaction, the app crashes saying can't perform this action after onSavedInstanceState.
I did a lot of research on this and found a lot of useful things here, here, but i still haven't been able to solve my problem. The first link is a question on SO, one of the answers was to shift calling the fragment transaction to the onResume method of the activity, but i don't know how to do this. Also i tried using commitAllowingStateLoss and the app still crashes, but the logcat says Activity has been destroyed.
Note: If there is no configuration change, everything runs smoothly.
Here is my Code:
Containing Activity
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("tag", "mainActivity onCreate");
Fragment taskf =getSupportFragmentManager().findFragmentByTag("taskfrag");
//Put the Fragment A if Fragment B is not showing
if(savedInstanceState == null){
if(taskf == null){
Log.i("tag", "MainFragment added");
FragmentTransaction fragmentTransaction= getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.wrapper, new MainFragment() , "mainfrag").commit();
}
}
}
//Fragment B is added here
public void addFragment(){
Log.i("tag", "fragment added");
this.getSupportFragmentManager().beginTransaction().replace(R.id.wrapper, new TaskFragment(), "taskfrag").commit();
}
// My dummy Task
public void startTask(){
Log.i("tag", "start Task");
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 100; i++) {
Log.i("tag", "publishProgress(" + i + "%)");
SystemClock.sleep(100);
}
getSupportFragmentManager().beginTransaction().replace(R.id.wrapper, new MainFragment(), "mainfrag").commitAllowingStateLoss();
}
}).start();
}
}
Fragment A
public class MainFragment extends Fragment {
View fView;
ProgressBar bar;
TextView textView;
Button button;
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i("tag", "onCreate in Main Fragment ");
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.i("tag", "onCreate View in Mainfragment");
fView = inflater.inflate(R.layout.mainfragment, container, false);
textView = (TextView) fView.findViewById(R.id.textview);
button = (Button) fView.findViewById(R.id.button);
//Button Click Listener
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Log.i("tag", "button clicked");
((MainActivity)getActivity()).startTask();
((MainActivity)getActivity()).addFragment();
}
});
return fView;
}
}
Fragment B
public class TaskFragment extends Fragment{
View fview;
ProgressBar bar;
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i("tag", "TaskFragment Created");
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.i("tag", "onCreateView in TaskFragment");
fview = inflater.inflate(R.layout.progressfragment, container, false);
bar = (ProgressBar) fview.findViewById(R.id.sendingSmsProgress);
return fview;
}
}
Thanks.

Related

Allow one handler for Runnable?

Im trying to implement Interstitial Ads in my app. Im using a handler with postDelayed to delay the showing of the interstitial ad by 10 seconds.
My small app uses fragments. I have fragment 1 which contains a button to go to fragment 2 via fragment replacement transaction.
A problem im having is multiple instances of the same task being made which results into more than 1 interstitial ad showing (which is not good). This happens if you go into fragment 2, press back and then go into fragment 2 again.
What I want is a way to only allow a single handler (1 message) for this runnable. To prevent multiple ads from appearing
My main activity
public class MainActivity extends ActionBarActivity {
private ViewGroup container;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null)
{
container = (ViewGroup)findViewById(R.id.container);
if(container != null)
{
Fragment1 fragment1 = new Fragment1();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(container.getId(), fragment1, Fragment1.class.getName());
fragmentTransaction.commit();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// 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.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
int isAvaiable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(isAvaiable == ConnectionResult.SUCCESS)
{
Log.d("TEST", "GPS IS OK");
}
else if(isAvaiable == ConnectionResult.SERVICE_MISSING ||
isAvaiable == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED ||
isAvaiable == ConnectionResult.SERVICE_DISABLED)
{
GooglePlayServicesUtil.getErrorDialog(isAvaiable, this, 10).show();
}
}
}
Fragment 1
public class Fragment1 extends Fragment implements OnClickListener {
private Button bFragmentB;
private ViewGroup container;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_1, container, false);
this.container = container;
bFragmentB = (Button)view.findViewById(R.id.bFragmentB);
bFragmentB.setOnClickListener(this);
return view;
}
#Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
switch(arg0.getId())
{
case R.id.bFragmentB:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(container.getId(),new Fragment2(),Fragment2.class.getName());
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
break;
}
}
}
Fragment 2 (which contains the interstitial ad)
public class Fragment2 extends Fragment
{
private Handler handler = new Handler();
private InterstitialAd interstitialAd;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_2, container, false);
return view;
}
#Override
public void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
interstitialAd = new InterstitialAd(getActivity());
interstitialAd.setAdUnitId(getResources().getString(R.string.banner_ad_unit_id));
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
interstitialAd.loadAd(adRequest);
interstitialAd.setAdListener(new AdListener()
{
#Override
public void onAdLoaded()
{
handler.postDelayed(showInterstitialAd, 10000);
}
});
}
private Runnable showInterstitialAd = new Runnable()
{
#Override
public void run()
{
interstitialAd.show();
}
};
}
Here is a summary of the things I have tried but did not work
On fragment B onDestroy I have this code
#Override
public void onDestroy()
{
super.onDestroy();
handler.removeCallbacks(showInterstitialAd);
}
Still resulted in more than 1 instance of the task (2 ads appearing). Also is not good if the screen rotates anyway because the task would be destroyed from my understanding.
Another attempt at things
interstitialAd.setAdListener(new AdListener()
{
#Override
public void onAdLoaded()
{
if(!handler.hasMessages(1))
{
handler.sendEmptyMessage(1);
handler.postDelayed(showInterstitialAd, 10000);
}
//else do nothing
}
});
This one was pretty stupid considering a new hander object is made at the start so it would not have a message to begin with :D. The idea was to have message in the queue of 1 and if it sees 1 existing already then do not start another handler.
Looks like your old fragment2 is not getting full destryoed/GC'ed yet.
Since we are trying to get hold of the existing callback, which we created in old fragment, we need to save a reference to it, so we can delete it from handler message queue. You can do this by saving it in Application level global.
public class Global extends Application {
public Runnable oldshowInterstitialAd = null;
}
update your manifest Application with
<application android:name=".Global"
add the handler.removeCallbacks(oldshowInterstitialAd); just before posting a new one.
public void onAdLoaded()
{
handler.removeCallbacks(((Global)getApplicationContext()).oldshowInterstitialAd);
handler.postDelayed(showInterstitialAd, 10000);
((Global)getApplicationContext()).oldshowInterstitialAd = showInterstitialAd;
}
saving a reference to old fragment's member may hinder its GC'ing, but we loose the reference anyways as we update oldshowInterstitialAd with newer one.

I get exception when i pass data to third fragment but it works ok for passing data to the second fragment

i have a problem with my three fragments application when i go to pass data between them.
I use an interface to pass the values, viewpager for the fragments and i keep the fragments on a list in the mainActivity.java.The problem seems to be the instance of the fragments i guess.
On my mainFragment (fragment1.java)i have two buttons, one for sending data to the 2nd fragment and one to send data to 3rd fragment.
The application works, and the data are shown on the second fragment when i press the button.
I get an exception if i press the second button to send the data to the third fragment.
The data are transfered to the 3rd fragment as they should be, but i get an exception if press the second button before i go to the second fragment and return to the first again.
I dont know if i make myself clear, but it seems that is an instance error although frag1 and frag2 have the same code.
here is my code:
mainactivity.java
public class MainActivity extends FragmentActivity
implements ICommunicator{
private String Importeddata;
private PagerAdapter mPagerAdapter;
private List<Fragment> fragments;
private ViewPager mpager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_layout);
initialisePaging();
}
private void initialisePaging() {
// TODO Auto-generated method stub
fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this, Fragment1.class.getName()));
fragments.add(Fragment.instantiate(this, Fragment2.class.getName()));
fragments.add(Fragment.instantiate(this, Fragment3.class.getName()));
mPagerAdapter = new PagerAdapter(this.getSupportFragmentManager(), fragments);
mpager = (ViewPager)findViewById(R.id.viewpager);
mpager.setAdapter(mPagerAdapter);
}
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
//Interface method implementation
public void respond(String data,int frItem) {
// TODO Auto-generated method stub
switch(frItem)
{
case 1:
/*
* THIS WAY WORKS 1
* Fragment2 fr2 = (Fragment2)fragments.get(1);
Toast.makeText(this, "you passed values"+data, Toast.LENGTH_SHORT).show();
System.out.println("you passed values"+data);
fr2.changeData(data);*/
/* THIS WAY WORKS 2
* Fragment2 fr2=(Fragment2)getSupportFragmentManager().findFragmentByTag("android:switcher:"+R.id.viewpager+":1");
fr2.changeData(data);
*/
/* THIS WAY WORKS 3
*
*/
Fragment2 fr2=(Fragment2) mPagerAdapter.instantiateItem(mpager, 1);
fr2.changeData(data);
break;
case 2:
/*
* 1st way works, only if i first go to fragment 2 and return to firstfragment*/
/*otherwise i get a nullpointer EXCEPTION */
/*Fragment3 fr3 = (Fragment3)fragments.get(2);
Toast.makeText(this, "you passed values"+data, Toast.LENGTH_SHORT).show();
System.out.println("you passed values"+data);
fr3.changeData(data);*/
/*2nd way works, only if i first go to fragment 2 and return to firstfragment*/
/*otherwise i get a nullpointer EXCEPTION */
Fragment3 fr3=(Fragment3)getSupportFragmentManager().findFragmentByTag("android:switcher:"+R.id.viewpager+":2");
fr3.changeData(data);
}
}
}
BELOW IS THE FRAGMENT1.JAVA which it has the two buttons
public class Fragment1 extends Fragment{
Button btn1;
Button btn2;
ICommunicator icommunicator;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.e(getTag(), "onActivityCreated 1");
icommunicator = (ICommunicator) getActivity();
btn1 = (Button) getActivity().findViewById(R.id.Btn_Send);
btn1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "you pressed the button", Toast.LENGTH_LONG).show();
icommunicator.respond("hello from Fragment 1",1);
}
});
btn2 = (Button)getActivity().findViewById(R.id.Btn_Send2);
btn2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "you pressed button 2", Toast.LENGTH_SHORT).show();
icommunicator.respond("hello from fragment1 fragment 2",2);
}
});
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.e(getTag(), "onAttach 1");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e(getTag(), "onDestroy 1");
}
#Override
public void onPause() {
super.onPause();
Log.e(getTag(), "onPause 1");
}
#Override
public void onResume() {
super.onResume();
Log.e(getTag(), "onResume 1");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e(getTag(), "onCreateView 1");
if (container == null){
return null;
}
return inflater.inflate(R.layout.fragment1_layout,
container,false);
}
}
**below is the fragment2.java, the fragment that i send the btn1 message**
public class Fragment2 extends Fragment{
private String data;
private TextView txt;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e(getTag(), "onCreateView 2");
txt = (TextView) getActivity().findViewById(R.id.txt_importData);
if (container == null){
return null;
}
return inflater.inflate(R.layout.fragment2_layout,
container,false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.e(getTag(), "onActivityCreated 2");
txt = (TextView) getActivity().findViewById(R.id.txt_importData);
if (this.data == null)
txt.setText("i wait value....");
else
txt.setText(this.data);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.e(getTag(), "onAttach 2");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e(getTag(), "onDestroy 2");
}
#Override
public void onPause() {
super.onPause();
Log.e(getTag(), "onPause 2");
}
#Override
public void onResume() {
super.onResume();
Log.e(getTag(), "onResume 2");
}
public void changeData(String importdata){
this.data = importdata;
txt.setText(importdata);
}
}
below is the fragment3.java, the fragment that i send the btn2 message
the data are sent to the fragment3.java , so far so good, but i get a nullpointer exception unless i have gone to the second fragment first and return to the first fragment and after that i press the second button, it seems that is something wrong with the view instance of the fragment.
public class Fragment3 extends Fragment{
private String data;
private TextView txt;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e(getTag(), "onCreateView 3");
txt = (TextView) getActivity().findViewById(R.id.txt_fragment3);
if (container == null){
return null;
}
return inflater.inflate(R.layout.fragment3_layout,
container,false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
txt = (TextView) getActivity().findViewById(R.id.txt_fragment3);
Log.e(getTag(), "onActivityCreated 3");
if (this.data == null)
txt.setText("i wait value....");
else
txt.setText(this.data);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.e(getTag(), "onAttach 3");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e(getTag(), "onDestroy 3");
}
#Override
public void onPause() {
super.onPause();
Log.e(getTag(), "onPause 3");
}
#Override
public void onResume() {
super.onResume();
Log.e(getTag(), "onResume 3");
}
public void changeData(String importdata){
this.data = importdata;
txt.setText(importdata);
}
}
if anyone can help me or tell his opinion i would appreciate it.
i need interface to communicate through fragments , that is the way fragments interact with each other, in your answer you suggest to pass the data from inside the clickListener if i am not mistake.
as for the setoffscreenPageLimit , can you tell me where i tell the code to cashe three pages or is it the way viewpager works to cache by default just three pages?
I added :
mpager.setOffscreenPageLimit(3);
and it works!
thank you.
It only caches 3 pages. Itself, page on right and on left. Add this:
mpager.setOffscreenPageLimit(3); // You have 3 fragments
And you can just do this, instead of doing all of that:
btn1 = (Button) getActivity().findViewById(R.id.Btn_Send);
btn1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
TextView txt = (TextView) getActivity().findViewById(R.id.txt_importData);
txt.setText("whatever you want");
}
});
btn2 = (Button)getActivity().findViewById(R.id.Btn_Send2);
btn2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
TextView txt = (TextView) getActivity().findViewById(R.id.txt_fragment3);
txt.setText("whatever you want");
}
})

How to implement saveFragmentInstanceState?

Could you anyone advice me how to implement saveFragmentInstanceState() or some other methods to retrieving fragment instance when back button is pressed. I use own stack for fragment, viz code bellow:
public class stackA extends ActivityInTab {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("StackA", "onCreate");
if(savedInstanceState == null){
navigateTo(new fragmentA());
}
}
}
Next there is implementation of ActivityInTab class. I think for this class must be implemented methods for saving and retrieving fragment state but still I can't find the way how to do this.
abstract class ActivityInTab extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_in_tab);
Log.i("ActivityInTab", "onCreate");
}
protected void navigateTo(Fragment newFragment) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content, newFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
}
#Override
public void onBackPressed() {
Log.i("ActivityInTab", "onBackPressed");
FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() > 1) {
super.onBackPressed();
} else {
// Otherwise, ask user if he wants to leave :)
//showExitDialog();
super.onBackPressed();
}
}
}
And finally, this is imlementation of Fragments:
public class fragmentA extends Fragment {
private LinearLayout ll;
private FragmentActivity fa;
private String textViewText;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.i("Fragment A", "onCreateView");
fa = super.getActivity();
ll = (LinearLayout) inflater.inflate(R.layout.fragmenta, container,
false);
Button next = (Button) ll.findViewById(R.id.button1);
Button randomBtn = (Button) ll.findViewById(R.id.random_button);
final TextView randomText = (TextView) ll
.findViewById(R.id.random_textview);
next.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
((ActivityInTab) getActivity()).navigateTo(new
fragmentB());
}
});
randomBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
randomText.setText(String.valueOf(Math.random()));
textViewText = randomText.getText().toString();
}
});
if (savedInstanceState != null) {
randomText.setText(savedInstanceState.getString("TextView"));
}
return ll;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// setRetainInstance(true);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("TextView", textViewText);
}
}
I'm able to save instance state only for orientation changes using onSaveInstanceState(Bundle outState), but no for back button.
I would be very grateful for any advice, thanks.
In the onBackPressed Method you have access to the FragmentManager which can retrieve any fragment for you using the FragmentManager methods "findFragmentById" or "findFragmentByTag".
You can get direct access to any fragment whos state you want to save using either of those two methods depending on how you added the fragments.

Fragment setRetainInstance not works (Android support lib) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Android fragments setRetainInstance(true) not works (Android support library)
I wrote a simple test project, but I cant understand why I always receive savedInstanceState = null in lifecycle methods onCreate, onCreateView and onActivityCreated. I change the screen orientation, see the log, but state not saved.
Tell me please where is my mistake.
Thanks.
The code of fragment class is:
public class TestFragment extends Fragment {
private String state = "1";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (savedInstanceState != null) {
//never works
state = savedInstanceState.getString("state");
}
//always prints 1
Toast.makeText(getActivity(), state, Toast.LENGTH_SHORT).show();
return inflater.inflate(R.layout.fragment_layout, container, false);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("state", "2");
Log.e("", "saved 2");
}
}
EDIT
When i try to use setRetainInstance i have no result again((( I change a state to 2 using btn1, but after changing orientation i see 1 when pressing on btn2. Help please(
public class TestFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
setRetainInstance(true);
super.onCreate(savedInstanceState);
}
private String state = "1";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, container, false);
//button for changing state
((Button)view.findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
state = "2";
}
});
//button for showing state
((Button)view.findViewById(R.id.button2)).setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Toast.makeText(getActivity(), state, Toast.LENGTH_SHORT).show();
}
});
return view;
}
}
I have seen the same issue. But you can save the instate state in an other way, thanks to the method setRetainInstance(true), all your class data are saved automatically.
#Override
public void onCreate(Bundle savedInstanceState) {
setRetainInstance(true);
super.onCreate(savedInstanceState);
}
EDIT
Try to also add these params when you declare your activities :
<activity
android:name="MyActivity"
android:configChanges="orientation|keyboardHidden|screenSize" />

Button in tab fragment

I was following tutorials on how to make Tabs using fragments.
each tab has this in the java files:
public class rdfri extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
// We have different layouts, and in one of them this
// fragment's containing frame doesn't exist. The fragment
// may still be created from its saved state, but there is
// no reason to try to create its view hierarchy because it
// won't be displayed. Note this is not needed -- we could
// just run the code below, where we would create and return
// the view hierarchy; it would just never be used.
return null;
}
return (LinearLayout)inflater.inflate(R.layout.rdfri, container, false);
}
}
I would like to try and get a imageButton in the fragment. I figured image bottons work with this code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rdmon);
ImageButton rainbowbook = (ImageButton) findViewById(R.id.imageButton1);
rainbowbook.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent myIntent = Intent(rdmon.this, RainbowBookActivity.class);
rdmon.this.startActivity(myIntent);
}
});
}
So how would I go about getting the button code in the fragment code?
Thanks.
Put the button code in the overridden onActivityCreated method in your fragment class.
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ImageButton rainbowbook = (ImageButton) findViewById(R.id.imageButton1);
rainbowbook.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent myIntent = Intent(rdmon.this, RainbowBookActivity.class);
rdmon.this.startActivity(myIntent);
}
});
}
This assumes of course that your imagebutton is contained in your fragment layout.

Categories

Resources