도전!7 문제에 이어서 작성했다.

 

<구현 목표>

액티비티는 총 5개. 로그인 화면, 메인메뉴, 고객 관리, 매출 관리, 상품관리

  • 로그인 화면 : 아이디와 비밀번호를 입력한 뒤 <로그인> 버튼을 누르면 메인메뉴로 넘어간다. (아이디, 비밀번호 입력이 되어있지 않을 경우 토스트로 입력하라는 메시지가 뜬다.)
  • 메인메뉴 : 3개의 버튼이 존재한다. <고객 관리>, <매출 관리>, <상품 관리> 버튼. 버튼을 누르면 각각의 화면으로 넘어간다.
  • 고객 관리 / 매출 관리 / 상품관리 : 화면 구성은 같다. 2개의 버튼이 존재한다. <메뉴로>, <로그인으로> 버튼.

       합쳐서 관리 액티비티라고 부르겠다.

       <메뉴로> : 직전 화면인 메인메뉴 화면으로 돌아간다.

       <로그인으로> : 초기화면인 로그인 화면으로 돌아간다.

이 때 어떤 화면으로부터 보내온 응답인지 토스트 메시지로 띄워야한다.

 

<구현>

1. 화면 구성

구분을 쉽게 하기 위해서 색을 변경해주었다. (좀 구리긴 하다)

 

2. <MainActivity.java>

package com.example.doitmission_07;

public class MainActivity extends AppCompatActivity {

    public static final int REQUEST_CODE = 100;
    EditText editText1, editText2;

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

        editText1 = findViewById(R.id.editTextText);
        editText2 = findViewById(R.id.editTextText2);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                System.out.println(editText1.getText());
                if(editText1.getText().length()==0 || editText2.getText().length()==0) { // 길이가 0, 즉 입력이 없을 경우 토스트 띄움
                    Toast.makeText(getApplicationContext(), "아이디와 비밀번호를 입력해주세요", Toast.LENGTH_LONG).show();
                }
                else{
                    Intent intent = new Intent(getApplicationContext(), MenuActivity.class);
                    startActivityForResult(intent, REQUEST_CODE);
                    //finish();
                }
            }
        });
    }
    
        @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(requestCode == REQUEST_CODE){
            if(resultCode==RESULT_CANCELED){
                String activity = data.getExtras().getString("activity"); // 문제 발생
                System.out.println(activity);
                Toast.makeText(getApplicationContext(), activity+" 화면으로부터 응답",Toast.LENGTH_LONG).show();
            }
            if(resultCode!= RESULT_OK){ // 성공 값이 아니라면 return
                return;
            }
        }
    }

}

 

크게 onClick 함수랑 onActivityResult 코드를 보겠다. 먼저 onClick을 보자.

2 - (1) onClick : 아이디, 비밀번호 입력이 되어있지 않은 경우

if(editText1.getText().length()==0 || editText2.getText().length()==0) {
   Toast.makeText(getApplicationContext(), "아이디와 비밀번호를 입력해주세요", Toast.LENGTH_LONG).show();
}

처음엔 조건문에 editText가 공백인지 구분하기 위해 editText1.getText().equals(" ")==true 를 사용했는데, 실행이 안되었다. equals를 이렇게 쓰는 게 아닌건가? 암튼, 길이가 0이면 공백이니까 그냥 length() 함수를 쓰는 방식으로 바꿨다.

 

2 - (2) onClick : 아이디, 비밀번호 입력이 된 경우

else{
     Intent intent = new Intent(getApplicationContext(), MenuActivity.class);
     startActivityForResult(intent, REQUEST_CODE);
     //finish();
}

startActivityForResult로 메인메뉴(MenuActivity)를 실행시켰다.

여기에 finish() 함수를 넣어버리는 바람에 실행 후 앱이 그냥 꺼져버리는 일이 발생함. ㅎ..

 

2 - (3) requestcode == REQUEST_CODE 가 성립한 이후의 코드를 보겠다.

만약 resultCode == RESULT_CANCELED면 실행된다. 왜 이렇게 했냐면,

관리액티비티에서는 2가지 버튼을 통해 '메인메뉴'로 가거나 '로그인화면'으로 갈 수 있다.

 

바로 이전 화면인 '메인메뉴'로 갈 시에 resultCode를 RESULT_OK로 보내주었다.

'로그인화면'으로 갈 시엔 다른 값을 반환해야하므로 걍 RESULT_CANCLED를 넣어주었다.

if(resultCode==RESULT_CANCELED){
     String activity = data.getExtras().getString("activity"); // 문제 발생
     Toast.makeText(getApplicationContext(), activity+" 화면으로부터 응답",Toast.LENGTH_LONG).show();
}

처음엔 저 코드에서 에러가 발생했다. 왜냐면

내가 생각한 intent 사용법 : 전역변수처럼 그냥 key와 value값을 선언하면 모든 액티비티에서 그 값을 사용할 수 있는 줄 알았음

-> 틀렸다! 액티비티의 순서가 1->2->3이고 각각 인텐트를 선언해서 다음 액티비티를 실행시켰을 때,

3->2->1로 가면서 인텐트를 각각 전달해주어야한다. (콘서트에서 다이빙한 가수를 관객들이 각자의 손으로 받아서 쭉 이동시키는 모습을 상상하면 이해가 쉬울 거다.(?))

 

그러니까, 저 코드에는 이상이 없다. 문제는 2번 순서를 맡은 메뉴 액티비티에서 자기가 받아온 key와 value를 메인 액티비티에 전달하지 않은 것이다. 그래서 저 코드에서는 "activity"라는 key 값이 없는데 실행하니까 문제가 발생한 것이다.

 

3. <MenuActivity.java>

package com.example.doitmission_07;

public class MenuActivity extends AppCompatActivity {
    public static final int REQUEST_CODE_MENU = 101;
    public static final int REQUEST_CODE_CM = 201;
    public static final int REQUEST_CODE_SM = 202;
    public static final int REQUEST_CODE_PM = 203;

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

        Button button1 = findViewById(R.id.button1);
        Button button2 = findViewById(R.id.button2);
        Button button3 = findViewById(R.id.button3);

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), CustomerManage.class);
                startActivityForResult(intent, REQUEST_CODE_CM);
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), SaleManage.class);
                startActivityForResult(intent, REQUEST_CODE_SM);
            }
        });

        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), ProductManage.class);
                startActivityForResult(intent, REQUEST_CODE_PM);
            }
        });
    }
    
        @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode==RESULT_CANCELED){
            String activity2 = data.getExtras().getString("activity");
            Intent intent = new Intent();
            intent.putExtra("activity", activity2);
            setResult(RESULT_CANCELED, intent);
            finish(); // 로그인 화면으로(가장 초기 화면으로)
        }
        if(resultCode!=RESULT_OK)
            return;
        if(data!=null) {
            String activity = data.getStringExtra("activity");
            if (activity != null) {
                Toast.makeText(getApplicationContext(), activity + " 화면으로부터 응답.", Toast.LENGTH_LONG).show();
            }
        }
    }
}

 

3 - (1) REQUEST_CODE 설정

public static final int REQUEST_CODE_CM = 201; // CustomerManage
public static final int REQUEST_CODE_SM = 202; // SaleManage
public static final int REQUEST_CODE_PM = 203; // ProductManage

위와 같이 설정해주었다.

 

3 - (2) 버튼의 onClick 메서드

public void onClick(View view) {
     Intent intent = new Intent(getApplicationContext(), CustomerManage.class);
     startActivityForResult(intent, REQUEST_CODE_CM);
}

위는 버튼1(고객 관리, CustomerManager)의 코드이다.

 

3 - (3) onActivityResult : 관리 액티비티 -> 로그인으로 (초기화면(MainActivity)으로 이동)

if(resultCode==RESULT_CANCELED){
    String activity2 = data.getExtras().getString("activity");
    Intent intent = new Intent();
    intent.putExtra("activity", activity2);
    setResult(RESULT_CANCELED, intent);
    finish(); // 로그인 화면으로(가장 초기 화면으로)
}

만약 resultCode==RESULT_CANCLED일 경우, 현 액티비티를 finish하고 메인 액티비티로 이동한다. (2-(3))

근데 finish() 하기 전에 관리 액티비티에서 받아온 값을 메인 액티비티로 넘겨야 하므로, 넘겨주는 코드를 작성한다.

(여기서 activity2 말고 그냥 activity로 써도 무관하다. 근데 나중에 다시 공부할 때, 값을 넘길 때 변수 이름을 동일하게 넘겨야 하나? 헷갈릴 수 있을 것 같아서 작성함. 변수 이름은 동일해도 되고 달라도 상관없음.)

 

3 - (4)  onActivityResult : 관리 액티비티 -> 메뉴로 (이전화면(MenuActivity)으로 이동)

if(data!=null) {
    String activity = data.getStringExtra("activity");
    if (activity != null) {
       Toast.makeText(getApplicationContext(), activity + " 화면으로부터 응답.", Toast.LENGTH_LONG).show();
    }
}

만약 data가 null이 아닌 경우. (putExtra로 값이 들어간 경우)

key 값인 "activity" 속의 값을 뽑아내, value 값을 토스트 메시지로 출력한다. 이를 통해 어느 화면으로부터 방금 응답을 받았는지 알 수 있다.

 

4. <CustomerManage.java>

package com.example.doitmission_07;

public class CustomerManage extends AppCompatActivity {

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

        Button menu_btn = findViewById(R.id.button1);
        Button login_btn= findViewById(R.id.button2);

        menu_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.putExtra("activity","고객 관리");
                setResult(RESULT_OK, intent);
                finish();
            }
        });

        login_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.putExtra("activity","고객 관리"); // 이거 안넣어서 에러난듯
                setResult(RESULT_CANCELED, intent);
                finish();
            }
        });
    }
}

 

4 - (1) <메뉴로> 버튼

menu_btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
       Intent intent = new Intent();
       intent.putExtra("activity","고객 관리");
       setResult(RESULT_OK, intent);
       finish();
    }
});

이전 화면으로 갈 것이기 때문에 RESULT_OK를 resultCode로 넣어준다.

 

4 - (2) <로그인으로> 버튼

login_btn.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
      Intent intent = new Intent();
      intent.putExtra("activity","고객 관리");
      setResult(RESULT_CANCELED, intent);
      finish();
    }
});

초기 화면으로 갈 것이기 때문에 RESULT_CANCELED를 resultCode로 넣어준다.

 

두 버튼 모두 해당 페이지의 이름을 인텐트 값으로 넣어준다.

(다른 관리 액티비티에는 다른 값을 넣어주게 설정한다. "매출 관리", "상품 관리")

 

5. 실행화면

 

아이디와 비밀번호를 입력하지 않으면 토스트 메시지가 뜬다.

입력 시 메인 메뉴가 뜬다.

 

메인 메뉴에서 <고객 관리> 버튼을 클릭해보았다.

 

<메뉴로> 버튼을 누르면 메인메뉴로, <로그인으로> 버튼을 누르면 로그인화면으로 간다.

이때 두 화면에서 모두 어떤 버튼에서 응답이 온 것인지 토스트 메시지를 띄운다.

 

다른 <관리> 버튼을 눌러도 동일한 실행이 이루어졌다.

 

<새로 알게된 점>

인텐트에 대해 좀 더 개념적인 이해를 했다.(전역변수 개념이 아니고 이전에 선언한 것에 종속되는 형태)