Fragment 1:
public class homePage extends Fragment {
private OnFragmentInteractionListener mListener;
private View view;
public homePage() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_home_page, container, false);
Button btnLogin = (Button) view.findViewById(R.id.login);
Button btnRegister = (Button) view.findViewById(R.id.register);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loginView();
}
});
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
registerView();
}
});
return view;
}
public static homePage newInstance() {
homePage fragment = new homePage();
Bundle args = new Bundle();
return fragment;
}
public void registerView(){}
public void loginView(){}
public interface OnFragmentInteractionListener {
}
}
Acitivty :
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
homePage homepage = new homePage();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, homepage)
.commit();
}
}
}
My fragment1 has two buttons with the id's "login" and "register". Whenever login is clicked, I want to go to my fragment_login.xml, and when register is clicked I want to go to my fragment_register.xml. Should I create these functions in my activity or in my fragment? And how should I do this? I'm fairly new to android and I'm trying to learn these basic things atm. Thanks for the help :(
Login context: "com.example.hoofdgebruiker.winkelskortrijk.login"
Register context: "com.example.hoofdgebruiker.winkelskortrijk.register"
You have to make a communication between Fragment objects via an Interface.
The Activity that make the switch between your fragments needs to implement that Interface.
So, in your case your classes must be defined as follows. This is your Interface, it helps you to tell your activity that a button has been clicked from within your Fragment:
public interface HomeClickListener {
void onLoginClick();
void onRegisterClick();
}
Your Activity needs to implement the above interface in order to be notified when a button has been clicked:
public class HomeActivity extends Activity implements HomeClickListener {
void onLoginClick() {
// Your activity code to replace your current Fragment with your Login fragment
}
void onRegisterClick() {
// Your activity code to replace your current Fragment with your Register fragment
}
}
Your fragment is hosted by an Activity, so you need to have a reference to it and notify it via an Interface:
public class LoginFragment extends Fragment {
final HomeClickListener homeClickListener
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
homeClickListener = (homeClickListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnHeadlineSelectedListener");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_home_page, container, false);
Button btnLogin = (Button) view.findViewById(R.id.login);
Button btnRegister = (Button) view.findViewById(R.id.register);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
homeClickListener.onLoginClick();
}
});
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
homeClickListener.onRegisterClick();
}
});
return view;
}
}
More information here.
Related
I am facing a problem where I am opening a dialog (Dialog 1) from fragment1 and there is a button (change) on Dialog1 on which if I click then: Dialog1 should be dismissed and on the same fragment1 should be replaced by fragment2(Another fragment)
public class PedigreeAnalysis extends Fragment //My Fragment1
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
showDialog();
}
// SHOW DIALOG FUNCTION IS SHOWN BELOW `
void showDialog() { //Function to show the dialog starts...
Dialog dialog= new Dialog(getActivity());
Button btn = dialog.findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Code for opening new fragment and dismissing the dialog.
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment1, new Fragment2()).commit();
dialog.dismiss();
}
});
}//Function Ends Here....
I have even tried the reverse logic of (dismissing the dialog first and then replacing it with the function but it also doesn't works) as :
dialog.dismiss();//First dismissing the dialog
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment1, new Fragment2()).commit();//Replacing the fragment
Follow this...
Fragment1:
public class Fragment1 extends Fragment {
private ItemClickListener itemClickListener;
private Button addButton;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// all the views are initialized here...
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
addButton.setOnClickListener(v -> {
if (itemClickListener != null) onItemClicked.onClicked(new Plan());
});
}
public Fragment1 setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
return this;
}
public interface ItemClickListener {
void onItemClicked(Plan plan);
}
}
In parent Activity Class
public class PlanActivity extends AppCompatActivity {
private Fragment1 fragment1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plan);
fragment1 = new Fragment1()
.setOnAddButtonClicked(this::openFragmentEditPlan);
openFragment1();
}
private void openFragment1() {
getSupportFragmentManager().beginTransaction()
//frameLayout_PlanActivity is the container of both fragments
.add(R.id.frameLayout_PlanActivity, fragment1)
.commit();
}
public void openFragmentEditPlan(Plan plan) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.frameLayout_PlanActivity, FragmentEditPlan.newInstance(plan))
.addToBackStack("Fragment Edit Plan")
.commit();
}
}
I have two buttons in MainActivity, the first one opens a custom DialogFragment with some spinners and in the other button it resets the spinners of this DialogFragment.
When I click the reset button it calls this method that is in the DialogFragment:
public class FilterDialogFragment extends DialogFragment {
private View view;
// ...
#Nullable
#Override
public View onCreateView(#NotNull LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.dialog_filters, container, false);
// start the spinners and adapters here
return view;
}
public void resetFilters() {
if (view != null) {
categorySpinner.setSelection(0);
productSpinner.setSelection(0);
priceSpinner.setSelection(0);
}
}
// some more codes here
}
My MainActivity:
public class MainActivity extends AppCompatActivity {
private FilterDialogFragment filterDialog;
private Button button_clear;
private Button button_filter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_clear = findViewById(R.id.button_clear);
button_filter = findViewById(R.id.button_filter);
filterDialog = new FilterDialogFragment();
button_filter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Show the dialog containing filter options
filterDialog.show(getSupportFragmentManager(), FilterDialogFragment.TAG);
}
});
button_clear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//reset all filters
filterDialog.resetFilters();
}
});
//some more codes here
}
//some more methods here
}
But by clicking the button that opens the DialogFragment, the values of the Spinners remain the same instead of returning the data of position 0 of each spinner.
Would anyone know how to solve this? I've tried everything and I can not.
The simplest way I ended up finding, was to delete the resetFilters method, and instead I did so:
button_clear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//reset all filters
filterDialog = new FilterDialogFragment(); }
});
I have a activity which prompts a dialog fragment. I want to call a method in the parent activity when the dialog fragment is dismissed. Here is the activity that contains the dialog fragment.
public class HomScr extends AppCompatActivity {
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.das_boa);
initialize();
}
private void initialize(){
tv = findViewById(R.id.tv);
Button btn = findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ProEdiCon dia_fra = new ProEdiCon();
dia_fra.show((this).getSupportFragmentManager(), "pro_edi_con");
}
}
}
private void method_to_run_onDismiss(){
tv.setText("method to run is executed");
Toast.makeText(this, "method to run successfully executed on dismiss Dialog Fragment", Toast.LENGTH_SHORT).show();
}
}
And the below code is the DialogFragment which gets dismissed in certain point and after that the parent activity must call the method to run on dismiss.
public class ProEdiCon extends DialogFragment {
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle bun) {
View pro_vie = inflater.inflate(R.layout.pro_edi_dat, container, false);
TextView tv = pro_vie.findViewById(R.id.tv);
tv.setText("I am the Dialog Fragment who is gonna be dismissed soon");
Button btn = pro_vie.findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
}
return pro_vie;
}
}
So can anybody help me do this?
You can use Dialog and set Dismiss listener and listen for the event when dialog will be dismissed
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ProEdiCon dia_fra = new ProEdiCon();
dia_fra.show();
dia_fra.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
//do some action here
}
});
}
}
and your Dialog will be like this:
public class ProEdiCon extends Dialog {
public ProEdiCon (#NonNull Context context) {
super(context);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pro_edi_dat);
TextView tv = pro_vie.findViewById(R.id.tv);
tv.setText("I am the Dialog Fragment who is gonna be dismissed soon");
Button btn = pro_vie.findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
}
}
You must create interface like this
CallBackListener.java
public interface CallBackListener {
void onDismiss();
}
Then in your fragment
public class ProEdiCon extends DialogFragment {
private CallBackListener callBackListener;
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//getActivity() is fully created in onActivityCreated and instanceOf differentiate it between different Activities
if (getActivity() instanceof CallBackListener)
callBackListener = (CallBackListener) getActivity();
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle bun) {
View pro_vie = inflater.inflate(R.layout.pro_edi_dat, container, false);
TextView tv = pro_vie.findViewById(R.id.tv);
tv.setText("I am the Dialog Fragment who is gonna be dismissed soon");
Button btn = pro_vie.findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(callBackListener != null)
callBackListener.onDismiss();
dismiss();
}
}
return pro_vie;
}
}
And finally in your Activity
public class HomScr extends AppCompatActivity implements CallBackListener {
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.das_boa);
initialize();
}
private void initialize(){
tv = findViewById(R.id.tv);
Button btn = findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ProEdiCon dia_fra = new ProEdiCon();
dia_fra.show((this).getSupportFragmentManager(), "pro_edi_con");
}
}
}
private void method_to_run_onDismiss(){
tv.setText("method to run is executed");
Toast.makeText(this, "method to run successfully executed on dismiss Dialog Fragment", Toast.LENGTH_SHORT).show();
}
#Override
public void onDismiss() {
method_to_run_onDismiss();
}
}
You might want to use a DialogListener interface inside your Dialog class and call it before the dialog is dissmissed.
Interface with your method
public interface MyInterface {
void method_to_run_onDismiss();
}
Dialog - create an instance of the interface and call it right before dismiss();
public class ProEdiCon extends DialogFragment {
private MyInterface myInterface;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle bun) {
...
myInterface = (MyInterface) context;
Button btn = pro_vie.findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myInterface.method_to_run_onDismiss();
dismiss();
}
}
return pro_vie;
}
}
Activity class implement the interface and use the method you already have
Public class HomScr extends AppCompatActivity implements MyInterface {
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.das_boa);
initialize();
}
private void initialize(){
tv = findViewById(R.id.tv);
Button btn = findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ProEdiCon dia_fra = new ProEdiCon();
dia_fra.show((this).getSupportFragmentManager(), "pro_edi_con");
}
}
}
private void method_to_run_onDismiss(){
tv.setText("method to run is executed");
Toast.makeText(this, "method to run successfully executed on dismiss Dialog Fragment", Toast.LENGTH_SHORT).show();
}
}
My app is simple just i have a FragmentA and FragmentB first one has a single button pass String data ("Hi i'm A") through second fragment who has a text to show this message My question is
Why my "ModifyTxt" method doesn't work ?
public class newFragmentA extends Fragment{
Button button;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.newfragmenta_layout,container,false);
}
newFragmentB newfragmentB;
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
button = getActivity().findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
newfragmentB.ModifyTxT("Hi I'm A");
}
});
}
}
And this is my second Fragment(FragmentB)
public class newFragmentB extends Fragment {
TextView textView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.newfragmentb_layout,container,false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
textView = getActivity().findViewById(R.id.TV);
}
public void ModifyTxT(String string){
textView.setText(string); }
}
Try this:
public class FragmentB extends Fragment {
// ...
public static FragmentB newInstance() {
return new FragmentB();
}
}
In FragmentA :
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentB newFragment = FragmentB.newInstance();
newFragment.modifyTxT("Hi I'm A");
}
});
Be careful to coding rules : uppercase first letter for class name, lowercase first letter for method...
Prefer using Interface to communicate with Fragments
public class FragmentA extends Fragment{
public interface MyCallback{
void modifyTxT(String text); // method naming convention start with small letter.
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
button = getActivity().findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (newfragmentB instanceof MyCallback) {
((MyCallback)newfragmentB).modifyTxT("Hi I'm A");
}
}
});
}
}
public class FragmentB extends Fragment implements FragmentA.MyCallback{
public static FragmentB getInstance(){
return new FragmentB();
}
#Override
public void modifyTxT() {
}
}
I have 3 main fragments inside viewpager and they have couple of buttons. I want each button to navigate to another fragment and back button to get back to main fragment. I tried to add fragment transaction but it does not work. What am I doing wrong here?
this is one of the main fragments
public class OneFragment extends Fragment implements View.OnClickListener{
public OneFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_one, container, false);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.aButton:
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment_one, AFragment.newInstance());
transaction.commit();
break;
}
}
}
this is the fragment I want to navigate
public class AFragment extends Fragment{
public AFragment() {
}
public static AFragment newInstance() {
AFragment fragment = new AFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.a_fragment, container, false);
}
}
First, define a public method in your Activity to switch tabs in the ViewPager, and also define the onBackPressed() override, which will select the first index when the back button is pressed:
public void selectIndex(int newIndex) {
mViewPager.setCurrentItem(newIndex);
}
#Override
public void onBackPressed() {
int currentPosition = mViewPager.getCurrentItem();
if (currentPosition != 0) {
mViewPager.setCurrentItem(0);
} else {
super.onBackPressed();
}
}
Then, modify the click listener in the Fragment in order to call the selectIndex() method:
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.aButton:
//select the index of AFragment:
((MainActivity)getActivity()).selectIndex(1);
break;
}
}