Android onBackPressed() inside a method - android

I have an Activity class and inside there are some methods. And I want to implement the onBackPressed() inside the method2 because I have an important variable that I want to free. I can't/don't make this variable with bigger scope and I can't free this variable inside the method2 because I want to terminate the application and the execution of method 2 with the pressing back button.
public class example extends Activity {
public void onCreate(Bundle savedInstanceState) {
method1();
}
public method 1 {
//take some input and assign in a variable.
method2(variable);
}
public method2 {
// do something with the variable that take before at method 1
// and finally press back button
onBackPressed(){}
//free variable , finish ();
}
}
As you know i can't Override the onBackPressed() inside the method only out at the activity area. Can you provide me a solution for this.

You should override the onBackPressed() method in the activity scope and call it from your method.
#Override
public void onBackPressed()
{
super.onBackPressed();
// Do your things.
}
public void method()
{
onBackPressed();
}
If you want to add some complex logic in the onBackPressed method, just create another one with parameters.
public void myOnBackPressed(int param1, String param2)
{
// Do your complex logic.
onBackPressed();
}
public void method()
{
myOnBackPressed(myInt, myString);
}

Related

Is there any way to Detect userInterations in Android fragments?

Could any one help me out with this situation.
I have implemented OnUserInteraction() method for Android Activity it is working fine for me.
But I want it for Fragments too.How can i able call OnUserInteraction() or is there any another way to identify userInteraction with the UI.
#Sunil's answer causes java.lang.StackOverflowError so I corrected it. Below code works smoothly
Create a java class in your app named UserInterationListener and put below code there
public interface UserInteractionListener {
void onUserInteraction();
}
Then create an instance variable in your activity, for this interface as below
private UserInteractionListener userInteractionListener;
Then implement a setter method for this variable, in your activity.
public void setUserInteractionListener(UserInteractionListener userInteractionListener) {
this.userInteractionListener = userInteractionListener;
}
Now override the onUserInteraction method of your activity and if the listener variable is not null, invoke the interface method.
#Override
public void onUserInteraction() {
super.onUserInteraction();
if (userInteractionListener != null)
userInteractionListener.onUserInteraction();
}
Now, in your fragment class, implement UserInteractionListener as below
public myFragment extends Fragment implements UserInteractionListener
also override interface's method
#Override
public void onUserInteraction(){
//TODO://do your work on user interaction
}
then in your fragment invoke your activity's userinteraction setter method like below
((YourActivity) getActivity()).setUserInteractionListener(this);
this last part is important.
There is another way around.
Create a listener in your activity as below
public interface UserInteractionListener {
void onUserInteraction();
}
Then create an instance variable in your activity, for this interface as below
private UserInteractionListener userInteractionListener;
Then implement a setter method for this variable, in your activity. (You can even keep a List of eventlistener objects, if you want to pass same userinteraction to multiple consumers)
public void setUserInteractionListener(UserInteractionListener userInteractionListener) {
this.userInteractionListener = userInteractionListener;
}
Now override the onUserInteraction method of your activity and if the listener variable is not null, invoke the interface method.
#Override
public void onUserInteraction() {
super.onUserInteraction();
if (userInteractionListener != null)
userInteractionListener.onUserInteraction();
}
Now, in your fragment class, register for events as below
((YourActivity) getActivity()).setUserInteractionListener(new YourActivity.UserInteractionListener() {
#Override
public void onUserInteraction() {
// Do whatever you want here, during user interaction
}
});

How can I Perform networking(save results in the database using volley) based on the result I got from a fragment?

I have an activity and a fragment. If I click a button then a fragment is called. Upon the result I got from the fragment I need some networking call to perform using volley. But I can't do any networking call from activity unless I call this within onClick() method.
I tried to perform networking from within onClick() of the fragment but that did not worked too.
How can i perform networking from the activity upon the result I got from the fragment? Do I must call from within onClick()?
This is the fragment
This is the Activity
I think that you can use callback.
Create intefrace and declare method saveResult() in it.
public interface YourInterface{
void saveResult();
}
After that your Activity must implement this interface and add your code for save result in database in saveResult method body
public class YourActivity implements YourInterface{
#override
void saveResult(){
//your code here
}
}
And finnaly in your fragment call method when you whant or when your fragment is ready.You can call method with help of
callBack.saveResult();
You must override onAttach in your fragment and there must initialize your callback
YourInterface callback;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if(activity instanceof YourInterface ) {
callback = (YourInterface ) activity;
}
}
Try with other on click method in at your onCreate method
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mark_distribution);
assign_buttton=(Button)findViewById(R.id.assign_marks);
view_buttton=(Button)findViewById(R.id.view_marks);
update_buttton=(Button)findViewById(R.id.update_marks);
//Like this-->>>
update_buttton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
marks_type=(String)assigned_marks_type.getText().toString();
marks=Integer.parseInt(assigned_marks.getText().toString().trim());
callback.saveResult(marks_type,marks);
}
});
//********************/
Intent i=getIntent();
course_title= i.getExtras().getString("COURSE_TITLE");
}
Hope to help you!

How can one know if an activity is started without a transition?

I have a use case where I mostly start an activity with a transition, but that's not the case when opening it from the navigation drawer.
To keep the transition smooth I have a Transition.TransitionListener in which I trigger some UI updating when the transition is done.
So I have something like this:
public class SomeActivity extends Activity {
public void onCreate(Bundle savedInstanceState){
// ...
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
Transition sharedElementEnterTransition = getWindow().getSharedElementEnterTransition();
sharedElementEnterTransition.addListener(new Transition.TransitionListener() {
// ...
#Override
public void onTransitionEnd(Transition transition) {
doSomeUiUpdating();
}
});
} else { // Pre-Lollipop
doSomeUiUpdating();
}
}
}
This works well when starting the Activity with the animation, but how can I know if the Activity was started without a transition so that I can call doSomeUiUpdating()?
I'm sure there must be a simple method in Activity, Window, Transition or somewhere that I have overlooked. I don't want to relay on the calling Activity to set some bundle that telling if the animation is showing or not.
You can try onTransitionStart of TransitionListener to set some boolean isAnimationStarted.
public class SomeActivity extends Activity {
private boolean isAnimationStarted = false;
public void onCreate(Bundle savedInstanceState) {
// ...
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
Transition sharedElementEnterTransition = getWindow().getSharedElementEnterTransition();
sharedElementEnterTransition.addListener(new Transition.TransitionListener() {
// ...
#Override
public void onTransitionEnd(Transition transition) {
doSomeUiUpdating();
}
#Override
public void onTransitionStarted(Transition transition) {
isAnimationStarted = true;
}
});
}
}
public void onStart() {
if (!isAnimationStarted) {
doSomeUiUpdating();
}
}
}
Since you are starting an Activity, you'll be making use of an Intent to start it. You can add extras to Intents and check for them in the onCreate() of the called Activity.
Let's assume that we have 2 Activities – ActivityA, and ActivityB.
Now, let's assume that ActivityA is the calling Activity, and that ActivityB is the called Activity.
In ActivityA, let's say you've written some code to start ActivityB with a SharedElementTransition.
#Override
public void onClick(View v) {
Intent startActivityBIntent = new Intent(getContext(), ActivityB.class);
startActivityBIntent.putExtra("IS_SHARED_ELEMENT_TRANSITION_ENABLED", true);
ActivityOptionsCompat activityOptionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), view, ViewCompat.getTransitionName(view));
startActivity(startActivityBIntent, activityOptionsCompat);
}
Now, if you notice above, I've passed an Intent extra with the putExtra() method. I've passed a Boolean value of true because I intend to start the Activity with a SharedElementTransition.
Now in ActivityB's onCreate() method, you can just check for the boolean value passed to the Intent. If you passed false, then you can add a conditional statement and perform your UI updating there. I've given you a small snippet below to help you get started:
private static final String isSharedElementTransitionEnabled = "IS_SHARED_ELEMENT_TRANSITION_ENABLED";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
// If you are postponing your SharedElementTransition, don't forget to call postponeEnterTransition() and override onPreDraw()
if (!getIntent().getExtras().getBoolean(isSharedElementTransitionEnabled)) {
//Do your UI updation here
}
}
The good thing about doing it this way is that you can then have full control over how your content transitions and your shared element transitions will play out.

How to get fragment tag or ID?

I have 2 fragments which are instantiated from the same class as the layouts are identical like so:
getSupportFragmentManager().beginTransaction().
add(R.id.leftContainer,new LeftFragmentClass(),"leftFrag").commit();
getSupportFragmentManager().beginTransaction().
add(R.id.rightFrag,new LeftFragmentClass(),"rightFrag").commit();
Within LeftFragmentClass there is a callback method which is called when the button within the fragment is pressed. After this some processing is done and data is displayed, however, right now the callback cannot distinguish which button was pressed. Is there a function which can return which fragment button was pressed?
For this type of condition i create a function inside fragment which will return me the instance of fragment and make the fragment constructor private something like:-
public class LeftFragmentClass extends Fragment{
private String fragmentTag = null;
public LeftFragmentClass(){}
public static LeftFragmentClass newInstance(String tag){
LeftFragmentClass mLeftFragmentClass = new LeftFragmentClass();
Bundle bundle = new Bundle();
bundle.putString ("tag",tag);
mLeftFragmentClass.setArgument(bundle);
return mLeftFragmentClass;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
tag = getArguments().getString("tag")
}
}
So i used newInstance function to create instance of LeftFragmentClass and pass the tag to it which i m setting to Fragment argument using bundle and inside onCreate get bundle using getArguments and from it the tag value. Pass this tag value as one of the parameter to your callback method to identify which button was clicked.
So from activity for getting instance of LeftFragmentClass you can write as
LeftFragmentClass mLeftFragmentClassLeft = LeftFragmentClass.newInstance("left")
LeftFragmentClass mLeftFragmentClassRight = LeftFragmentClass.newInstance("Right")
==== Edit ====
keep the fragment class constructors always public don't make it private as i suggested above in my sample code. Making it private will cause application to crash with exception
java.lang.RuntimeException: Unable to start activity
ComponentInfo{MainActivity}:
android.support.v4.app.Fragment$InstantiationException: Unable to
instantiate fragment com.thatswhy.AppAlertDialog: make sure class name
exists, is public, and has an empty constructor that is public
Fragment fragment = getFragmentManager().findFragmentByTag("Tag")
As per provided the info you can do something like this, in your callback method pass the button object and check accordingly,
Some code snippet to explain the same :
Suppose your callback method is onButtonClick() then you can pass button object like :
public void onButtonClick(Button button){
// check here with button id
if(button.getId() == R.id.button1) {
} else if(button.getId() == R.id.button1) {
}
}
Hope this makes things clear..
The cleanest way of doing this I've seen is to create two distinct View.OnClickListener(s) in the Activity.
Have a getter() for each. public View.OnClickListener getLeftButtonPressed(), public View.OnClickListener getRightButtonPressed()
Then when you instantiate your left and right instances of your fragment, just pass in the appropriate 'View.OnClickListener' to the constructor of the Fragment. This not only reduces the code in the Fragment(s), it also centralizes the 'logic' of what to do when buttons are pressed.
public class MyActivity extends Activity {
// create the two listeners
View.OnClickListener leftButtonListener = new View.OnClickListener() {
public void onClick(View v) {
leftButtonClicked(v);
}
});
View.OnClickListener rightButtonListener = new View.OnClickListener() {
public void onClick(View v) {
rightButtonClicked(v);
}
});
// 2 getters
public View.OnClickListener getLeftListener() { return this.leftButtonListener; }
public View.OnClickListener getRightListener() { return this.rightButtonListener; }
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.content_layout_id);
}
// actual logic of what to do when each button is pressed.
private void leftButtonClicked(View v){
// some logic here
}
private void rightButtonClicked(View v){
// some logic here
}
}
This removes you later having to keep track of which button was pressed by making use of strings and if/then/else blocks, etc.
Add a parameter to interface callback function in your fragment;
interface Interfacecallback{
public void callbackfunction(int fragid);
}
Interfacecallback interfacecallback;
//in your button click
//pass 1 for fragment right
//pass 2 for fragment left
interfacecallback.callbackfunction(1);
You can check the fragment tag using this line of code if it exists:-
Fragment mapFragment = getFragmentManager().findFragmentByTag("MapRestaurantFragment");

Is there a better way of checking how activity was finished in onDestroy than setting a flag?

I want to call foo() every time my activity is destroyed, unless it is destroyed as result of clicking on a specific menu option (that eventually calls finish()). Currently I do this by calling foo() on default in onDestroy, unless a FLAG is set to true, where FLAG is set when I intercept the click on the menu option.
Is there a better way of doing this than setting a flag? Perhaps some way I can attach a tag to Android's finish() so that I can see the reason? Normally I would just try to call foo where it applies, but I can't account for every reason an activity might be destroyed.
Further caveat is that I would prefer not to make changes to base class (RootActivity)
public abstract class RootActivity extends Activity{
private flag someCondition;
#Override
protected void onCreate(Bundle savedInstanceState){
//...
}
// ...
public void startJob(JobAction.Id jobaction){
if (!jobaction.someCondition){
return;
}else{
startSomeLongAsynchronousJob(someCondition);
finish(); //If this is why onDestroy happened in subclass, I dont want to call foo()
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
//...
startJob(JobAction.SOMEENUM); //Startjob is being called in the superclass
}
//...
}
public class SpecificJob extends SomeClassThatExtendsRoot{
private boolean FLAG = false;
#Override
public void onCreate(Bundle bundle){
super.onCreate(bundle);
//...
}
// ... some code ...
#Override
public onDestroy(){
if (!FLAG){ //Check if it was finish() that did this
foo();
}
super.onDestroy();
}
#Override
onOptionsItemSelected(MenuItem item){
super.onOptionsItemSelected(item);
if (item.getItemId()==r.id.DONTCALLFOO){
flag=true;
}
}
}
You have to override onSaveInstanceState in your activity.
#Override
protected void onSaveInstanceState(Bundle outState) {
Log.d("ApplicationFlow","onSaveInstanceState was called. System destroy your activity");
foo();
super.onSaveInstanceState(outState);
}
It is always called when the activity is destroyed by the system, and not by you (when you call finish()).
The purpose is give to user a chance to save some state in Bundle outState parameter. This bundle will be passed to onCreate(Bundle savedInstanceState) to the user restore the state, when the activity is going to be recreated.
See documentation

Categories

Resources