Hi I have small app in android where Im using fragments with navigation drawer for menu. But now I want show in my fragments dialog popup window when user click on something and there I get these errors:
MainActivity:
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new FindPeopleFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
First error I get on fragment = new HomeFragment(); >>incompatible types.
Second error on HomeFragment at onCreateView method >> method does not override or implement a method from a supertype
HomeFragment:
public class HomeFragment extends FragmentActivity {
public HomeFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
final RelativeLayout rlPolievkaShowDialog=(RelativeLayout)rootView.findViewById(R.id.rlPolievkaButton);
rlPolievkaShowDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
return rootView;
}
private void showDialog() {
DialogFragment newFragment = DialogFragmentAlergeny.newInstance();
newFragment.show(getSupportFragmentManager(), "dialog");
}
}
DialogFragmentAlergeny:
public class DialogFragmentAlergeny extends DialogFragment {
public static DialogFragmentAlergeny newInstance() {
DialogFragmentAlergeny frag = new DialogFragmentAlergeny();
return frag;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.alergeny_dialog, null);
alertDialogBuilder.setView(view);
alertDialogBuilder.setTitle(getString(R.string.alergeny_dialog_title));
alertDialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
return alertDialogBuilder.create();
}
}
How Fix it:
HomeFragment must extend Fragment
You must use/import android.support.v4.app.Fragment, android.support.v4.app.DialogFragment, android.support.v4.app.FragmentActivity everywhere where needed.
newFragment.show(getActivity().getSupportFragmentManager(), "dialog"); use getsupportManager not FragmentManager()
Use FragmentManager fragmentManager = getSupportFragmentManager(); not FragmentManager()
Thats all thx all for help.
HomeFragment is not a fragment but a FragmentActivity...change extends class to Fragment
public class HomeFragment extends FragmentActivity { ... }
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();
}
I have Index.class as the Activity, when the user choose Profile, it will call fragment Profile
if (id == R.id.nav_profile){
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.setCustomAnimations(R.anim.enter,R.anim.exit,R.anim.enter,R.anim.exit);
transaction.replace(R.id.flContent, new Profile(), "ProfileFragment");
transaction.addToBackStack(null);
viewPager.getAdapter().notifyDataSetChanged();
transaction.commit();
}
Now in Profile Fragment, when the user clicks a button it will call DevRegistration Activity
case 1:
btnBeDeveloper.setText("Developer Console");
btnBeDeveloper.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent index = new Intent(getActivity(), DevRegistration.class);
startActivity(index);
}
});
break;
Then in DevRegistration class, after I click the register button, it will display a dialog fragment class.
What I want to do is when I click the button inside the dialog fragment, how can I refresh the profile fragment?
Dialog Fragment Class:
public class df_SuccessDevRegistration extends DialogFragment {
Button btnDevGoProfile;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
View rootView = inflater.inflate(R.layout.fragment_success_developer_registration, container, false);
btnDevGoProfile = (Button) rootView.findViewById(R.id.btnDevGoProfile);
btnDevGoProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
getFragmentManager().popBackStack();
getActivity().finish();
Profile fragment = (Profile)
getSupportFragmentManager().findFragmentByTag("ProfileFragment");
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction()
transaction.detach(fragment);
transaction.attach(fragment);
transaction.commit();
}
});
return rootView;
}
}
By the way, I dont know why getSupportFragmentManager isnt working. It shows an error cannot resolve method... when I used getFragmentManager() it crashes.
You could also try this to refresh the current fragment
FragmentTransaction ftran = getActivity().getFragmentManager().beginTransaction();
ftran .detach(this).attach(this).commit();
In your dev registration activity , get your fragment :
Profile profileFragment = getSupportFragmentManager().findFragmentByTag("ProfileFragment");
To refresh it you can try :
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.detach(profileFragment);
transaction.attach(profileFragment);
transaction.commit();
EDIT:
Can you try this ?
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
View rootView = inflater.inflate(R.layout.fragment_success_developer_registration, container, false);
btnDevGoProfile = (Button) rootView.findViewById(R.id.btnDevGoProfile);
return rootView;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
btnDevGoProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().popBackStack();
Profile fragment = (Profile)
getActivity().getSupportFragmentManager().findFragmentByTag("ProfileFragment");
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction()
transaction.detach(fragment);
transaction.attach(fragment);
transaction.commit();
getActivity().finish();
dismiss();
}
});
}
Hope this helps.
I have button in fragment1. I want to click this buttton and replace fragment1 by fragment2 but my app still close when I try to run it
This is my code in fragment1
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.layout_menu, container, false);
// gallery = (Gallery) rootView.findViewById(android.R.id.list);
//gallery.setAdapter(new ItemAdapter(generateData(), getActivity()));
Button button = (Button) rootView.findViewById(R.id.imageButtonAll);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
HomeFragment homeFragment = new HomeFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, homeFragment);
transaction.commit();
}
});
return rootView;
}
}
You cant open a fragment from inside another fragment.
So you have to move your code from the onClick to your activity and run it there.
In your Activity (lets assume its MainActivity):
public void openMyFragment(){
HomeFragment homeFragment = new HomeFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, homeFragment);
transaction.commit();
}
And then, add this in your fragments onClick:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity) getActivity()).openMyFragement();
}
});
The problem is that you are trying to replace a view that does not exist within the view that you are inflating. You have to switch these fragments from your FragmentActivity, which has the contentview containing the layout you are trying to replace.
MainActivity:
class MainActivity extends FragmentActivity {
public Fragment frag1;
public Fragment frag2;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
frag1 = new Frag1();
frag2 = new Frag2();
//assumption to switch to frag 1 immediately
switchToFragment(R.id.frame_container, homeFragment);
...
}
/** Switch UI to the given fragment (example) */
void switchToFragment(Fragment newFrag) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, newFrag)
.commitAllowingStateLoss();
currentFragment = newFrag;
}
}
Fragment:
....
final Activity activity = getActivity();
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
about.setTextColor(Color.WHITE);
if(activity instanceof MainActivity) {
((MainActivity) activity).switchToFragment(((MainActivity) activity).frag1));
}
}
});
...
I have to move Detailfragment to GridActivity.Workflow for activity
is GridActivity ->HomeActivity->DetailFragment.
In GridActvity I am using an image button.On Click the image button I
had set the position to move HomeActivity onArticlelistener.
With this listener I can move to fragment using position.
GridActivity1.java:
int position;
........
........
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_tour:
Intent i1=new Intent(GridActivity1.this,MainActivity.class);
i1.putExtra("tour",2);
i1.putExtra("position", position);
startActivity(i1);
break;
}
}
MainActivity.java:
public class MainActivity extends ActionBarActivity implements OnTabChangeListener,ArticleSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app_main_tab_fragment_layout);
posGrid= getIntent().getExtras().getInt("position");
switch(posGrid){
case 0:
int posTour = getIntent().getIntExtra("tour", 0);
articleSelected(posTour, "Tour Guide");
break;
}
}
#Override
public void onArticleSelected(int position, String content)
{
articleSelected(position, content);
}
public void articleSelected(int position, String content)
{
if(position==2)
{
action_bar_hometext.setText(content);
FragmentManager manager = getFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
DetailFragment newFragment = new DetailFragment();
ft.replace(R.id.realtabcontent, newFragment);
ft.addToBackStack(null);
ft.commit();
}
}
DetailFragment.java:
public class TourGuideFirstFragment extends BaseFragment implements
OnItemClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_tour_guide, container,
false);
return view;
}
}
I don't need action bar back button.Because I am using navigation
drawer in fragments.
My issue is,when I click the hardware back button in DetailFragment I
need to move directly to GridActivity.Now it is moving to HomeActivity then it back to GridActivity.
You are adding a FragmentTransaction to the backstack, so in order to get rid of this you just have to remove the line from MainActivity
ft.addToBackStack(null);
After that it should work as you want it to work
In my app I'm using ActionBArSherlock to create fragments. The main activity is a SherlockFragmentActivity from where I create the fragments. The fragments are in their own class files and they extend SherlockFragment. I need to display an alert dialog in a fragment but I'm unable to do so.
I googled it, but in vain. I checked the samples given along with the ActionBarSherlock library. They have shown how to create a dialog in a FragmentActivity but not in a Fragment. I tried implementing the same in a fragment but I can't use getSupportFragmentManager(). It is undefined for the type Fragment.
public class Fragment1 extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment2, container, false);
return rootView;
}
public void someFunction(){
if(somethingHappens)
showDialog();
}
//the code that follows is from the sample in ActionBarSherlock
void showDialog() {
DialogFragment newFragment = MyAlertDialogFragment.newInstance(
R.string.alert_dialog_two_buttons_title);
newFragment.show(getSupportFragmentManager(), "dialog"); //getSupportFragmentManager() is undefined for the type Fragment
}
public void doPositiveClick() {
// Do stuff here.
Log.i("FragmentAlertDialog", "Positive click!");
}
public void doNegativeClick() {
// Do stuff here.
Log.i("FragmentAlertDialog", "Negative click!");
}
public static class MyAlertDialogFragment extends SherlockDialogFragment {
public static MyAlertDialogFragment newInstance(int title) {
MyAlertDialogFragment frag = new MyAlertDialogFragment();
Bundle args = new Bundle();
args.putInt("title", title);
frag.setArguments(args);
return frag;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int title = getArguments().getInt("title");
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.alert_dialog_icon)
.setTitle(title)
.setPositiveButton(R.string.alert_dialog_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((FragmentAlertDialogSupport)getActivity()).doPositiveClick(); // Cannot cast from FragmentActivity to fragment
}
}
)
.setNegativeButton(R.string.alert_dialog_cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((FragmentAlertDialogSupport)getActivity()).doNegativeClick(); //Cannot cast from FragmentActivity to fragment
}
}
)
.create();
}
}
Can you tell me how to show a dialog in a Sherlock Fragment?
From within a SherlockFragment you may call
getSherlockActivity().getSupportFragmentManager();
to get your fragment manager to show the dialog fragment.