long story short.
I have the mainActivity with two Fragments. So instead of the mainActivity there are the two Fragments.
In the first Fragment there is a Switch.
Is it possible to update the background from the mainActivity when the switch is checked or unchecked? The Background is set in the content_main.xml, because then you have no transition when changing the fragments.
So is it at all possible?
I thought this would work:
if(switch.isChecked()) {
SharedPreferences sharedPref = getActivity().getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("background1", R.drawable.background2);
editor.apply();
}
And in the MainActivity:
SharedPreferences sharedPref = getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
int bg = sharedPref.getInt("background1", R.drawable.background1);
getWindow().setBackgroundDrawableResource(bg);
Or is it just not possible because the fragment isn't loading itself new?
If so. How is it possible?
Thanks in advance guys
source:
Changing background of an activity from another activity
Use callback interface to communicate between fragment and your activity
Please see the below code snippet :
public class YourFragment extends Fragment{
OnCallbackReceived mCallback;
// Implement this interface in your Activity.
public interface OnCallbackReceived {
public void Update(boolean state);
}
In your fragment :
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (OnCallbackReceived) activity;
} catch (ClassCastException e) {
}
}
// You can Call the event from fragment as mentioned below
// mCallback is the activity context.
mCallback.Update(switch.isChecked());
Activity :
public class MainActivity extends Activity
implements YourFragment.OnCallbackReceived {
// Implemented method.
public override void Update(boolean state) {
// Update bg here
}
Original:
How to send data from fragment to activity
use Otto event bus,It's easy and simple
Click this link
add this to your dependencies
implementation compile 'com.squareup:otto:1.3.8'
Activity or Fragment onCreate add this one
Bus bus = new Bus();
You can post event like this from your activity or fragment
bus.post(new AnswerAvailableEvent(42));
if you want to get events even when your fragment is in the foreground or background, Subscribe to the events like below
#Subscribe public void answerAvailable(AnswerAvailableEvent event) {
// TODO: React to the event somehow!
}
Don't forget to register and unregister in onStart and onStop
#Override
protected void onStart(){
super.onStart();
bus.register(this);
}
#Override
protected void onStop(){
super.onStop();
bus.unregister(this);
}
Yes, it's possible to achieve that. I think the easiest way to do so is through a listener/callback.
First of all, create your listener class:
public interface MyCallback {
void onSwitchStateChanged(boolean isChecked);
}
After that, make your Activity implement that interface, and implement your background changing logic inside the onSwitchStateChanged method.
Now, inside your Fragment's onAttach() method, do the following (this example is in Kotlin):
override fun onAttach(context: Context?) {
super.onAttach(context)
if (context is MyCallback) {
myListener = context as MyCallback
}
else {
throw RuntimeException("Must implement MyCallback!")
}
}
Where myListener is a variable inside your fragment.
Now add a setOnCheckedChangeListener on your switch, like it's described on this answer, and use the callback inside it. For example (in Java):
mySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
myListener.onSwitchStateChanged(isChecked);
}
});
Related
Is it possible for two (switch) buttons to have synchronized behavior between fragments? i.e: When button A is switched on in fragment A, I want button B's appearance in fragment B to also appear switched on.
How would I do that? The end goal is to have a global button on either fragment.
You can use a boolean flag in your activity and set it false by default and when any of switch is pressed on in either fragment then set its value to true, and when you navigate to another fragment then check flag value and if its true then switch it on or else off.
That would depend on whether both fragments are on same activity. If they are, then all you need is a boolean flag on the said activity and synchronise depend on that.
If not, then maybe create an boolean preference and synchronise based on that. Hope this helps. If you need code examples, let me know.
public interface Listener {
public boolean getFlag();
public void setFlag(boolean enable);
}
public class SomeActivity extends AppCompatActivity implements Listener {
// getFlag, setFlag implementation
}
public class FragmentA {
private boolean state;
private Listener listener;
private Switch switchBtn;
public void onAttach(Context ctx){
listener = (Listener) this.getActivity();
// check for ClassCast Exception
}
public void onActivityCreated() {
state = listener.getFlag();
switchBtn.setChecked(state);
}
}
For details view this page
Sample of communication between Fragments. Example below is modified from Communicating with Other Fragments
Step 1. Create an interface
public interface ButtonCallback{
void onClick(boolean val)
}
Step 2. In the HostActivity which hosts both fragment A and B, make HostActivity implements interface ButtonCallback.
public class HostActivity extends AppCompatActivity implements ButtonCallback{
void onClick(boolean val){
}
}
Step 3. In fragment A & B, initialize the callback with casting the activity
class FragmentA extends Fragment{
ButtonCallback callback;
#Override
public void onAttach(Context context) {
super.onAttach(context);
//Make sure activity host implement ButtonCallback interface
try {
callback= (ButtonCallback ) context;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement ButtonCallback");
}
}
//public method to update fragment's button state
public void setGlobalButtonState(boolean val){
//globalButton has been initialized in onCreateView function
globalButton.setEnabled(val);
}
}
class FragmentB extends Fragment{
ButtonCallback callback;
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
callback= (ButtonCallback ) context;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement ButtonCallback");
}
}
public void setGlobalButtonState(boolean val){
//globalButton has been initialized in onCreateView function
globalButton.setEnabled(val);
}
}
Step 4. In Fragment A, call ButtonCallback.onClick(boolean) when user click on the button
globalButton.setOnClickListener(new View.OnClickListener(View v){
Boolean value = !v.isEnabled();
callback.onClick(value)
});
Step 5. In HostActivity's onClick function, find a way to get Fragment B that suis your context, and update the button in Fragment B via the setGlobalButtonState function
void onClick(boolean val){
//get Fragment B.
fragmentB.setGlobalButtonState(val);
}
Additional note, if the button meant to be global, it might worth to consider to put the button on the host Activity instead if that suits your context.
Here is the developer guide on communicating with other fragments: https://developer.android.com/training/basics/fragments/communicating .
In the activity have the shared attribute. In each fragment, go to the parent activity to get that attribute on button click.
To reduce dependency, use an interface to obtain the data from the activity, as shown in the link provided
I think this question may simple but I didn't find any solution for this,
I there any way in Android that if any one of an activity calls onPause() I need to show Toast message or any notification kind of thing need to show. Generally I want to get notified when activity calls onPause() but I need it in one place since I may have some 15 activity I don't want to add it in all the activity.
ex:If I have activity when any one of the activity calls onPause I need to get notified but that notification code should be in one place and we should not add any line of code onPause() Is it possible to do this.
Thanks.
Create a baseActivity, which has for example :
open class BaseActivity : AppCompatActivity() {
override fun onPause() {
super.onPause()
Toast.makeText(this, "notified", Toast.LENGTH_SHORT).show()
}
}
Then you can extends this in your activities and handle the on pause call in BaseActivity
If your minSdkVersion >= 14, you can use Application.ActivityLifecycleCallbacks: ActivityLifecycleCallbacks
You have to define a custom Application class and you can register for this callbacks afterwards:
public class MyApplication extends Application {
private class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
#Override
public void onActivityCreated(final Activity activity, final Bundle savedInstanceState) {
//nothing to do
}
#Override
public void onActivityDestroyed(final Activity activity) {
//nothing to do
}
#Override
public void onActivityPaused(final Activity activity) {
// TODO Do your stuff, e.g. show toast.
}
#Override
public void onActivityResumed(final Activity activity) {
//nothing to do
}
#Override
public void onActivitySaveInstanceState(final Activity activity, final Bundle outState) {
//nothing to do
}
#Override
public void onActivityStarted(final Activity activity) {
}
#Override
public void onActivityStopped(final Activity activity) {
}
}
private final LifecycleCallbacks callbacks;
public void onCreate() {
super.onCreate();
callbacks = new LifecycleCallbacks();
application.registerActivityLifecycleCallbacks(callbacks);
}
}
Create a BaseActivity which contain all the methods you want to use in all other activities.
Then extend every activity with BaseActivity to call onPause() method.
In my main Activity, I have a DialogFragment that contains a FragmentTabHost. I have two tabs, one that is a DialogFragment and one that is a ListFragment. When either the 'OK' button is pressed in the inner DialogFragment or when an element in the ListFragment is pressed, I want to pass two Strings (that are entered in two TextView's in the inner DialogFragment and are displayed in each element in the ListFragment) back to the Activity, but I am unsure of how to do this with multiple levels of Fragments.
Any help is appreciated!
There's no magic.
You can achieve with two approaches.
Use callback.
Create interface and class to pass the data through child Fragment to Activity. You don't need to modify bridged TabHostFragment as Fragment always rely on its mother Context (Activity) no matter how many fragments wrap the fragment.
public class TwoStrings {
public TwoStrings(String one, String two){
this.one = one;
this.two = two;
}
public String one;
public String two;
}
First, declare interface.
public interface DataPassListener {
void dataPassed(TwoStrings data);
}
And, implement interface in Activity.
public class MainActivity extends Activity implements DataPassListener {
#Override
public void dataPassed(TwoStrings data) {
// do something with data.
Log.d("string one", data.one);
Log.d("string two", data.two);
}
}
Finally, let child Fragment acknowlege that mother Activity has the callback listener.
public class DialogFragment1 extends DialogFragment {
DataPassListener listener;
#Override
public void onAttach(Activity activity) {
if (activity instanceOf DataPassListener)
listener = (DataPassListener) activity;
}
public void setDataPassListener(DataPassListener listener){
listener = ((DataPassListener) listener);
}
public void doSomeThing(){
if(listener != null) // important to prevent NullPointerException
listener.dataPassed("a", "b");
}
}
Use EventBus.
I prefer to use Otto in order to publish and subscribe data.
To subscribe event for listening in Activity,
public class MainActivity extends Activity {
#Override
public void onResume() {
super.onResume();
BusProvider.getInstance().register(this);
}
#Override
public void onPause() {
super.onPause();
BusProvider.getInstance().unregister(this);
}
#Subscribe
public void onUpdateTwoStrings(TwoStrings event) {
// do something with data.
Log.d("string one", data.one);
Log.d("string two", data.two);
}
}
And, publish event in anywhere in Fragment.
bus.post(new TwoStrings("a", "b"));
Take a look at setTargetFragment() and getTargetFragment() methods. You could connect fragments with each other through it without any additional callbacks and libs.
Please please don't minus my question i confused when googling.
I used Android Tab Layout with Swipeable Views in my code for when user pressed setting button on an activity.
now I need send message from TopRatedFragment.java that extends from fragment to the activity that call the mainActivity of "Android Tab Layout with Swipeable Views".
You can do this by implementing a call back
create an interface first
public interface CommunicationInterface {
public void onSuccess();
public void onFailed();
}
then in your activity implement the interface
public class YourActivity extends ActionBarActivity implements CommunicationInterface {
//default functions
#Override
public void onSuccess() {
//stuff you want to do in the acivity
}
#Override
public void onFailed() {
//stuff you want to do in the acivity
}
}
Now in the fragment
public class yourfragment extends Fragment {
CommunicationInterface callback;
//stuffs that usually come in yor fragment and like OncreateView etc
#Override
public void onActivityCreated(#Nullable Bundle outState) {
super.onActivityCreated(outState);
//after all the stuff you want to do in your fragment then implement //call back function to communicate with the activity
callback= (CommunicationInterface) getActivity();
callback.onSuccess();//according to your purpose use where ever you like
callback.onFailed();//according to your purpose use where ever you like
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
callback= (CommunicationInterface) activity;
}
}
Take a close look on this reference:
Creating event callbacks to the activity
The android docs recommend using this pattern of having the parent activity implement an interface of the fragment (Basically calling methods on it)
class MyFragment extends Fragment {
interface Listener {
public void onSomeEvent();
}
private void somethingHappeninInTheFragment() {
// let the activity know
((Listener) getActivity()).onSomeEVent();
}
}
class MyActivity extends Activity implements MyFragment.Listener {
// etc
#Override
public void onSomeEvent() {
// handle the message from the fragment
}
}
Explained with a more concrete example here: http://developer.android.com/guide/components/fragments.html#EventCallbacks
Here's the solution:
Step 1 : From your fragment.
Intent i = new Intent(getActivity(), YourActivity.class);
i.putExtra("key", "Your value1");
i.putExtra("key2", "Your value2");
i.putExtra("key3", "Your value3");
getActivity().startActivity(i);
Step 2 : In your Activity where you want the result
Intent getResults = getIntent();
String firstValue = getResults.getStringExtra("key1");
String secondValue = getResults.getStringExtra("key2");
String thirdValue = getResults.getStringExtra("key3");
Use those values your needs are.
Hope this helps.. :)
From a view (a custom status bar) I need to know when the activity is paused and resumed. Is it possible?
Is it possible?
Yes and very easily.
Declare a interface and provide its implementation via your inner view to the outer activity.
Call the respective delegate in the onResume and onPause of activity to notify your inner view.
Simple. Hope this helps :)
Something like this
class MyActivity extends Activity {
public interface ActivityLifeCycleLister{
onResumeCalled();
}
public ActvityLifeCycleLsistener listener;
public void setActivityLifeCycleListener(ActvityLifeCycleLsistener listener) {
this.listener = listener;
}
#Override
public void onResume(){
super.onResume();
if(listener != null) {
listener.onResumeCalled();
}
}
class MyInnerView extends View {
// Some init method
void init() {
MyActivity.setActivityLifeCycleListener(new ActivityLifeCycleListener() {
void onResumeCalled() {
// Do whatever here
}
});
}
}
}
This approach can be used for all the components of your application who wants to listen life cycle events.
You can just create two methods onResume() and onPause() of your custom View (you can call this two methods whatever you want). Then in your activity you will have override onResume and onPause and call customView.onResume() and customView.onPause().