For the first second I making a Android App where students can rent a room. Now I work on the login en register pages.
I have a problem with the register page. In my app there can two types of users register they are called "Student" and "Verhuurder". In the account fragment there are two buttons for the register pages. I can't get it working to the two pages..
I had so much trouble with activity and fragments...
Can anyone help me?
My code :
Account Fragment
public class AccountFragment extends Fragment implements View.OnClickListener{
public AccountFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (MainActivity.loginId == "")
{
return inflater.inflate(R.layout.fragment_account, container, false);
}
else
{
return inflater.inflate(R.layout.inlog_account, container, false);
}
}
// BUTTON
Button btnStudent = (Button) view.findViewById(R.id.btnRegisterStudent);
btnStudent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStudent:
//what to put here
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment_container, new AccountFragmentStudent());
ft.commit();
break;
}
}
});
}
XML Account fragment
<Button
android:id="#+id/btnRegisterStudent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:text="Student op zoek naar een kamer"
android:background="#color/colorPrimary"
android:onClick="StudentRegister"/>
MainActivity
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, Callback<LoginResults> {
private EditText emailInput;
private EditText passwordInput;
private HomeFragment fragment;
public static String loginId = "";
public static String loginSecret = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HomeFragment fragment = new HomeFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
public void Login(View v) {
emailInput = (EditText) findViewById(R.id.email);
passwordInput = (EditText) findViewById(R.id.password);
String email = emailInput.getText().toString();
String password = passwordInput.getText().toString();
doLogin(email, password);
}
public void onResponse(Response<LoginResults> response) {
if (response.isSuccess() && response.body() != null) {
loginId = response.body().clientId;
loginSecret = response.body().clientSecret;
fragment.setLoginToken1(loginId);
fragment.setLoginToken2(loginSecret);
new AlertDialog.Builder(MainActivity.this)
.setTitle("Gelukt")
.setMessage("U bent ingelogd")
.setCancelable(false)
.setPositiveButton("oke", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
}).create().show();
// Create fragment and give it an argument specifying the article it should show
InlogAccountFragment newFragment = new InlogAccountFragment();
Bundle args = new Bundle();
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
else
new AlertDialog.Builder(MainActivity.this)
.setTitle("Mislukt")
.setMessage("Uw inloggegevens zijn incorrect")
.setCancelable(false)
.setPositiveButton("oke", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
}).create().show();
{
}
}
public void onFailure(Throwable t) {
new AlertDialog.Builder(MainActivity.this)
.setTitle("Er is iets fouts gegaan")
.setMessage("Probeer opnieuw")
.setCancelable(false)
.setPositiveButton("oke", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
}).create().show();
}
public void doLogin(String email, String password){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("BLABLA")
.addConverterFactory(GsonConverterFactory.create())
.build();
Login service = retrofit.create(Login.class);
service.loginResults(
email,
password
).enqueue(this);
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_home) {
HomeFragment fragment = new HomeFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
} else if (id == R.id.nav_favorieten) {
FavoriteFragment fragment = new FavoriteFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
} else if (id == R.id.nav_berichtenbox) {
MessageFragment fragment = new MessageFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
} else if (id == R.id.nav_account) {
AccountFragment fragment = new AccountFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
} else if (id == R.id.nav_instellingen) {
SettingsFragment fragment = new SettingsFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
I generally try to keep my fragments light and decoupled, and delegate heavy lifting (particularly interaction with other fragments) to the activity which is using them. You might like to try the following approach:
Try adding a listener interface to your AccountFragment - something like this:
public interface Listener {
void onStudentRegistrationSelected();
void onVerhuurderRegistrationSelected();
}
You'll also need to add:
// Member declaration at the top of the fragment class
private Listener mListener;
#Override public void onAttach(Context context) {
super.onAttach(context);
try {
mListener = (Listener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement " +
Listener.class.getSimpleName() + ".");
}
}
This will set the activity which is using the fragment as the listener.
Then, set up the on click handler of the appropriate buttons in AccountFragment to call the appropriate method on the listener. Something like this:
view.findViewById(R.id.btnRegisterStudent).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListener.onStudentRegistrationSelected();
}
}
Back in MainActivity, implement the AccountFragment.Listener interface, override the methods of the listener, and create and commit the appropriate registration fragment in each of the listener method overrides - for example, onStudentRegistrationSelected() would display the AccountFragmentStudent fragment. Also, if you add this to the fragment backstack, then the user will be returned to the AccountFragment if they hit the back button while on the AccountFragmentStudent, which is a nice piece of UX.
Hope that helps!
Related
This is my main activity where I am calling my fragments:
public class what extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mToggle;
private ListView mDrawerList;
private ArrayAdapter<String> mAdapter;
private FragmentTransaction fragmentTransaction;
NavigationView navigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_what);
mDrawerLayout=(DrawerLayout)findViewById(R.id.drawer_layout);
mToggle=new ActionBarDrawerToggle(this, mDrawerLayout, R.string.open, R.string.close);
mDrawerLayout.addDrawerListener(mToggle);
mToggle.syncState();
fragmentTransaction= getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.main_content,new mainfrag());
fragmentTransaction.commit();
ActionBar actionBar= getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
navigationView=(NavigationView)findViewById(R.id.nav_view);
navigationView.getMenu().getItem(1).setChecked(false);
navigationView.getMenu().getItem(0).setChecked(true);
navigationView.getMenu().getItem(2).setChecked(false);
navigationView.getMenu().getItem(3).setChecked(false);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_main:
navigationView.getMenu().getItem(1).setChecked(false);
navigationView.getMenu().getItem(2).setChecked(false);
navigationView.getMenu().getItem(3).setChecked(false);
navigationView.setCheckedItem(R.id.nav_main);
mDrawerLayout.closeDrawers();
fragmentTransaction=getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_content, new mainfrag());
fragmentTransaction.commit();
getSupportActionBar().setTitle(("SGPA and CGPA Calculator"));
item.setChecked(true);
break;
case R.id.nav_savedcal:
navigationView.getMenu().getItem(0).setChecked(false);
navigationView.getMenu().getItem(2).setChecked(false);
navigationView.getMenu().getItem(3).setChecked(false);
navigationView.setCheckedItem(R.id.nav_savedcal);
mDrawerLayout.closeDrawers();
fragmentTransaction=getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_content, new savedFragment());
fragmentTransaction.commit();
getSupportActionBar().setTitle(("Saved Calculations"));
item.setChecked(true);
break;
case R.id.nav_upldoc:
navigationView.getMenu().getItem(0).setChecked(false);
navigationView.getMenu().getItem(1).setChecked(false);
navigationView.getMenu().getItem(3).setChecked(false);
navigationView.setCheckedItem(R.id.nav_upldoc);
mDrawerLayout.closeDrawers();
fragmentTransaction=getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_content, new uploadedfragment());
fragmentTransaction.commit();
getSupportActionBar().setTitle(("Uploaded documents"));
item.setChecked(true);
break;
case R.id.nav_site:
navigationView.getMenu().getItem(0).setChecked(false);
navigationView.getMenu().getItem(1).setChecked(false);
navigationView.getMenu().getItem(2).setChecked(false);
navigationView.setCheckedItem(R.id.nav_site);
mDrawerLayout.closeDrawers();
fragmentTransaction=getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_content, new resultsite());
fragmentTransaction.commit();
getSupportActionBar().setTitle(("VTU Results"));
item.setChecked(true);
break;
}
return false;
}
});
}
public boolean onOptionsItemSelected(MenuItem item ){
if(mToggle.onOptionsItemSelected(item)){
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
finish();
}
break;
case DialogInterface.BUTTON_NEGATIVE:
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?").setPositiveButton("Yes", dialogClickListener)
.setNegativeButton("No", dialogClickListener).show();
return;
}
}
This is my default fragment :
public class mainfrag extends Fragment {
private View view;
private AdView adView;
private Button button10;
private Button button11;
public mainfrag() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_mainfrag, container, false);
adView = view.findViewById(R.id.adView);
button10 = (Button) view.findViewById(R.id.button10);
button10.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openmainactivity();
}
});
button11 = (Button) view.findViewById(R.id.button11);
button11.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openscheme();
}
});
return view;
}
public void openmainactivity() {
Intent intent = new Intent(getContext(), MainActivity.class);
startActivity(intent);
}
public void openscheme(){
Intent intent=new Intent(getContext(), scheme.class);
startActivity(intent);
}
}
This is one of the other fragments:
public class savedFragment extends Fragment {
RecyclerView recyclerview;
adapter_sgpa recyclerAdapter;
ArrayList<POJO> sgpaArrayList;
public savedFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentTransaction tx = getChildFragmentManager().beginTransaction();
tx.replace(R.id.container, new sgpa_frag());
tx.commit();
}
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
Fragment fragment = null;
switch (id) {
case R.id.navigation_sgpa:
sgpa_frag sf = new sgpa_frag();
FragmentManager fragmentManager = getChildFragmentManager();
fragmentManager.beginTransaction().replace(R.id.container, sf).commit();
return true;
case R.id.navigation_cgpa:
cgpa_frag cf = new cgpa_frag();
fragmentManager = getChildFragmentManager();
fragmentManager.beginTransaction().replace(R.id.container, cf).commit();
return true;
}
return false;
}
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_saved, container, false);
BottomNavigationView nav = (BottomNavigationView) v.findViewById(R.id.bottom_navigation);
nav.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
return v;
}
}
What changes should I make in this code so that I am able to move back from the other fragments to the main fragment on pressing back button ?
Maintain one boolean variable to check current fragment is MainFragment or not.
if its not MainFragment -> replace MainFragment
Else -> super.onBackPressed()
ex:
private boolean isMainFragment=true; //make it false when move to other fragment
#Override
public void onBackPressed() {
if(!isMainFragment){
isMainFragment=true;
//replace your MainFragment
}
else{
//your logic show dialog or super.onBackPressed()
}
}
Ithink I know what you need. have a look at the last part of this documentation
"You can add a fragment transaction to the back stack. The back stack keeps track of actions in your app which can be backtracked when the user clicks Android's standard "back" button on the device. If you add a fragment transaction to the back stack then the transaction can be backtracked (reversed) with a click on the back button on the device" quotet from Jenkov
simply do fragmentTransaction.addToBackStack(null) on your main activity before you do the commit this will allow you to travel back using the back button
if you always want to travel back to the main fragment then you want to only add the main fragment to the backstack that way on pressing the back button you will always land there
in this part of your oncreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_what);
mDrawerLayout=(DrawerLayout)findViewById(R.id.drawer_layout);
mToggle=new ActionBarDrawerToggle(this, mDrawerLayout, R.string.open, R.string.close);
mDrawerLayout.addDrawerListener(mToggle);
mToggle.syncState();
fragmentTransaction= getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.main_content,new mainfrag());
//HERE YOU PUT THE CODE V
fragmentTransaction.addToBackStack(null);
//HERE YOU PUT THE CODE ^
fragmentTransaction.commit();
ActionBar actionBar= getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
// ALL THE OTHER STUFF COMMING AFTER
In my app I have created a Navigation Drawer with six Fragments. The MainOption Fragment is not included in the Navigation item menu list. Now I want to activate Back button on mobile device to redirect to Main Fragment. For example if I have fragments A,B,C,D,E,F, and now if I click B, then if I press back button, it will back to A. In the same way if I Press back button on Fragment E it will redirect to Fragment A. Now how can I achive this logic in my code. Hence I have tried lots of code from the website, but nothis was working at all. Here is my code snepet for Navigation Drawer
private NavigationView navigationView;
private DrawerLayout drawerLayout;
private Toolbar toolbar ;
private View navigationHeader;
private ImageView imgProfile;
private TextView txtName, txtWebsite;
// flag to load home fragment when user presses back key
private boolean shouldLoadHomeFragOnBackPress = true;
private Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mHandler = new Handler();
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.nav_view);
// Navigation view header
navigationHeader= navigationView.getHeaderView(0);
txtName = navigationHeader.findViewById(R.id.username);
txtWebsite = navigationHeader.findViewById(R.id.email);
imgProfile = navigationHeader.findViewById(R.id.profile_image);
// load nav menu header data
loadNavHeader();
//Set the Home Fragment initially
OptionMenuFragment fragment = new OptionMenuFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment, "OptionMenuFragment");
fragmentTransaction.commit();
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.setDrawerListener(toggle);
toggle.syncState();
navigationView.setNavigationItemSelectedListener(this);
}
private void loadNavHeader() {
// name, website
txtName.setText("Hallo");
txtWebsite.setText("mail.com");
imgProfile.setImageResource(R.drawable.profile_image);
//ToDo: Image should be uploaded from web
}
String lastFragmentTag;
boolean showingFirstFragment = true;
public void addNewFragment(Fragment fragment, String fragmentTag) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
if (lastFragmentTag != null) {
Fragment currentFragment = fragmentManager.findFragmentByTag(lastFragmentTag);
transaction.remove(currentFragment);
} else {
Fragment currentFragment = fragmentManager.findFragmentById(R.id.fragment_container);
transaction.hide(currentFragment);
}
transaction.add(R.id.fragment_container, fragment, fragmentTag);
transaction.commit();
lastFragmentTag = fragmentTag;
showingFirstFragment = false;
}
#Override
public void onBackPressed() {
//Here we're gonna remove the last fragment added, and show OptionMenuFragment again
if (!showingFirstFragment)
{
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
Fragment firstFragment = fragmentManager.findFragmentByTag("OptionMenuFragment");
Fragment currentFragment = fragmentManager.findFragmentByTag(lastFragmentTag);
transaction.remove(currentFragment);
transaction.show(firstFragment);
transaction.commit();
showingFirstFragment = true;
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.blu_home) {
Intent intent = new Intent(this, MainOptionPage.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
String fragmentTag=null;
// Handle navigation view item clicks here.
Fragment fragment = null;
FragmentManager fragmentManager = getSupportFragmentManager();
switch (item.getItemId()) {
case R.id.view_profile:
fragment = new ViewProfileFragment();
fragmentTag = "ViewProfileFragment";
break;
case R.id.todo_list:
fragment =new ToDoListFragment();
fragmentTag="ToDoListFragment";
break;
case R.id.logout:
showAlertDialogLogOut();
break;
case R.id.settings:
fragment = new SettingsFragment();
fragmentTag="SettingFragment";
break;
case R.id.about:
fragment = new AboutFragment();
fragmentTag="AboutFragment";
break;
case R.id.info:
fragment=new InfoFragment();
fragmentTag="InfoFragment";
break;
}
if(fragment!=null){
fragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).commit();
}
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
private void showAlertDialogLogOut() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Logout");
builder.setMessage("Are you sure you want to log out?");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// close the dialog, go to login page
dialog.dismiss();
startActivity(new Intent(MainOptionPage.this, LoginPage.class));
}
});
builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// Do nothing
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
For that approach, you will want to use the add(containerViewId, fragment, tag) method instead of replace(containerViewId, fragment), since replace will call remove(Fragment) for ALL fragments previously added to the container, before adding the new fragment. Also, you will want to use addToBackStack(name).
Here's a method I created for a project, and slightly modified for you:
String lastFragmentTag;
boolean showingFirstFragment = true;
public void addNewFragment(Fragment fragment, String fragmentTag) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
if (lastFragmentTag != null) {
Fragment currentFragment = fragmentManager.findFragmentByTag(lastFragmentTag);
transaction.remove(currentFragment);
} else {
Fragment currentFragment = fragmentManager.findFragmentById(R.id.fragment_container);
transaction.hide(currentFragment);
}
transaction.add(R.id.fragment_container, fragment, fragmentTag);
transaction.commit();
lastFragmentTag = fragmentTag;
showingFirstFragment = false;
}
Then you just have to make this change inside onNavigationItemSelected:
Fragment fragment = null;
FragmentManager fragmentManager = getSupportFragmentManager();
String fragmentTag;
switch (item.getItemId()) {
case R.id.view_profile:
fragment = new ViewProfileFragment();
fragmentTag = "ViewProfileFragment";
break;
...
}
if(fragment!=null){
addNewFragment(fragment, fragmentTag);
}
Where "fragmentTag", is going to be a String variable which you change according to the fragment instantiated.
EDIT: Some more changes since the code wasn't working as intended:
#Override
public void onBackPressed() {
//Here we're gonna remove the last fragment added, and show OptionMenuFragment again
if (!showingFirstFragment)
{
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
Fragment firstFragment = fragmentManager.findFragmentByTag("OptionMenuFragment");
Fragment currentFragment = fragmentManager.findFragmentByTag(lastFragmentTag);
transaction.remove(currentFragment);
transaction.show(firstFragment);
transaction.commit();
showingFirstFragment = true;
} else {
super.onBackPressed();
}
}
And when adding OptionMenuFragment, do this instead:
fragmentTransaction.replace(R.id.fragment_container, fragment, "OptionMenuFragment");
Hello I'm trying to override back button to back to home page it gives me this error when press back from BasicInfoFragment then press back again in home fragment (MainFragment)
it gives
java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.FragmentManager android.support.v4.app.FragmentActivity.getSupportFragmentManager()' on a null object reference
then the application crushs
java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.FragmentManager android.support.v4.app.FragmentActivity.getSupportFragmentManager()' on a null object reference
at com.teqneia.blooddonation.BasicInfoFragment.doBack(BasicInfoFragment.java:245)
at com.teqneia.blooddonation.MainActivity.onBackPressed(MainActivity.java:258)
at android.app.Activity.onKeyUp(Activity.java:2530)
at android.view.KeyEvent.dispatch(KeyEvent.java:2726)
at android.app.Activity.dispatchKeyEvent(Activity.java:2798)
at android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:543)
at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:53)
at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:315)
at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:53)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2368)
at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4333)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4295)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3836)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3889)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3855)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3981)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3863)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4038)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3836)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3889)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3855)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3863)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3836)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3889)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3855)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4014)
at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:4175)
at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2378)
at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1999)
at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1990)
at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2355)
at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:330)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
BasicInfoFragment java
public class BasicInfoFragment extends Fragment implements MainActivity.OnBackPressedListener, View.OnClickListener {
.
.
public BasicInfoFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_basic_info, container, false);
initialize(view);
// Inflate the layout for this fragment
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((MainActivity) getActivity()).setOnBackPressedListener(this);
}
void initialize(View view) {
//VIEW OLD DATA AND ADD LISTENERS
name = (EditText) view.findViewById(R.id.name_edit);
email = (EditText) view.findViewById(R.id.email_edit);
mobile = (EditText) view.findViewById(R.id.mobile_edit);
LastDonation = (EditText) view.findViewById(R.id.date_edit);
LastDonation.setInputType(InputType.TYPE_NULL);
LastDonation.requestFocus();
LastDonation.setOnClickListener(this);
//TAKE DATA FROM SERVER
//name.setText("");
//email.setText();
//mob.setText();
//LastDonation.setText();
b = (Button) view.findViewById(R.id.save_edit);
b.setOnClickListener(this);
//get Radio Groups
radioBgGroup = (RadioGroup) view.findViewById(R.id.bg_edit);
radioRhGroup = (RadioGroup) view.findViewById(R.id.rh_edit);
if (mSharedGetter.getBloodType().equals("A")) {
}
#Override
public void doBack() {
Fragment fragment = null;
fragment = new MainFragment();
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.fragment_container, fragment);
transaction.commit();
}
MainActivity
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
.
.
.
.
.
.
protected OnBackPressedListener onBackPressedListener;
public interface OnBackPressedListener {
void doBack();
}
public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
this.onBackPressedListener = onBackPressedListener;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Initially Load MainFFragment xml
setContentView(R.layout.activity_main);
Fragment fragment = new MainFragment();
//Apply fragment
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
View header = navigationView.getHeaderView(0);
TVnav_name = (TextView) header.findViewById(R.id.nav_name);
navigationView.setNavigationItemSelectedListener(this);
TVnav_name.setText(mSharedGetter.getUserName());
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else if (onBackPressedListener != null)
onBackPressedListener.doBack();
else
super.onBackPressed();
}
#Override
protected void onDestroy() {
onBackPressedListener = null;
super.onDestroy();
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
if (id == R.id.nav_edit_info) {
fragment = new BasicInfoFragment();
if (fragment != null) {
//Apply fragment
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
} else if (id == R.id.nav_home) {
fragment = new MainFragment();
if (fragment != null) {
//Apply fragment
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment, "MY_FRAGMENT");
fragmentTransaction.commit();
}
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
MainFragment
public class MainFragment extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_main, container, false);
return view;
}
//DIALOG BUILDER
new AlertDialog.Builder(getActivity())
.setTitle("DONATION REQUEST")
.setView(dialogView)
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.setPositiveButton("Request now", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//Send the request
Dialog f = (Dialog) dialog;
}
}).show();
}
}
in doBack method getActivity() is returning null. It is also not needed as you can call getFragmentManager() from a Fragment. Here's how to do just that, with fewer lines.
#Override
public void doBack() {
Fragment fragment = new MainFragment();
getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit();
}
in your BasicInfoFragment you have
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((MainActivity) getActivity()).setOnBackPressedListener(this);
}
MainFragment should have the same line, otherwise pressing back twice as you described will invoke BasicInfoFragment doBack() twice.
Since you detach it from its activity after the first back click you get a null value from getActivity() here when the second back arrives:
FragmentManager fm = getActivity().getSupportFragmentManager();
Always call like this.
//In Activity
FragmentManager fm = getSupportFragmentManager();
//In Fragment
FragmentManager fm = getActivity().getFragmentManager();
//For Nested Fragments
FragmentManager fm = getChildFragmentManager();
I think it would be better if you describe what you are trying to solve. I believe you may be having an error in the concept of how fragments work and the management of the back stack.
I believe the problem is your back event is being triggered but this is popping the fragment out but the reference is still there.
Take a look at:
https://aarcoraci.wordpress.com/2017/02/13/android-tutorial-drawer-and-fragment-navigation-made-easyier/
I WAS WORKING BY THE EXAMPLE YOU JUST GAVE ME AS DUPLICATE, READ THE ENTIRE POST, TY
I'm making a simple app with sliding menu by using the template provided by android studio. And I have to use fragments to switch between items of the sliding menu.
What I wanna do? (check app design at the bottom)
When I click on button pass data it should set the text in the Fragment B to the text that I entered in a Fragment A but without going directly to the Fragment B. So when I press the button pass data then I wanna go to the sliding menu and select item that containts fragment B and then I wanna see the text from Fragment A. Thanks in advance.
public class MainActivity extends AppCompatActivity implements FragmentA.DataPassListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
displayFragmentA();
} else if (id == R.id.nav_gallery) {
displayFragmentB();
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
});
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void passData(String data) {
FragmentB fragmentB = new FragmentB();
Bundle args = new Bundle();
args.putString("data", data);
fragmentB.setArguments(args);
//getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragmentB).commit();
//it works with the commented part but I dont wanna go directly to the fragment when I press pass data button
}
public void displayFragmentA() {
FragmentA frag = new FragmentA();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, frag);
fragmentTransaction.commit();
}
public void displayFragmentB() {
FragmentB frag = new FragmentB();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, frag);
fragmentTransaction.commit();
}
}
Fragment A code:
public class FragmentA extends Fragment {
DataPassListener mCallback;
public interface DataPassListener {
public void passData(String data);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Make sure that container activity implement the callback interface
try {
mCallback = (DataPassListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement DataPassListener");
}
}
public FragmentA() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
final EditText input = (EditText) view.findViewById(R.id.etInputID);
Button passDataButton = (Button) view.findViewById(R.id.bPassDataID);
passDataButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCallback.passData(input.getText().toString());
}
});
return view;
}
}
Fragment B code:
public class FragmentB extends Fragment {
TextView showReceivedData;
public FragmentB() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fragment_b, container, false);
showReceivedData = (TextView) view.findViewById(R.id.showReceivedData);
Bundle args = getArguments();
if (args != null) {
showReceivedData.setText(args.getString("data"));
} else {
Toast.makeText(getActivity(), "didnt get the bundle from mainactivity", Toast.LENGTH_LONG).show();
}
return view;
}
}
Design of the app:
If these two fragments use same activity,
to set value to fragment :
getActivity().getIntent().putExtra("key", "value");
To get value from fragment :
getActivity().getIntent().getExtras().getString("key");
I am working on a project in which i am navigating from activity to a fragment which contains my reservation page with EditText fields like Name, Email Id. What i want to know is whether it is possible to get the values of those fields and send them as an email in fragment. if yes please help.
MainActivity.java
public class MainActivity extends AppCompatActivity {
FloatingActionButton fab;
RelativeLayout aboutUs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
aboutUs = (RelativeLayout) findViewById(R.id.aboutUs);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
//click methods goes here
public void clickAboutUs(View view){
/*android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentAboutUs fragmentAboutUs = new FragmentAboutUs();
fragmentTransaction.replace(R.id.fragment_container, fragmentAboutUs);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();*/
FragmentAboutUs fragmentAboutUs = new FragmentAboutUs();
replaceFragment(fragmentAboutUs , true);
}
public void clickEvents(View view){
FragmentEvents fragmentEvents = new FragmentEvents();
replaceFragment(fragmentEvents,true);
}
public void clickMedia(View view){
FragmentMedia fragmentMedia = new FragmentMedia();
replaceFragment(fragmentMedia,true);
}
public void clickContact(View view){
FragmentContact fragmentContact = new FragmentContact();
replaceFragment(fragmentContact,true);
}
public boolean popFragment() {
boolean isPop = false;
Fragment currentFragment = getSupportFragmentManager()
.findFragmentById(R.id.fragment_container);
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
isPop = true;
getSupportFragmentManager().popBackStackImmediate();
}
return isPop;
}
#Override
public void onBackPressed() {
if (!popFragment()) {
finish();
}
}
public void replaceFragment(Fragment fragment, boolean addToBackStack) {
android.support.v4.app.FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
if (addToBackStack) {
transaction.addToBackStack(null);
} else {
getSupportFragmentManager().popBackStack(null,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
transaction.replace(R.id.fragment_container, fragment);
transaction.commit();
getSupportFragmentManager().executePendingTransactions();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Here is my fragment class
FragmentContact.java
public class FragmentContact extends Fragment
{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.contac_us, container,false);
return view;
}
}
In fragment FragmentContact i am planning to include reseration form. I search for "Registration page using fragment in android" but didnt get any help.
There is nothing different about the code that goes in a Fragment vs an Activity. You can use findViewById just like you have been, but you simply need to use the inflated view.
public class FragmentContact extends Fragment
{
private EditText address, body;
private Button sendEmailButton;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.contac_us, container,false);
sendEmailButton = (Button) view.findViewById(R.id.send_email);
sendEmailButton.setOnClickListener(...); // TODO: Implement
return view;
}
public void sendEmail(String address, String body) { }
}