I'm trying to get back to a fragment from a fragmentActivity, but it is not working, I'm getting NullPointerException, When I hit cancel I need to update the previous fragment. How can I get back to a fragment and update it? don't know why this is happening.
public class AddEscolas extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.addescola);
mSessao = new SecurePreferences(AddEscolas.this, "sessao");
pesquisa = (EditText) findViewById(R.id.campo_pesquisa);
nomeEscola = (TextView) findViewById(R.id.nomeEscola);
logradouro = (TextView) findViewById(R.id.endereco);
cidade = (TextView) findViewById(R.id.cidade);
procura = pesquisa.getText();
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(pesquisa.getWindowToken(), 0);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
findViewById(R.id.btnProcurar).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new Pesquisa().execute();
mFerramentas.hideKeyboard(AddEscolas.this, pesquisa);
}
});
findViewById(R.id.btnCancelar).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
}
});
}
}
FragmentClass :
public class EscolasFragment extends Fragment {
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_escolas, container, false);
ImageView add = (ImageView) rootView.findViewById(R.id.add);
mSessao = new SecurePreferences(getActivity(), "sessao");
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent addIntent = new Intent(getActivity(), AddEscolas.class);
startActivity(addIntent);
}
});
return rootView;
}
}
Suppose you just need to call finish(), like this:
findViewById(R.id.btnCancelar).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
The reason for the NullPointerException maybe is that the layout id of R.id.content_frame could not be found in the AddEscolas activity.
If you need to update the EscolasFragment fragment after the AddEscolas activity exits, you may do as follow steps:
use startActivity() from the EscolarFragment fragment to call the AddEscolas activity.
use onActivityResult() in the activity containing the EscolarFragment fragment to extract result returned by the AddEscolas activity.
use onResume() in the EscolarFragment fragment to update the UI.
You have wrong idea about what FragmentActivity is. Activities host fragments. You cant go to fragment without having activity. Read the docs
Null pointer exception comes from
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
you need to give instance to 'fragment'. Somehing like:
Fragment fragment = new YourFragment();
Simply call onBackPressed(); in the FragmentActivity.
Related
My MainActivity contain buttons which is used to switch to different fragments. Inside each fragment there are also has buttons. Activity button onClickListener work fine before implementing button onClickListener in fragments. I wonder if this is not supported by Android or my code is not correct.
Any pointer is appreciated. Thank you.
Fragment code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
v = inflater.inflate(fragment1, container, false);
b2=(Button)v.findViewById(R.id.button2);
b2.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v){
button2Clicked(v);
}
});
return inflater.inflate(R.layout.fragment1, container, false);
}
public void button2Clicked(View view){
//do something
}
Activity code:
public class MainActivity extends FragmentActivity {
private Button btnHealth;
private Button btnSetting;
private Button btnSleep;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Init component
btnHealth = (Button) findViewById(R.id.btnHealth);
btnSleep = (Button) findViewById(R.id.btnSleep);
btnSetting = (Button) findViewById(R.id.btnSetting);
replaceFragment(1);
btnHealth.setOnClickListener(new AdapterView.OnClickListener(){
#Override
//On click function
public void onClick(View view) {
replaceFragment(0);
}
});
btnSleep.setOnClickListener(new AdapterView.OnClickListener(){
#Override
//On click function
public void onClick(View view) {
replaceFragment(1);
}
});
btnSetting.setOnClickListener(new AdapterView.OnClickListener(){
#Override
//On click function
public void onClick(View view) {
replaceFragment(2);
}
});
}
//Create method replace fragment
private void replaceFragment(int pos) {
Fragment fragment = null;
switch (pos) {
case 0:
fragment = new Fragment1();
break;
case 1:
fragment = new Fragment2();
break;
case 2:
fragment = new Fragment3();
break;
default:
fragment = new Fragment2();
break;
}
if(null!=fragment) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.main_content, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
}
It is possible. If you want to handle the OnClick Event of the fragment inside the Activity class, you can do so by using FragmentInteractionListener (interface). Example: Android - handle fragment onClick from activity
I have an activity "MainActivity" that contains two fragments. Fragment1 has a EditText and a button. When the user presses the button the text inside the EditText will be sent to Fragment2 which only has a TextView. But I can't quite figureout how to send the text from EditText in Fragment1 to TextView in Fragment2. If someone could help? Appreciated. Thanks
Fragment1
package org.pctechtips.myfragmentapp;
/**
* Created by george on 5/16/17.
*/
public class ButtonFragment extends Fragment {
Button bt;
EditText editText;
TextView txtView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.button_fragment,
container, false);
txtView = (TextView) view.findViewById(R.id.textView_fragment1);
editText = (EditText) view.findViewById(R.id.editText_fragment1);
bt = (Button) view.findViewById(R.id.button_fragment1);
bt.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
buttonClicked(v);
}
});
return view;
}
public void buttonClicked (View view) {
.onButtonClick(edittext.getText().toString());
}
}
MainActivity
package org.pctechtips.myfragmentapp;
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*fragments 1 section*/
FragmentManager fm1 = getFragmentManager();
FragmentTransaction ft1 = fm1.beginTransaction();
ButtonFragment bf = new ButtonFragment();
ft1.add(R.id.button_fragment1, bf);
ft1.commit();
/*Fragment 2 section*/
FragmentManager fm2 = getFragmentManager();
FragmentTransaction ft2 = fm2.beginTransaction();
TextviewFragment tf = new TextviewFragment();
ft2.add(R.id.textView_fragment2, tf);
ft2.commit();
}
}
Fragment2
public class TextviewFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.text_fragment, container, false);
}
}
The quick and easy answer is to call getView().findViewById() from the activity (as shown below). The more proper approach is to give your fragments an interface that gets and retrieves the text. Below is the code for the quick and easy method, but when you create a fragment in Android studio it shows you how to do the more proper interface approach.
package org.pctechtips.myfragmentapp;
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*fragments 1 section*/
FragmentManager fm1 = getFragmentManager();
FragmentTransaction ft1 = fm1.beginTransaction();
ButtonFragment bf = new ButtonFragment();
ft1.add(R.id.button_fragment1, bf);
ft1.commit();
/*Fragment 2 section*/
FragmentManager fm2 = getFragmentManager();
FragmentTransaction ft2 = fm2.beginTransaction();
TextviewFragment tf = new TextviewFragment();
ft2.add(R.id.textView_fragment2, tf);
ft2.commit();
EditText et = (EditText) ft1.getView().findViewById(YOUR_EDITTEXT_ID);
Button button = (Button) ft1.getView().findViewById(YOUR_BUTTON_ID);
TextView tv = (TextView) ft2.getView().findViewById(YOUR_TEXTVIEW_ID);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tv.setText(et.getText();)
}
});
}
You can do it by several ways. For example via Activity like in Official Docs. But, I'm prefer send broadcast messages via LocalBroadcastManager like in this answer of war_Hero:
In Sending Fragment(Fragment B - Your ButtonFragment)
public class FragmentB {
private void sendMessage() {
Intent intent = new Intent("custom-event-name");
intent.putExtra("message", "your message");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
And in the Message to be Received Fragment(FRAGMENT A - Your TextviewFragment)
public class FragmentA {
#Override
public void onCreate(Bundle savedInstanceState) {
...
// Register receiver
LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
new IntentFilter("custom-event-name"));
}
// This will be called whenever an Intent with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("message");
}
};
}
And don't forget to unregister receiver:
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
I have been putting some debugging into my app to try to work out what is happening with the lifecycle.
I have some tabs and each tab content is a different fragment, each time a tab is changed onCreateView is called in the corresponding fragment.
In some of my onCreateViews I am currently mocking up some data and injecting table rows etc and then inflating the view every time. Like in the example below:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(LOG_TAG, "******************* onCreateView() is being called in the Container Fragment *********************");
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_patient, container, false);
mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), android.R.id.tabcontent);
//Set up tabs
mTabHost.addTab(mTabHost.newTabSpec("home_addresses").setIndicator("Home Addresses"), HomeAddressesFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("postal_addresses").setIndicator("Postal Addresses"), PostalAddressesFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("temp_addresses").setIndicator("Temporary Addresses"), TemporaryAddressesFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("email_other").setIndicator("Email / Other"), TemporaryAddressesFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tel_fax").setIndicator("Telephone & Fax"), TemporaryAddressesFragment.class, null);
//Set to home addresses tab
mTabHost.setCurrentTab(0);
tempAddressBtn = (Button)rootView.findViewById(R.id.temp_addr_tab_btn);
tempAddressBtn.setTransformationMethod(null);
tempAddressBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tabHandler(v);
}
});
postalAddressBtn = (Button)rootView.findViewById(R.id.postal_addr_tab_btn);
postalAddressBtn.setTransformationMethod(null);
postalAddressBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tabHandler(v);
}
});
homeAddressBtn = (Button)rootView.findViewById(R.id.home_addr_tab_btn);
homeAddressBtn.setTransformationMethod(null);
homeAddressBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tabHandler(v);
}
});
telFaxBtn = (Button)rootView.findViewById(R.id.tel_fax_tab_btn);
telFaxBtn.setTransformationMethod(null);
telFaxBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tabHandler(v);
}
});
emailOtherBtn = (Button)rootView.findViewById(R.id.email_other_tab_btn);
emailOtherBtn.setTransformationMethod(null);
emailOtherBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tabHandler(v);
}
});
return rootView;
}
My question is should I be doing this each time the onCreateView method is called? Is the view already cached somewhere?
I am seeing code in tutorials that looks a bit like:
#Override
protected void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.pager_activity);
if (savedInstance == null) {
PagerFragment frag = PagerFragment.newInstance(buildPagerData());
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().add(R.id.layout_fragments, frag, PAGER_TAG).commit();
}
findViewById(R.id.btnFragments).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
changeFragmentVisibility();
}
});
}
I know this Fragment in the example above extends from FragmentActivity and mine just extend from Fragment but it is using the fragment manager and checking if the state is null before deciding to instantiate a new fragment.
Edit: I am guessing as well that as this happens in onCreate and not onCreateView it happens less frequently?
I am wondering if this is something that I should be doing or if its ok to continue with the way I am going?
In my opinion you should manage your tabs from the parent Activity. Each Fragment should be responsible for one part of the UI.
Another advantage of that approach is that each Fragment layout will be a bit easier. And it will be easier to apply different containers if needed (e.g ViewPager).
I want to know how to stop running thread and asyncTask of fragment safely on android.
here is my code:
public class MainActivity extends FragmentActivity {
public Fragment mFragment;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
Button btn_next = (Button) findViewById(R.id.button_next);
btn_next.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
((FragmentOne)mFragment).infoThread.interrupt();
}
});
Intent intent = getIntent();
String start_fragment = intent.getStringExtra("start_fragment");
onShowFragment(start_fragment);
}
public void onShowFragment(String select_fragment) {
Fragment fr = null;
switch (select_fragment) {
case "fragment1":
fr = new FragmentOne();
break;
case "gragment2":
fr = new FragmentTwo();
break;
}
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_place, fr);
ft.commit();
}
}
public class FragmentOne extends Fragment {
public Thread infoThread;
public View view_one;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view_one = inflater.inflate(R.layout.fragment_one, container, false);
onGetInfo();
return view_one;
}
public void onGetInfo() {
infoThread= new Thread(new Runnable() {
#Override
public void run() {
String response_info = HTTPUtils.HTTPPost(Global.USER_URL,
"name", "abc",
"password", "1234");
processGetInfo(response_info);
}
});
infoThread.start();
}
}
in here, when click btn_next button, FATAL EXCEPTION ERROR occur.
please help me.
try to use:
infoThread.stop()
instead of:
infoThread.interrupt();
You are never initialising mFragment with a value.
Add mFragment = fr; to onShowFragment
But, you're going to have a whole load of different issues if you carry on down this path. You should consider a more robust framework than performing http requests in threads spawned from a Fragment's onCreateView method.
i created an activity that contains 5 fragments and one of the fragments contains a profile page and i created another activity to edit the profile page but when i click the save button to return to the Edit (fragment) . The app crashes..
i need help or suggestions
this is my Fragment code below :
public class MeFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.me, container, false);
Button bt = (Button) view.findViewById(R.id.btedit);
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(getActivity(), Editme.class);
startActivity(i);
}
});
return view;
}
and this is the Editme Class:
Button btnLoad = (Button) findViewById(R.id.btsave);
OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
MeFragment save = new MeFragment();
fragmentTransaction.add(R.id.fragment_content, save);
fragmentTransaction.commit();
}
};
btnLoad.setOnClickListener(listener);
If you opened another activity and after making some changes you'd like to go back to previous activity(with 5 fragments) simply call finish method instead of doing fragment transaction.
OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
}