I have a MainActivity and a HomeTabs with three tabs (A B C), i set a refresh on tab C .
My structure is when i trigger onRefresh on tab C , i will switch to MainActivity
and load the data again to show the HomeTabs.
My problem is when i click back for finish(); , the layout will show tab C.
I try to finish the Fragment use like:
getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
or
((MainActivity)getActivity()).removeFragment(getActivity());
Both of them are no working , when i click back , i still can't finish the app immediately.
Some one can teach me what step i miss it , that would be appreciated.
My HomeTabs extends Fragment it use ViewPager and TabLayout add three tabs
MainActivity:
public class MainActivity extends AppCompatActivity {
private FrameLayout frameLayout;
private Toolbar toolBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
frameLayout = (FrameLayout) findViewById(R.id.frameLayout);
// Load the main Fragment
if (savedInstanceState == null) {
switchFragment(HomeTabs.newInstance());
}
//take the onRefresh dataļ¼send data to HomeTabs and open tab C
if (getIntent().hasExtra("refresh")) {
boolean isRefresh = getIntent().getExtras().getBoolean("refresh");
if (isRefresh) {
Bundle bundle = new Bundle();
bundle.putBoolean("refresh", isRefresh);
HomeTabs homeTabs = new HomeTabs();
homeTabs.setArguments(bundle);
switchFragment(homeTabs);
}
}
}
public void switchFragment(Fragment fragment) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.frameLayout, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
// I try to finsh my tab C , it's no working
public void removeFragment(Activity activity) {
activity.onBackPressed();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
new DialogHandler(this).quickDialog(
getResources().getString(R.string.quick),
getResources().getString(R.string.confirm),
getResources().getString(R.string.cancel),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// If i onRefrsh three times , i will finsh three times... here is my issue.
finish();
}
}, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
}
return super.onKeyDown(keyCode, event);
}
}
Here is my tab C Fragment refresh call back method:
public class MyLineChart extends Fragment implements SwipeRefreshLayout.OnRefreshListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my_line_chart, container, false);
//.....................
return view;
}
#Override
public void onRefresh() {
refreshLayout.setRefreshing(false);
// Both of them are no working.
//((MainActivity)getActivity()).removeFragment(getActivity());
//getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
Intent intent = new Intent(getActivity(),MainActivity.class);
intent.putExtra("refresh", true);
startActivity(intent);
}
Finally my HomeTabs Fragment take the date and show tab C:
Bundle bundle = getArguments();
if (bundle != null) {
boolean isRefresh = bundle.getBoolean("refresh");
if (isRefresh) {
//tab C position is 2
tabLayout.getTabAt(2).select();
}
}
Try this solution to add below code when you are starting activity again on Refresh click:-
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
OR
Update your MainActivity.java
1) Add function in MainActivity
public void refreshFragment() {
Bundle bundle = new Bundle();
bundle.putBoolean("refresh", isRefresh);
HomeTabs homeTabs = new HomeTabs();
homeTabs.setArguments(bundle);
switchFragment(homeTabs);
}
Now Call that from Fragment Tab C just replacing startActivity(refresh) code:
MainActivity mainActivity = (MainActivity) getActivity();
mainActivity.refreshFragment();
you can add a listener in your fragment that can trigger a function in your parent activity
which means you need to add an interface in your fragmentC code
public class MyLineChart extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private MyLineChartListener fragmentListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my_line_chart, container, false);
//.....................
return view;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof MyLineChartListener) {
fragmentListener = (MyLineChartListener) context;
} else {
// throw an error
}
}
#Override
public void onRefresh() {
refreshLayout.setRefreshing(false);
// Both of them are no working.
//((MainActivity)getActivity()).removeFragment(getActivity());
//getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
fragmentListener.onSettingRefresh();
}
public interface MyLineChartListener {
void onSettingRefresh();
}
}
then you need to implement the listener in the MainActivity code as follows
public class MainActivity extends AppCompatActivity implements MyLineChart.MyLineChartListener {
private FrameLayout frameLayout;
private Toolbar toolBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
frameLayout = (FrameLayout) findViewById(R.id.frameLayout);
// Load the main Fragment
if (savedInstanceState == null) {
switchFragment(HomeTabs.newInstance());
}
}
public void switchFragment(Fragment fragment) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.frameLayout, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
// I try to finsh my tab C , it's no working
public void removeFragment(Activity activity) {
activity.onBackPressed();
}
// this function will be called when the fragment is refreshed
#Override
public void onSettingRefresh() {
Bundle bundle = new Bundle();
bundle.putBoolean("refresh", true);
HomeTabs homeTabs = new HomeTabs();
homeTabs.setArguments(bundle);
switchFragment(homeTabs);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
new DialogHandler(this).quickDialog(
getResources().getString(R.string.quick),
getResources().getString(R.string.confirm),
getResources().getString(R.string.cancel),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// If i onRefrsh three times , i will finsh three times... here is my issue.
finish();
}
}, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
}
return super.onKeyDown(keyCode, event);
}
}
Related
I am using tabs to switch between different lists in my app. When a user touches an item in a list, the following is the code to show and hide the detail. I am wondering how to add a back-button that goes back to the correct list it came from. I am replacing fragments so I don't know if the standard back button works in my case?
public class MainActivity extends AppCompatActivity implements
NavigationView.OnNavigationItemSelectedListener,
TabLayout.OnTabSelectedListener,
CustomerFragment.CustomerListListener,
CustomerDetailListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
}
public void onShowCustomerDetail(Customer customer){
HostFragment hostFragment = (HostFragment) customPagerAdapter.getItem(viewPager.getCurrentItem());
CustomerDetailFragment fragment = CustomerDetailFragment.newInstance(customer);
hostFragment.replaceFragment(fragment, true);
}
public void onCloseCustomerDetail() {
HostFragment hostFragment = (HostFragment) customPagerAdapter.getItem(viewPager.getCurrentItem());
CustomerFragment fragment = new CustomerFragment();
hostFragment.replaceFragment(fragment, true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// just for testing. will do switch case here
onBackPressed();
}
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
}
CustomPagerAdapter:
public class CustomPagerAdapter extends FragmentStatePagerAdapter {
private final List<String> tabTitles = new ArrayList<String>() {{
add("Messages");
add("Customers");
add("Jobs");
add("Maps");
}};
private List<Fragment> tabs = new ArrayList<>();
public CustomPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
initializeTabs();
}
private void initializeTabs() {
tabs.add(HostFragment.newInstance(new MessageFragment()));
tabs.add(HostFragment.newInstance(new CustomerFragment()));
tabs.add(HostFragment.newInstance(new JobFragment()));
tabs.add(HostFragment.newInstance(new MapFragment()));
}
#Override
public Fragment getItem(int position) {
return tabs.get(position);
}
#Override
public int getCount() {
return tabs.size();
}
#Override
public CharSequence getPageTitle(int position) {
return tabTitles.get(position);
}
}
HostFragment:
public class HostFragment extends BackStackFragment {
private Fragment fragment;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_host, container, false);
if (fragment != null) {
replaceFragment(fragment, false);
}
return view;
}
public void replaceFragment(Fragment fragment, boolean addToBackstack) {
if (addToBackstack) {
getChildFragmentManager().beginTransaction().replace(R.id.hosted_fragment, fragment).addToBackStack(null).commit();
} else {
getChildFragmentManager().beginTransaction().replace(R.id.hosted_fragment, fragment).commit();
}
}
public static HostFragment newInstance(Fragment fragment) {
HostFragment hostFragment = new HostFragment();
hostFragment.fragment = fragment;
return hostFragment;
}
}
Because of the way I set up my fragments inside tabs using Child Fragment Manager, I had to do this in my onBackPressed to make it work:
#Override
public void onBackPressed() {
HostFragment hostFragment = (HostFragment) customPagerAdapter.getItem(viewPager.getCurrentItem());
FragmentManager fm = hostFragment.getChildFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
} else {
super.onBackPressed();
}
}
First of all you need to add fragments in backstack while using it
see below code for creating a fragment and adding inside it to backstack
public final static String TAG_FRAGMENT = "HostFragment"; // used inside every fragment
final HostFragment fragment = new HostFragment();
final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, fragment, TAG_FRAGMENT);
transaction.addToBackStack(TAG_FRAGMENT);
transaction.commit();
After that inside activity onBackPressed() you need to pop fragment every backpressed that you want.
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack(); // pop fragment here
} else {
super.onBackPressed(); // after nothing is there default behavior of android works.
}
}
All you need to do is add the fragment to the back stack when you create your fragment. It would look something like this:
CustomerDetailFragment fragment=CustomerDetailFragment.newInstance(customer);
getFragmentManager().beginTransaction()
.addToBackStack("Fragment Tag")
.replace(R.id.yourContainer, fragment, "Fragment Tag")
.commit();
Once you have this, you can just use the home back button to pop the fragments off the stack. If you want to use a custom button to go back, you would have to implement your own popping of the stack, which would call getFragmentManager().popBackStack();
Write a fuction onBackpress()
#Override
public void onBackPressed() {
new AlertDialog.Builder(this)
.setTitle("Exit?")
.setMessage("Do you really want to exit?")
.setNegativeButton("No")
.setPositiveButton("Yes", new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
YourActivityname.super.onBackPressed();
}
}).create().show();
}
From all the searches I have found on SO stating that you should save your instance state in the #Override public void onSaveInstanceState(Bundle outState)
However This is tightly coupled with the activities lifestyle.
How can I save the state of my listview in a fragment that gets swapped out with another fragment.
I have one main activity which all the fragments are loaded into.
I have tried this so far:
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Save adapter data so that when the fragment is returned to it can be resused.
ArrayList<CategoryMobileDto> categories = new ArrayList<CategoryMobileDto>();
for(int i=0; i < adapter.getCount();i++)
{
categories.add(adapter.getItem(i));
}
String persistData = new Gson().toJson(categories);
outState.putString("Categories", persistData);
}
and then in my OnCreate();
if(savedInstanceState!=null)
{
String data =savedInstanceState.getString("Categories");
Type collectionType = new TypeToken<ArrayList<CategoryMobileDto>>() {
}.getType();
adapter.addAll(gson.<Collection<CategoryMobileDto>>fromJson(data, collectionType));
adapter.notifyDataSetChanged();
}else{
// Make request to server
}
however savedInstanceState is always null. But this makes sense as my activity is not being destroyed and recreated.
This is how I transition from one fragment to another:
fragment.setArguments(args);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, fragment, "ProductListFragment");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Is there a way i can save the state of my listview when the fragment is removed and then restore it again when the fragment is popped from the back-stack?
Move this code from onCreate() to onActivityCreated() of Fragment
if(savedInstanceState!=null)
{
String data =savedInstanceState.getString("Categories");
Type collectionType = new TypeToken<ArrayList<CategoryMobileDto>>() {
}.getType();
adapter.addAll(gson.<Collection<CategoryMobileDto>>fromJson(data, collectionType));
adapter.notifyDataSetChanged();
}else{
// Make request to server
}
If you have any query please let me know.
You can use the Arguments with the Fragment(Only if you have the data to show in fragment before the fragment is loaded means attached). You can setArguments to a fragment which will be persisted when you go to another fragment by fragment transaction and when you come back, load the fragment from the getArguments function.
public void setArguments (Bundle args)
Added in API level 11
Supply the construction arguments for this fragment. This can only be called before the fragment has been attached to its activity; that is, you should call it immediately after constructing the fragment. The arguments supplied here will be retained across fragment destroy and creation.
public final Bundle getArguments ()
Added in API level 11
Return the arguments supplied when the fragment was instantiated, if any.
Please find the sample code below for passing data between fragments :
main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/flContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
MainActivity.java
public class MainActivity extends Activity implements IFragContainer {
private static final String FRAG_TAG = "FragTag";
private FragBase mFrag;
private String dataToBePassedBack;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
changeFragment(FragA.class, "Data to Frag A");
}
#Override
public void changeFragment(Class<? extends FragBase> fragClass, String data) {
try {
FragmentTransaction ft = getFragmentManager().beginTransaction();
mFrag = fragClass.newInstance();
Bundle args = new Bundle();
args.putString("DATA", data);
mFrag.setArguments(args);
ft.replace(R.id.flContainer, mFrag, FRAG_TAG);
ft.addToBackStack(mFrag.toString());
ft.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onBackPressed() {
dataToBePassedBack = mFrag.getDataToPassBack();
FragmentManager mgr = getFragmentManager();
mgr.executePendingTransactions();
boolean doCheckAndExit = true;
for (int i = mgr.getBackStackEntryCount() - 1; i > 0; i--) {
BackStackEntry entry = mgr.getBackStackEntryAt(i);
if (!TextUtils.isEmpty(entry.getName())) {
mgr.popBackStackImmediate(entry.getId(),
FragmentManager.POP_BACK_STACK_INCLUSIVE);
doCheckAndExit = false;
break;
}
}
if (doCheckAndExit) {
finish();
} else {
mFrag = (FragBase) mgr.findFragmentByTag(FRAG_TAG);
}
}
#Override
public String getDataToBePassedBack() {
return dataToBePassedBack;
}
}
IFragContainer.java
public interface IFragContainer {
void changeFragment(Class<? extends FragBase> fragClass, String data);
String getDataToBePassedBack();
}
FragBase.java
public abstract class FragBase extends Fragment {
public String getDataToPassBack(){
return null;
}
}
FragA.java
public class FragA extends FragBase {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Button btn = new Button(getActivity());
final IFragContainer fragContainer = (IFragContainer) getActivity();
if (TextUtils.isEmpty(fragContainer.getDataToBePassedBack())) {
btn.setText(getArguments().getString("DATA"));
} else {
btn.setText(fragContainer.getDataToBePassedBack());
}
btn.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
fragContainer.changeFragment(FragB.class, "Data to Frag B");
}
});
return btn;
}
}
FragB.java
public class FragB extends FragBase {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Button btn = new Button(getActivity());
btn.setText(getArguments().getString("DATA"));
btn.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
getActivity().onBackPressed();
}
});
return btn;
}
#Override
public String getDataToPassBack() {
return "Data from Frag B to A";
}
}
I have a main activity which contains the action bar with 3 menu buttons in it.
I then have a fragment within this main activity which has a list.
I would like to be able to refresh the list in the fragment from the main activity, when one of the menu buttons is clicked, or preferably just removed all the rows from the list.
Any help is appreciated.
Thanks.
public class Favourite extends SherlockFragmentActivity {
ActionBar actionBar;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.favourite);
actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(false);
BitmapDrawable bg = (BitmapDrawable)getResources().getDrawable(R.drawable.actionbar_bg);
bg.setTileModeX(TileMode.REPEAT);
getSupportActionBar().setBackgroundDrawable(bg);
getSupportActionBar().setIcon(R.drawable.favourite_title);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tabAll = actionBar.newTab();
ActionBar.Tab tabfavs = actionBar.newTab();
ActionBar.Tab tabhist = actionBar.newTab();
tabAll.setText("all");
tabfavs.setText("favs");
tabhist.setText("hist");
tabAll.setTabListener(new MyTabListener());
tabfavs.setTabListener(new MyTabListener());
tabhist.setTabListener(new MyTabListener());
actionBar.addTab(tabAll);
actionBar.addTab(tabfavs);
actionBar.addTab(tabhist);
try{
}
catch(Exception e)
{
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.actionbar_itemlist_favourite, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.history:
break;
case R.id.favourite:
Intent favAct = new Intent(this, Favourite.class);
startActivity(favAct);
break;
case R.id.delete:
///I WANT TO BE ABLE TO REFRESH FRAGMENTLIST FROM HERE
}
return true;
}
}
class MyTabListener implements ActionBar.TabListener {
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if(tab.getPosition()==0)
{
FavouriteAllWords frag = new FavouriteAllWords();
ft.replace(android.R.id.content, frag);
}
else if(tab.getPosition()==1)
{
FavouriteFavWords frag = new FavouriteFavWords();
ft.replace(android.R.id.content, frag);
}
else if(tab.getPosition()==2)
{
FavouriteHistWords frag = new FavouriteHistWords();
ft.replace(android.R.id.content, frag);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
////////////////////MY LIST FRAGMENT CLASS
public class FavouriteAllWords extends ListFragment {
ArrayAdapter<String> adapter;
List<String> stringOfFavWords;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved)
{
adapter = new ArrayAdapter<String>(
inflater.getContext(), R.layout.row, stringOfFavWords);
setListAdapter(adapter);
return super.onCreateView(inflater, group, saved);
}
#Override
public void onActivityCreated (Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
}
}
You can easily achieve this using INTERFACE
MainActivity.java
public class MainActivity extends Activity {
public FragmentRefreshListener getFragmentRefreshListener() {
return fragmentRefreshListener;
}
public void setFragmentRefreshListener(FragmentRefreshListener fragmentRefreshListener) {
this.fragmentRefreshListener = fragmentRefreshListener;
}
private FragmentRefreshListener fragmentRefreshListener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b = (Button)findViewById(R.id.btnRefreshFragment);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(getFragmentRefreshListener()!=null){
getFragmentRefreshListener().onRefresh();
}
}
});
}
public interface FragmentRefreshListener{
void onRefresh();
}
}
MyFragment.java
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = null; // some view
/// Your Code
((MainActivity)getActivity()).setFragmentRefreshListener(new MainActivity.FragmentRefreshListener() {
#Override
public void onRefresh() {
// Refresh Your Fragment
}
});
return v;
}
}
Just make your update/refresh method public and call it from your Activity.
OR
Use LocalBroadcastManager or EventBus to send event from your Activity, and by subscribing to this event in a Fragment - react to it and call refresh/update method.
Your activity can call methods in the fragment by acquiring a reference to the Fragment.
(1) Provide a tag when you add your fragment.
transaction.add(R.id.fragment_container, myFragment, "myfragmentTag");
(2) In your hosting activity you can find the fragment and have access to it's methods.
FragmentManager fm = getSupportFragmentManager();
myFragment f = (myFragment) fm.findFragmentByTag("myfragmentTag");
f.refreshAdapter()
(3) refreshAdapter() could now call adapter.notifyDataSetChanged().
This is one of the recommended ways to communicate up to a fragment.
The interface implementation is mainly for communicating back to the activity.
Biraj Zalavadia's answer is 100% right, you will call nay fragment methods from using interface....
this interface methods is running without error...
use this in MainActivity above oncreate
private FragmentRefreshListener fragmentRefreshListener;
public FragmentRefreshListener getFragmentRefreshListener() {
return fragmentRefreshListener;
}
public void setFragmentRefreshListener(
FragmentRefreshListener fragmentRefreshListener) {
this.fragmentRefreshListener = fragmentRefreshListener;
}
inside of Activity
private void refreshcall(String result2) {
// TODO Auto-generated method stub
if (getFragmentRefreshListener() != null) {
getFragmentRefreshListener().onRefresh(result2);
}
}
and put this in needed Fragment
private FragmentRefreshListener fragmentRefreshListener;
public FragmentRefreshListener getFragmentRefreshListener() {
return fragmentRefreshListener;
}
public void setFragmentRefreshListener(
FragmentRefreshListener fragmentRefreshListener) {
this.fragmentRefreshListener = fragmentRefreshListener;
}
Communicating with Other Fragments
http://developer.android.com/training/basics/fragments/communicating.html
This can also be used to communicate between an Activity and a Fragment.
When you click on ActionBar any Button then call interface to refresh the ListFragment. Because in java interface is used for inter-communication.
In Kotlin
Get the list of Support Fragment from the activity and check Instance and then call fragment function
val fragments = supportFragmentManager.fragments
for (fragment in fragments) {
if (fragment is HomeCategoriesFragment) {
fragment.updateAdapter() // Define function in Fragment
}
}
Why do i always get error when i try to call AlertDialog from my fragment?
At first i try to put it in OnCreate but it also get the same error log...
MainFragment.java
public class MainFragment extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_fragment);
if (savedInstanceState == null) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
LoginFragment fragment = new LoginFragment();
ft.add(R.id.simple_fragment, fragment).commit();
}
}
}
LoginFragment.java
public class LoginFragment extends Fragment implements OnClickListener {
Helper application;
static LoginFragment newInstance() {
LoginFragment f = new LoginFragment();
Bundle args = new Bundle();
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(getActivity().getApplicationContext());
dlgAlert.setMessage("TEST");
dlgAlert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
dlgAlert.setCancelable(false);
dlgAlert.create().show();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_login, container, false);
Button inner = (Button) v.findViewById(R.id.btnSignUp);
inner.setOnClickListener(LoginFragment.this);
return v;
}
#Override
public void onClick(View v) {
}
}
and this is the error log
12-19 10:14:25.295: E/AndroidRuntime(1083): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myfirstapp/com.example.fragment.MainFragment}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
anyone has ever encountered this before?
Just try
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(getActivity());
If you are dealing with nested fragments. When a fragment has it's own child fragments you need to use getChildFragmentManager().
Iam new to android .I need to go back to the FragmentActivity from fragment page.
My work flow is:
MainActivity->ProfileActivity->ProfilePhotoEditFragment
I need to go back to
ProfilePhotoEditFragment -> ProfileActivity
manifest
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
ProfilePhotoEditFragment.java
public class ProfilePhotoEditFragment extends Fragment implements OnClickListener {
ViewUtils mViewUtils;
Bundle mSavedInstanceState;
private OnNavigateProfileListener mOnNavigateProfileListener;
private Button mCancelButton;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context mContext = getActivity().getApplicationContext();
mViewUtils = new ViewUtils(mContext);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mSavedInstanceState = savedInstanceState;
View view = inflater.inflate(R.layout.fragment_edit_profile_pic, container, false);
mCancelButton = (Button) view.findViewById(R.id.cancel);
mCancelButton.setOnClickListener(this);
return view;
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onClick(View view) {
if (view.getId() == mCancelButton.getId()){
onBackPressed();
}
}
public void onBackPressed() {
// do something on back.
return;
}
}
remove current fragment ProfilePhotoEditFragment in onBackPressed()
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
//( "stackzeo");
} else {
getSupportFragmentManager().popBackStack();
removeCurrentFragment();
//("stacknotzeo");
}
..
public void removeCurrentFragment() {
Fragment currentFrag = (Fragment) getFragmentManager()
.findFragmentById(R.id.content_frame);
if (currentFrag != null)
getFragmentManager().beginTransaction().remove(currentFrag);
getFragmentManager().beginTransaction().commit();
}
Call findFragmentById() on FragmentManager and determine which fragment is in your R.id.content_frame container.
Thank you All. this my working code
....
#Override
public void onClick(View view) {
if (view.getId() == mCancelButton.getId()){
getActivity().getSupportFragmentManager().popBackStack();
removeCurrentFragment();
}
}
public void removeCurrentFragment()
{
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
Fragment currentFrag = getActivity().getSupportFragmentManager().findFragmentById(R.id.fragment_common_profile_layout);
String fragName = "NONE";
if (currentFrag!=null)
fragName = currentFrag.getClass().getSimpleName();
if (currentFrag != null)
transaction.remove(currentFrag);
transaction.commit();
}
getActivity().onBackPressed();
You should be able to call this code from every fragment.
Please check, if getActivity() returns null.
Hope this helps.
just write down
public void onBackPressed(){
super.onBackPressed();
}