MyTetra Share
Делитесь знаниями!
Урок 30. Подробнее про onActivityResult. Зачем нужны requestCode и resultCode
23.04.2017
11:21
Текстовые метки: Activity, onActivityResult
Раздел: Android - Ресурсы - StartAndroid

Урок 30. Подробнее про onActivityResult. Зачем нужны requestCode и resultCode

03 ноября 2011

В этом уроке:

- разбираемся, зачем нужны requestCode и resultCode в onActivityResult

 

На прошлом уроке мы поверхностно рассмотрели, как вызвать Activity, и как сделать так, чтобы она вернула результат. Рассмотрим немного подробней этот механизм. Создадим приложение, которое будет вызывать два разных Activity и получать от них результат. Как мы помним, результат приходит в метод onActivityResult. И requestCode используется, чтобы отличать друг от друга пришедшие результаты. А resultCode – позволяет определить успешно прошел вызов или нет.

 

Создадим проект:

Project name: P0301_ActivityResult
Build Target: Android 2.3.3
Application name: ActivityResult
Package name: ru.startandroid.develop.p0301activityresult
Create Activity: MainActivity

 

Нарисуем экран в main.xml:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical">

    <TextView

        android:id="@+id/tvText"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:layout_marginTop="20dp"

        android:gravity="center_horizontal"

        android:text="Hello World"

        android:textSize="20sp">

    </TextView>

    <LinearLayout

        android:id="@+id/linearLayout1"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_margin="20dp"

        android:orientation="horizontal">

        <Button

            android:id="@+id/btnColor"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_marginRight="5dp"

            android:layout_weight="1"

            android:text="Color">

        </Button>

        <Button

            android:id="@+id/btnAlign"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_marginLeft="5dp"

            android:layout_weight="1"

            android:text="Alignment">

        </Button>

    </LinearLayout>

</LinearLayout>

На экране TextView с текстом. И две кнопки для выбора цвета шрифта и выравнивания текста в TextView. Нажатие на кнопку будет вызывать Activity для выбора и получать обратно результат.

Давайте начнем кодить в MainActivity.java:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

package ru.startandroid.develop.p0301activityresult;

 

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;

 

public class MainActivity extends Activity implements OnClickListener {

   

  TextView tvText;

  Button btnColor;

  Button btnAlign;

   

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

         

        tvText = (TextView) findViewById(R.id.tvText);

         

        btnColor = (Button) findViewById(R.id.btnColor);

        btnAlign = (Button) findViewById(R.id.btnAlign);

         

        btnColor.setOnClickListener(this);

        btnAlign.setOnClickListener(this);

         

    }

 

  @Override

  public void onClick(View v) {

    // TODO Auto-generated method stub

     

  }

}

Определили экранные элементы, прописали обработчик кнопкам и пока остановимся на этом.

 

Создадим два других Activity. Начнем с Activity для выбора цвета. Создадим layout-файл color.xml:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="horizontal">

    <Button

        android:id="@+id/btnRed"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_margin="5dp"

        android:layout_weight="1"

        android:text="Red">

    </Button>

    <Button

        android:id="@+id/btnGreen"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_margin="5dp"

        android:layout_weight="1"

        android:text="Green">

    </Button>

    <Button

        android:id="@+id/btnBlue"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_margin="5dp"

        android:layout_weight="1"

        android:text="Blue">

    </Button>

</LinearLayout>

 

Создаем класс ColorActivity. ColorActivity.java:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

package ru.startandroid.develop.p0301activityresult;

 

import android.app.Activity;

import android.content.Intent;

import android.graphics.Color;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

 

public class ColorActivity extends Activity implements OnClickListener {

   

  Button btnRed;

  Button btnGreen;

  Button btnBlue;

   

  @Override

  protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.color);

     

    btnRed = (Button) findViewById(R.id.btnRed);

    btnGreen = (Button) findViewById(R.id.btnGreen);

    btnBlue = (Button) findViewById(R.id.btnBlue);

     

    btnRed.setOnClickListener(this);

    btnGreen.setOnClickListener(this);

    btnBlue.setOnClickListener(this);

  }

 

  @Override

  public void onClick(View v) {

    Intent intent = new Intent();

    switch (v.getId()) {

    case R.id.btnRed:

      intent.putExtra("color", Color.RED);

      break;

    case R.id.btnGreen:

      intent.putExtra("color", Color.GREEN);

      break;

    case R.id.btnBlue:

      intent.putExtra("color", Color.BLUE);

      break;

    }

    setResult(RESULT_OK, intent);

    finish();

  }

}

Как обычно определяем элементы, присваиваем обработчик кнопкам и реализуем onClick. В onClick мы создаем Intent, затем определяемкнопка с каким цветом была нажата и помещаем в Intent объект с именем color и значением цвета. Ставим статус RESULT_OK, указываем, что надо вернуть объект intent в качестве результата и закрываем Activity. Для значения цветов используем системные константы.

 

Аналогично создаем Activity для выбора выравнивания.

Layout-файл align.xml:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="horizontal">

    <Button

        android:id="@+id/btnLeft"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_margin="5dp"

        android:layout_weight="1"

        android:text="Left">

    </Button>

    <Button

        android:id="@+id/btnCenter"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_margin="5dp"

        android:layout_weight="1"

        android:text="Center">

    </Button>

    <Button

        android:id="@+id/btnRight"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_margin="5dp"

        android:layout_weight="1"

        android:text="Right">

    </Button>

</LinearLayout>

 

 

AlignActivity.java:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

package ru.startandroid.develop.p0301activityresult;

 

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.Gravity;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

 

public class AlignActivity extends Activity implements OnClickListener {

   

  Button btnLeft;

  Button btnCenter;

  Button btnRight;

   

  @Override

  protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.align);

     

    btnLeft = (Button) findViewById(R.id.btnLeft);

    btnCenter = (Button) findViewById(R.id.btnCenter);

    btnRight = (Button) findViewById(R.id.btnRight);

     

    btnLeft.setOnClickListener(this);

    btnCenter.setOnClickListener(this);

    btnRight.setOnClickListener(this);

  }

 

  @Override

  public void onClick(View v) {

    Intent intent = new Intent();

    switch (v.getId()) {

    case R.id.btnLeft:

      intent.putExtra("alignment", Gravity.LEFT);

      break;

    case R.id.btnCenter:

      intent.putExtra("alignment", Gravity.CENTER);

      break;

    case R.id.btnRight:

      intent.putExtra("alignment", Gravity.RIGHT);

      break;

    }

    setResult(RESULT_OK, intent);

    finish();

  }

}

Здесь все аналогично, как и в ColorActivity. Только работаем не с цветами, а с выравниванием. Не забудьте прописать оба Activity в манифесте.

Теперь можем завершить код в MainActivity.java. Добавим пару своих констант в класс для удобства:


1

2

final int REQUEST_CODE_COLOR = 1;

final int REQUEST_CODE_ALIGN = 2;

Эти константы далее будем использовать в качестве requestCode.

 

Допишем метод onClick:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

@Override

public void onClick(View v) {

  Intent intent;

  switch (v.getId()) {

  case R.id.btnColor:

    intent = new Intent(this, ColorActivity.class);

    startActivityForResult(intent, REQUEST_CODE_COLOR);

    break;

  case R.id.btnAlign:

    intent = new Intent(this, AlignActivity.class);

    startActivityForResult(intent, REQUEST_CODE_ALIGN);

    break;

  }

}

 

Мы определяем, какая кнопка была нажата и посылаем Intent с ожиданием возврата результата. Два вызова отличаются классом вызываемого Activity и параметром requestCode в методе startActivityForResult. При вызове ColorActivity используем константу REQUEST_CODE_COLOR, а при вызове AlignActivity -REQUEST_CODE_ALIGN. Эту константу мы обратно получим в методе обработки результата –onActivityResult, и по ней сможем определить из какого именно Activity пришел результат.

Давайте реализуем метод onActivityResult в MainActivity.java:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

  // запишем в лог значения requestCode и resultCode

  Log.d("myLogs", "requestCode = " + requestCode + ", resultCode = " + resultCode);

  // если пришло ОК

  if (resultCode == RESULT_OK) {

    switch (requestCode) {

    case REQUEST_CODE_COLOR:

      int color = data.getIntExtra("color", Color.WHITE);

      tvText.setTextColor(color);

      break;

    case REQUEST_CODE_ALIGN:

      int align = data.getIntExtra("alignment", Gravity.LEFT);

      tvText.setGravity(align);

      break;

    }

  // если вернулось не ОК

  } else {

    Toast.makeText(this, "Wrong result", Toast.LENGTH_SHORT).show();

  }

}

Для наглядности пишем в лог значения переменных.

Вспоминаем, что в ColorActivity и AlignActivity в методе setResult мы ставили статус RESULT_OK при отправке результата. Значит в onActivityResult нам надо ожидать этот статус, как обозначение успешного окончания вызова.

Если вызов прошел успешно (resultCode = RESULT_OK), то мы смотрим значение requestCode. Если оно равно константе REQUEST_CODE_COLOR, то вспоминаем, что мы использовали эту константу в методеstartActivityForResult, когда отправляли запрос на выбор цвета. Значит, нам пришел результат этоговыбора. Мы берем Intent (data) и извлекаем из него значение объекта с именем color и присваиваем это значение цвету текста в TextView. Константа Color.WHITE в методе getIntExtra означает значение по умолчанию. Т.е. если в Intent не найдется объекта с именем color, то метод вернет белый (white) цвет.

Аналогично для REQUEST_CODE_ALIGN. Эту константу мы использовали для запроса выбора выравнивания. И если в методе onActivityResult параметр requestCode = этой константе, значит пришел ответ на запрос выравнивания. И мы считываем это значение из Intent и присваиваем его атрибуту Gravity для TextView.

Если resultCode не равен RESULT_OK, значит что-то пошло не так. Выводим на экран соответствующее сообщение. Этот случай может наступить, например, если на экране выбора не делать выбор, а нажать кнопку Назад.

Давайте все сохраним и запустим приложение.

Нажмем Color

 

и выберем, например Red

 

Цвет изменился

 

смотрим лог:

requestCode = 1, resultCode = -1

requestCode пришедший в метод onActivityResult равен 1. Все верно, это значение константыREQUEST_CODE_COLOR, которое мы использовали при вызове.

resultCode = -1 – это значение системной константы RESULT_OK 

Т.е. все верно, пришел ответ на запрос цвета, и его статус = RESULT_OK.

 

Теперь жмем Alignment и выбираем Right, получаем выравнивание вправо:

Смотрим лог:

requestCode = 2, resultCode = -1

requestCode = 2, что равно константе REQUEST_CODE_ALIGN. Значит пришел ответ на запрос выравнивания.

resultCode = -1, т.е. RESULT_OK.

 

Теперь снова жмем Color

но вместо того, чтобы выбрать цвет нажмем кнопку назад

 

Отобразилось наше сообщение об ошибке. Смотрим логи:

requestCode = 1, resultCode = 0

requestCode = 1 – все верно, мы запрашивали цвет (REQUEST_CODE_COLOR)

resultCode = 0, это значение константы RESULT_CANCELED, значит вызов прошел неудачно

Ограничений на значение статуса в методе setResult нет. RESULT_OK и RESULT_CANCELED – системные общепринятые константы. Но вы можете свободно использовать свои значения, если в этом есть необходимость.

 

Итак, подведем итог.

requestCode – это в некотором роде ID запроса. Задается в методе startActivityForResult, и проверяется потом в onActivityResult, чтобы точно знать, на какой вызов пришел ответ.

resultCode – статус вызова. Задается в методе setResult, и проверяется в onActivityResult, чтобы понять насколько успешно прошел вызов. Если при вызове что-то пошло не так, то вернется системная константаRESULT_CANCELED.

 

Полный код MainActivity.java:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

package ru.startandroid.develop.p0301activityresult;

 

import android.app.Activity;

import android.content.Intent;

import android.graphics.Color;

import android.os.Bundle;

import android.util.Log;

import android.view.Gravity;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;

import android.widget.Toast;

 

public class MainActivity extends Activity implements OnClickListener {

 

  final int REQUEST_CODE_COLOR = 1;

  final int REQUEST_CODE_ALIGN = 2;

 

  TextView tvText;

  Button btnColor;

  Button btnAlign;

 

  /** Called when the activity is first created. */

  @Override

  public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

 

    tvText = (TextView) findViewById(R.id.tvText);

 

    btnColor = (Button) findViewById(R.id.btnColor);

    btnAlign = (Button) findViewById(R.id.btnAlign);

 

    btnColor.setOnClickListener(this);

    btnAlign.setOnClickListener(this);

  }

 

  @Override

  public void onClick(View v) {

    Intent intent;

    switch (v.getId()) {

    case R.id.btnColor:

      intent = new Intent(this, ColorActivity.class);

      startActivityForResult(intent, REQUEST_CODE_COLOR);

      break;

    case R.id.btnAlign:

      intent = new Intent(this, AlignActivity.class);

      startActivityForResult(intent, REQUEST_CODE_ALIGN);

      break;

    }

  }

 

  @Override

  protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    // запишем в лог значения requestCode и resultCode

    Log.d("myLogs", "requestCode = " + requestCode + ", resultCode = " + resultCode);

    // если пришло ОК

    if (resultCode == RESULT_OK) {

      switch (requestCode) {

      case REQUEST_CODE_COLOR:

        int color = data.getIntExtra("color", Color.WHITE);

        tvText.setTextColor(color);

        break;

      case REQUEST_CODE_ALIGN:

        int align = data.getIntExtra("alignment", Gravity.LEFT);

        tvText.setGravity(align);

        break;

      }

      // если вернулось не ОК

    } else {

      Toast.makeText(this, "Wrong result", Toast.LENGTH_SHORT).show();

    }

  }

}

 

Так же в этом разделе:
 
MyTetra Share v.0.52
Яндекс индекс цитирования