I created my test project where i code to communicate between two fragments but actully I want to access activity from fragment.
Here is code to connect fragment to fragment, its working absolutely right without any error but now i want to change this code to connect activity from fragment instead of fragment to fragment communication.
So Please change this code to access activities from fragment. I stuck on this issue for than a week.So Guys please resolve this.
here is my mainaactivity:
public class MainActivity extends AppCompatActivity implements FragmentA.FragmentAListener, FragmentB.FragmentBListener {
private FragmentA fragmentA;
private FragmentB fragmentB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentA = new FragmentA();
fragmentB = new FragmentB();
getSupportFragmentManager().beginTransaction()
.replace(R.id.container_a, fragmentA)
.replace(R.id.container_b, fragmentB)
.commit();
}
#Override
public void onInputASent(CharSequence input) {
fragmentB.updateEditText(input);
}
#Override
public void onInputBSent(CharSequence input) {
fragmentA.updateEditText(input);
}
Here is my FragmentA.java:
public class FragmentA extends Fragment {
private FragmentAListener listener;
private EditText editText;
private Button buttonOk;
public interface FragmentAListener {
void onInputASent(CharSequence input);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_a, container, false);
editText = v.findViewById(R.id.edit_text);
buttonOk = v.findViewById(R.id.button_ok);
buttonOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CharSequence input = editText.getText();
listener.onInputASent(input);
}
});
return v;
}
public void updateEditText(CharSequence newText) {
editText.setText(newText);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof FragmentAListener) {
listener = (FragmentAListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement FragmentAListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
Here is my FragmentB.java:
public class FragmentB extends Fragment {
private FragmentBListener listener;
private EditText editText;
private Button buttonOk;
public interface FragmentBListener {
void onInputBSent(CharSequence input);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_b, container, false);
editText = v.findViewById(R.id.edit_text);
buttonOk = v.findViewById(R.id.button_ok);
buttonOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CharSequence input = editText.getText();
listener.onInputBSent(input);
}
});
return v;
}
public void updateEditText(CharSequence newText) {
editText.setText(newText);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof FragmentBListener) {
listener = (FragmentBListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement FragmentBListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
Here is my Fertilizers.java file which i want to access from FragmentA.:
public class Fertilizers extends AppCompatActivity {
RecyclerView mRecyclerView;
List<FertilizerData> myFertilizersList;
FertilizerData mFertilizersData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fertilizers);
mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
GridLayoutManager gridLayoutManager;
gridLayoutManager = new GridLayoutManager(Fertilizers.this, 1);
mRecyclerView.setLayoutManager(gridLayoutManager);
myFertilizersList = new ArrayList<>();
mFertilizersData = new FertilizerData("Urea Fertilizer","Urea is a concent","Rs.1900",R.drawable.urea);
myFertilizersList.add(mFertilizersData);
myFertilizersList.add(mFertilizersData); }
}
please write here a block of code to call Fertilzers Activity from FragmentA, I,ll be very thankful to you.
Calling getActivity() in your fragment gives you the calling activity so if MainActivity started your fragment then you would do
(MainActivity(getActivity())).something_from_your_main_activity
Solution found by itself regarding this issue.
FragmentHome.java class should look like this:
public class FragmentHome extends Fragment {
private Button button;
public FragmentHome(){
}
public interface OnMessageReadListener
{
public void onMessageRead(String message);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home, container, false);
button = (Button)v.findViewById(R.id.bn);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), Fertilizers.class);
intent.putExtra("some"," some data");
startActivity(intent);
}
});
return v;
}
}
FertilizersActivity.java should look like this:
public class Fertilizers extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fertilizers);
Bundle bundle = getIntent().getExtras();
if (bundle != null){
if(bundle.getStringArrayList("some") !=null){
Toast.makeText(getApplicationContext(),"data:" + bundle.getStringArrayList("some"),Toast.LENGTH_LONG).show();
}
}
}
}
Related
I'm trying to implent the next code in Android Studio and it does not work.
I want to pass from a Fragment (GalleryFragment) to an Activity (postropa) with a button.
I have linked the botton with the function (BotonPulsado) and I don't know what is wrong (In the design view).
Design View
Code:
import (...)
public class GalleryFragment extends Fragment {
private GalleryViewModel galleryViewModel;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
galleryViewModel =
ViewModelProviders.of(this).get(GalleryViewModel.class);
View root = inflater.inflate(R.layout.fragment_gallery, container, false);
final TextView textView = root.findViewById(R.id.text_gallery);
galleryViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
textView.setText(s);
}
});
return root;
}
public void BotonPulsado(View view) {
Intent intent = new Intent(getContext(), postropa.class);
startActivity(intent);
}
}
You should create Button variаble as a class field.
private GalleryViewModel galleryViewModel;
Button button; <<-------
After that you need to define it in method onCreateView()
button = (Button) findViewById(R.id.button2);
And set onClickListener() on this button to handle the call.
There you must call the method that starts the activity.
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
BotonPulsado();
}
});
Your final code:
import (...)
public class GalleryFragment extends Fragment {
private GalleryViewModel galleryViewModel;
Button button;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
galleryViewModel =
ViewModelProviders.of(this).get(GalleryViewModel.class);
View root = inflater.inflate(R.layout.fragment_gallery, container, false);
final TextView textView = root.findViewById(R.id.text_gallery);
galleryViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
textView.setText(s);
}
});
button = (Button) findViewById(R.id.button2);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
BotonPulsado();
}
});
return root;
}
public void BotonPulsado() {
Intent intent = new Intent(getContext(), postropa.class);
startActivity(intent);
}
}
I'm implementing the autocomplete suggestion code in Google map place api.
We are using OnMapReadyCallback as an implement.
The MapView.getMapAsync(this) function was originally used in onCreateView. But now I'm going to use it in setupAutoCompleteFragment. However, in MapView.getMapAsync(this), it is not compiled due to this. What can be used?
public class googlemaptab extends Fragment implements OnMapReadyCallback {
MapView mapview;
Button kakaobutton;
public static googlemaptab newInstance(){
return new googlemaptab();
}
public googlemaptab() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_googlemaptab, container, false);
kakaobutton = (Button)view.findViewById(R.id.kakaobutton);
mapview = (MapView)view.findViewById(R.id.google_map_view);
setupAutoCompleteFragment();
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
kakaobutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//클릭하면 카카오maptab으로 이동하겠다.
((MainActivity)getActivity()).replaceFragment(kakaomaptab.newInstance());
}
});
}
#Override
public void onStart() {
super.onStart();
mapview.onStart();
}
#Override
public void onResume() {
super.onResume();
mapview.onResume();
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(mapview != null)
{
mapview.onCreate(savedInstanceState);
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
LatLng SEOUL = new LatLng(37.56, 126.97);
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(SEOUL);
markerOptions.title("서울");
markerOptions.snippet("수도");
googleMap.addMarker(markerOptions);
googleMap.moveCamera(CameraUpdateFactory.newLatLng(SEOUL));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(13));
}
private void setupAutoCompleteFragment() {
PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)getActivity().
getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
mapview.getMapAsync(this);
}
#Override
public void onError(Status status) {
Log.e("Error", status.getStatusMessage());
}
});
}
}
You could do it better this way
private void setupAutoCompleteFragment(OnMapReadyCallback instance) {
PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)getActivity().
getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
mapview.getMapAsync(instance);
}
#Override
public void onError(Status status) {
Log.e("Error", status.getStatusMessage());
}
});
}
And don't forget to update your onCreateView with the new function signature as the following:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_googlemaptab, container, false);
kakaobutton = (Button)view.findViewById(R.id.kakaobutton);
mapview = (MapView)view.findViewById(R.id.google_map_view);
setupAutoCompleteFragment(this);
return view;
}
You can use Classname.this in this case.
For example: if your fragment name is HomeFragment then,
HomeFragment.this
If this still doesn't work then you can override onViewCreated() function and call mapView.getMapAsync(this) inside onViewCreated()
If needed check this link
have you tried with mapview.getMapAsync(getActivity()); instead of mapview.getMapAsync(this);
I am trying to pass information from my alert dialog to my second fragment (I am using tabbed activity layout).
I want to pass information from alert dialog to fragment when I click on my ImageView, but my app keep crashing until I implement my interface inside MainActivity.java. My main mission here is to open alert dialog which contains several buttons. When I click first button I want to print "Test br 3" but it does not work inside my Fragment, it only works inside my MainActivity.java where method prints "Test br 2".
My Main Activity
public class MainActivity extends AppCompatActivity implements ExercisesAlertDialog.DataTransfer {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
#Override
public void ApplyData() {
System.out.println("Test br 2");
}
My Fragment
public class Frag2 extends Fragment implements ExercisesAlertDialog.DataTransfer {
ImageView plusbtn;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag2, container, false);
plusbtn = (ImageView) v.findViewById(R.id.plusbtn);
plusbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ExercisesDialog();
}
});
return v;
}
public void ExercisesDialog()
{
ExercisesAlertDialog exercisesAlertDialog = new ExercisesAlertDialog();
exercisesAlertDialog.show(getFragmentManager(), "Exercises Dialog");
}
#Override
public void ApplyData() {
System.out.println("Test br 3");
}
My Alert Dialog
public class ExercisesAlertDialog extends AppCompatDialogFragment {
ImageButton one, two;
private DataTransfer listener;
public int first;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.workout_custom_menu, null);
builder.setView(v);
builder.setTitle("Choose your Workout");
builder.setPositiveButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dismiss();
}
});
one = (ImageButton) v.findViewById(R.id.first);
two = (ImageButton) v.findViewById(R.id.second);
one.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
first = 1;
if(first ==1)
{
listener.ApplyData();
}
}
});
return builder.create();
}
public interface DataTransfer
{
void ApplyData();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
listener = (DataTransfer) context;
}
catch (ClassCastException e)
{
throw new ClassCastException(toString() + "Must implement DataTransfer");
}
}
}
I changed getChildFragmentManager() instead of getFragmentManager() in the show() call. Second thing is onAttach() to listener = (DataTransfer) getParentFragment(); instead of context.
Could guys hep me integrate Startapp network in this activity, this is my code it has not the oncreate method i tried to integrate it but i failed. Please help me. You can find below the code and it does not contain the oncreate method.Im new to coding and i tried lot of time to solve this problem it's easy for me if the oncreate method is there i can integrate the ad network easy. Pleas guys any idea to deal with will help me. Thank you
public class MainFragment extends Fragment {
public MainFragment() {
// Required empty public constructor
}
private final String TAG = "MainFragment";
Activity activity;
AdView bannerAdView;
boolean isAdLoaded;
CardView cardVideoToGIF, cardImagesToGIF, cardCaptureImage, cardVideoToAudio, cardVideoCutter, cardGallery;
LinearLayout linearRow2;
private String SELECTED_TYPE = Constants.TYPE_GIF;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_main, container, false);
}
#Override
public void onResume() {
super.onResume();
if (bannerAdView != null) {
bannerAdView.resume();
}
((MainActivity) activity).setTitle("");
((MainActivity) activity).setDrawerState(true);
if (!MyApplication.isFFmpegSupports) {
linearRow2.setVisibility(View.GONE);
}
}
#Override
public void onPause() {
if (bannerAdView != null) {
bannerAdView.pause();
}
super.onPause();
}
#Override
public void onDestroy() {
if (bannerAdView != null) {
bannerAdView.destroy();
}
super.onDestroy();
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initViews(view);
cardVideoToGIF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showPopupMenu(cardVideoToGIF);
SELECTED_TYPE = Constants.TYPE_GIF;
}
});
Replace your code with the following
public class MainFragment extends Fragment {
// Add these lines of code which is the onCreate method of your Fragment
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// put your integration code here
Log.i("MainFragment", "onCreate()");
}
public MainFragment() {
// Required empty public constructor
}
private final String TAG = "MainFragment";
Activity activity;
AdView bannerAdView;
boolean isAdLoaded;
CardView cardVideoToGIF, cardImagesToGIF, cardCaptureImage, cardVideoToAudio, cardVideoCutter, cardGallery;
LinearLayout linearRow2;
private String SELECTED_TYPE = Constants.TYPE_GIF;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_main, container, false);
}
#Override
public void onResume() {
super.onResume();
if (bannerAdView != null) {
bannerAdView.resume();
}
((MainActivity) activity).setTitle("");
((MainActivity) activity).setDrawerState(true);
if (!MyApplication.isFFmpegSupports) {
linearRow2.setVisibility(View.GONE);
}
}
#Override
public void onPause() {
if (bannerAdView != null) {
bannerAdView.pause();
}
super.onPause();
}
#Override
public void onDestroy() {
if (bannerAdView != null) {
bannerAdView.destroy();
}
super.onDestroy();
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initViews(view);
cardVideoToGIF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showPopupMenu(cardVideoToGIF);
SELECTED_TYPE = Constants.TYPE_GIF;
}
});
I have a MainActivity, and I want to attach a fragment with 3 buttons in it to that activity. On clicking button 1 it should replace this fragment with another fragment. But when I change orientation the current fragment and the old fragment are both getting attached. Can someone help me solve this ?
Following is my MainActivity.java:
public class MainActivity extends AppCompatActivity implements OnButtonsClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction()
.add(R.id.mainactivity, new FragmentHomepage(), "aboutMe")
.commit();
}
#Override
public void button1Action() {
FragmentAboutMe fragmentAboutMe=new FragmentAboutMe();
getSupportFragmentManager().beginTransaction()
.add(R.id.mainactivity,fragmentAboutMe)
.commit();
}
#Override
public void button2Action() {
Intent intent =new Intent(this,ActivityMasterDetail.class);
startActivity(intent);
}
#Override
public void button3Action() {
Intent intent =new Intent(this,ActivityViewPager.class);
startActivity(intent);
}
}
This is my FragmentHomepage.java:
public class FragmentHomepage extends Fragment {
private static final String ARG_SECTION_NUMBER ="section number";
OnButtonsClickListener onButtonsClickListener;
public static FragmentHomepage newInstance(int sectionNumber){
FragmentHomepage fragmentHomepage=new FragmentHomepage();
Bundle args=new Bundle();
args.putInt(ARG_SECTION_NUMBER,sectionNumber);
fragmentHomepage.setArguments(args);
return fragmentHomepage;
}
public FragmentHomepage(){}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
onButtonsClickListener= (OnButtonsClickListener) context;
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Button button1= (Button) getActivity().findViewById(R.id.aboutMe);
final Button button2= (Button) getActivity().findViewById(R.id.task2);
final Button button3= (Button) getActivity().findViewById(R.id.task3);
button1.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
onButtonsClickListener.button1Action();
}
});
button2.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
onButtonsClickListener.button2Action();
}
});
button3.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
onButtonsClickListener.button3Action();
}
});
}
#Nullable
#Override
public View onCreateView(final LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View rootView=null;
rootView =inflater.inflate(R.layout.fragment_homepage,container,false);
return rootView;
}
}
and my second activity is as follows
(in FragmentAboutMe.java):
public class FragmentAboutMe extends Fragment {
int counters=0;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState==null)counters=0;
else counters=savedInstanceState.getInt("count");
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("count",13);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_aboutme,container,false);
}
}
In your onCreate() method put a check whether the fragment is already present. Android automatically restores the fragment manager state upon orientation change and hence upon orientation change, the fragment which you added on button click would automatically be added. Thus if you will add new fragment in onCreate() without check, this would result in adding the 2 fragments. This is causing the issue.
FragmentManager fm = getSupportFragmentManager();
if (fm.findfragmentById(R.id.mainactivity) == null) {
FragmentHomepage fragment = new FragmentHomepage ();
fm.beginTransaction().add (R.id.mainactivity, fragment).commit();
}
You would want to save the state. You would need to extend Fragment to store the objects that need saving.
Override the onConfigurationChanged(..) and it should work out.
When I had to handle screen orientation changes, I recall having used this reference [link].
There are two ways.
Either you need to save the state in the bundle in onSaveInstanceState() method. Also save the states of fragment.
When activity recreate itself then check the value of bundle inside onCreate() or onRestoreInstanceState() method. Now initialize all the objects as before.
Else
set the value of activity inside manifest file as
android:configChanges="layoutDirection|orientation|screenLayout|screenSize"
and override the method.
#Override
public void onConfigurationChanged(Configuration newConfig) {
}
Second technique will not allow the activity to restart on orientation change.