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;
}
}
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 different classes that i will show
public class Iniziale extends AppCompatActivity {
Button credits,gioca,giocamyquiz,newquestion;
TextView testo;
public boolean whatgame;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_iniziale);
gioca = findViewById(R.id.gioca);
giocamyquiz = findViewById(R.id.giocamyquiz);
newquestion= findViewById(R.id.newquestions);
whatgame=true;
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
gioca.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
whatgame=true;
Intent homeIntent = new Intent(Iniziale.this, MainActivity.class);
startActivity(homeIntent);
finish();
}
});
giocamyquiz.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
whatgame=false;
Intent homeIntent = new Intent(Iniziale.this, MainActivity.class);
startActivity(homeIntent);
finish();
}
});
}
public boolean FragmentMethod() {
return whatgame;
}
}
and a fragment
public class MainActivityFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_main_activity, container, false);
what=true; //sceglie a quale quiz giocare
what=((Iniziale) getActivity()).FragmentMethod();
I want use method FragmentMethod() in my Fragment class because I need the value of the whatgame variable.
How the code is write it doesn't work.
In Iniziale class I have 2 buttons and based of what button i click I will modify my whatgame variable and modify some parameters in fragment class
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() {
}
}
There are lot of (duplicate) questions and answers are available, I went through almost all of them and failed. On reference of this question, I made some changes recently.
Brief : In my app, MainActivity holds Fragment View Pager and FrangmentA,B and C. FrangmentA Shows a DialogFragment CDialog onClik. After dismissing CDialog I need to Call FragmentA's doReload() which is not happening here.
MainActivity
protected void onCreate(Bundle savedInstanceState){
...
mSectionsPageAdapter = new FragmentAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
setupViewPager(mViewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
int defaultValue = 0;
int page = getIntent().getIntExtra("One", defaultValue);
mViewPager.setCurrentItem(page);
}
private void setupViewPager(ViewPager viewPager)
{
FragmentAdapter adapter = new
FragmentAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentA(), "FragA");
adapter.addFragment(new FragmentB(), "FragB");
adapter.addFragment(new FragmentC(), "FragC");
viewPager.setAdapter(adapter);
}
FragmentA
public class FragmentA extends Fragment implements CDialog.Dismissed{
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
...
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
FragmentManager fm = getActivity().getFragmentManager();
DialogFragment f = new CDialog();
f.show(fm, "CDialog");
}
});
#Override
public void dialogDismissed() {
Log.e(DFD_1, "dialogDismiss Called" );// <-- This is not working*
doReload();
}
}
And CDialogue
public class CDialog extends DialogFragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
....
return v;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
...
dfd_1.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
getDialog().dismiss(); //<--when this happens*
}
});
}
#Override
public void onDismiss(DialogInterface dialog) {
if (getActivity() != null && getActivity() instanceof Dismissed) {
((Dismissed) getActivity()).dialogDismissed();
}
super.onDismiss(dialog);
}
public interface Dismissed {
public void dialogDismissed(); //<-- FragmentA implements this
}
}
You can always have direct callback to your Fragment itself.
First step, is to set targetFragment using setTargetFragment():
DialogFragment#setTargetFragment(Fragment fragment, int requestCode);
I do it this way:
public void showDialogFragment(Fragment targetFragment, AppCompatDialogFragment appCompatDialogFragment, int requestCode) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
appCompatDialogFragment.setTargetFragment(targetFragment, requestCode);
fragmentTransaction.add(appCompatDialogFragment, appCompatDialogFragment.getClass().getSimpleName());
fragmentTransaction.commitAllowingStateLoss();
}
and then call to this method to open dialog fragment as:
public static final int RC_CDIALOG = 111;
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
showDialogFragment(FragmentA.this, new CDialog(), RC_CDIALOG);
}
});
Then, in your DialogFragment's onDismissListener(), have some code like below:
#Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if (getTargetFragment() instanceof FragmentA)
((FragmentA) getTargetFragment()).doReload();
}
What you did this way is:
Show Dialog Fragment "CDialog" along with telling it that your target fragment is "FragmentA" whose reference you can use incase you have something to do with it. In your case you had to call doReload();
I m new to android and i m having trouble with fragment communication, reading about it discovered the standard method of creating an interface and implementing it from the parentActivity which doesn't work in my case which is as follows.
I have an Activity named as ActivityA which extends fragment activity,in which i have a view pager for i want to keep two fragments namely fragmentA and fragmentB which should be swipable fragments.
fragmentA has a button which onClicked should make a change in fragmentB, to be precise on click it should add a string in the listView in fragmentA.
Now i have created the both the fragments's layouts as well as added the viewPAger to my FragmentActivity, they work great on swiping, the function is executed onButtonClick of fragmentA and logic works perfectly, after this is i want the changes to be reflected in fragmentB.
Using the interface method i can't find the reference to my fragment by id as it is added by viewPager to ActivityA
How do i do this??
help me out.
Stackoverflow says don't ask questions with out code so
Here is the Sample code
Activity A which has a virewPAger, need help how to get my fragment's Reference from the viewPager
public class ActivityA extends FragmentActivity implements FragmentA.Communicator
{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_A);
viewPager= (ViewPager) findViewById(R.id.pager);
fragmentManager=getSupportFragmentManager();
viewPager.setAdapter(new myAdapter(fragmentManager));
}
class myAdapter extends FragmentPagerAdapter{
public myAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = null;
switch (i){
case 0: fragment = new listOfIDsScanned();
break;
case 1: fragment = new displayCounter();
break;
default: //something witch won't crush the app
break;
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
}
This is fragmentA , actual fragment name is something else just for simple representation calling it fragmentA, which has an interface Communicator to communicate between fragments
public class fragmentA extends android.support.v4.app.Fragment implements View.OnClickListener
{
TextView counter;
Button scanStudentID;
int count=0;
String name=null,rollNo=null;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.display_counter,container,false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
scanStudentID= (Button) getActivity().findViewById(R.id.startScanning);
scanStudentID.setOnClickListener(this);
}
#Override
public void onClick(View v)
{
switch(v.getId()){
case R.id.startScanning:
startScanning();
break;
}
}
public void startScanning()
{
startActivityForResult(new Intent(getActivity(),Barcode.class),1);
}
public interface Communicator
{
// necessary methods
}
}
now finally fragmentB, in which methodToBeCalled(parameters) has to be invoked on the button click in fragementA
public class fragementB extends android.support.v4.app.Fragment
{
ListView listView;
ArrayList<String> rollNo= new ArrayList<>();
ArrayList<String> studentName= new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_list_of_ids_scanned,container,false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listView= (ListView) getActivity().findViewById(R.id.listView);
}
public void methodToBeCalled(String rollNo,String studentName)
{
if(!alreadyScanned(rollNo))
{
}
else
{
}
}
boolean alreadyScanned(String rollNo)
{
return true;
}
}