Android Back Directly To Root Activity

Awhile ago I had to fix a back flow navigation between activities. I had 4 activities A -> B -> C -> D and If I pressed the back button from Activity D I wanted to go back to A. And if I was in Activity C and the back button was pressed I needed to go back to B. I tried with Intent.FLAG_ACTIVITY_CLEAR_TOP, but it didn’t work for me. So the solution to this situation was to use onActivityResult().

Here’s how I implemented the code:

1. Create 4 activities: ActivityA, ActivityB, ActivityC and ActivityD

2. Create only one xml file (for the purpose of this tutorial) and name it activity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".ActivityA">

    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textColor="@android:color/black"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button"/>

</RelativeLayout>

 3. ActivityA 

For ActivityA we will just open the next activity (B).

package com.example.test;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class ActivityA extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);

        TextView activityNameTextView = (TextView)findViewById(R.id.text_view);
        activityNameTextView.setText("Activity A");

        Button button = (Button) findViewById(R.id.button);
        button.setText("Open Activity B");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Launch Activity B
                Intent intent = new Intent();
                intent.setClass(ActivityA.this, ActivityB.class);
                startActivity(intent);
            }
        });
    }
}

 4. ActivityB

In this activity we have to add code for starting the next activity (C) using startActivityForResult.

NOTE: resultCode=101 and requestCode=100 are aleatory numbers.

package com.example.test;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class ActivityB extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);

        TextView activityNameTextView = (TextView)findViewById(R.id.text_view);
        activityNameTextView.setText("Activity B");


        Button button = (Button) findViewById(R.id.button);
        button.setText("Open Activity C");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Launch Activity C
                Intent intent = new Intent();
                intent.setClass(ActivityB.this, ActivityC.class);

                startActivityForResult(intent, 100);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == 100){
            if (resultCode == 101) {
                finish();
            }
        }
    }
}

 5. ActivityC

In this activity we have to use startActivityForResult() and setResult(). The latter will be added only when we want to open ActivityD, because in this case if ActivityD is opened and we press the back button we will want to navigate directly to ActivityA, and this can be achieved by setting this result. But if we don’t want to open ActivityD and we press the back button from C, we want to navigate to B and in this case by NOT setting the result, the onActivityResult() method will not be called and therefore ActivityB will be displayed.

package com.example.test;

import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class ActivityC extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);

        TextView activityNameTextView = (TextView)findViewById(R.id.text_view);
        activityNameTextView.setText("Activity C");


        Button button = (Button) findViewById(R.id.button);
        button.setText("Open Activity D");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Launch Activity D
                Intent intent = new Intent();
                intent.setClass(ActivityC.this, ActivityD.class);

                // When we want to open last Activity (D) call setResult() in order to be received
                // in Activity B and onActivityResult() from B will be called. If this button is not
                // clicked and the user navigates from Activity C to B,
                // the onActivityResult from B will NOT be called.
                setResult(101);

                startActivityForResult(intent, 100);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == 100){
            if (resultCode == 101) {
                finish();
            }
        }
    }
}

 6. ActivityD

package com.example.test;

import android.app.Activity;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;


public class ActivityD extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);

        TextView activityNameTextView = (TextView)findViewById(R.id.text_view);
        activityNameTextView.setText("Activity D");

        // When we are on the last Activity (D) call setResult() in order to be received
        // in Activity C so onActivityResult() from C will be called
        setResult(101);
    }
}

 

 

Android Studio Tip #6 – Multiple Cursors

I have heard before about this “ability” of Android Studio of having multiple cursors active at the same time, but I haven’t found it very useful until today. You can see what I am talking about in the gif below:

Press ALT + SHIFT and left click on the mouse and select the position of each cursor.

multipleCursors

As you can see, this feature is really cool :D

Android Studio Tip #5 – Autocomplete “for” statement

When you want to write a for statement most of you guys (or at least me :P) start to write character by character “for (int i = 0; i < list.size(); i++)”. Well Android Studio makes this easier for us and we can avoid writing that much by using a combination of 2 keys:

CTRL + J

If you are inside a method and you want to generate a for statement you just have to press CTRL + J and select fori option from the dialog. You will just have to fill in the size of the list.

fori

 

As you can see, there are more options from where you can choose. So you can generate iterators and other stuff, not just the for statement. So please feel free to try more of these options :D