Do it 안드로이드 앱 프로그래밍 도전과제 - do it andeuloideu aeb peulogeulaeming dojeongwaje

Do it 안드로이드 앱 프로그래밍 도전과제 - do it andeuloideu aeb peulogeulaeming dojeongwaje

도전과제 15

고객 정보 입력 화면을 만들고 이 화면이 보이거나 사라질 때 애니메이션이 동작하도록 해보세요.

  1. 새로운 액티비티를 추가하고 고객 정보 입력이 가능하도록 만듭니다. 고객 정보 입력 화면에서는 이름과 나이, 전화번호를 입력받도록 만듭니다.
  2. MainActivity에서 [입력 화면으로] 버튼을 누르면 고객 정보 입력 화면이 보이도록 합니다. 이 과정에서 오른쪽에서 왼쪽으로 나타나는 애니메이션을 적용합니다.
  3. 고객 정보 입력 화면에서 [저장] 버튼을 누르면 MainActivity로 돌아오도록 합니다. 이 과정에서도 애니메이션을 적용합니다.

참고할 점
화면 전체에 애니메이션을 적용할 수 있습니다.

풀이

레이아웃은 간단하게 main화면과, 버튼을 누르면 나올 고객정보 입력 창을 만들었다. 
애니메이션을 만들어야 하는데, 애니메이션은 우선 res/anim 폴더에 3개의 xml 파일로 구성하였다.

<!--move_right.xml-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0%p"
        android:toXDelta="100%p"
        android:duration="500"
        android:fillAfter="true"
        android:repeatCount="0"
        />
</set>

<!--move_left.xml-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="100%p"
        android:toXDelta="0%p"
        android:duration="500"
        android:fillAfter="true"
        android:repeatCount="0"
        />

</set>

<!--not_move.xml-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="0" android:duration="500"/>
</set>

오른쪽으로 화면이 이동하는 move_right와 왼쪽으로 화면이 이동하는 move_left, 그리고 안움직이는 not_move이다.
여기서 fromXDelta -> toXDelta까지 이동한다는 뜻이고, duration은 지속시간. fillAfter는 애니메이션  이후 애니메이션 마지막 결과를 적용시킬 것이냐는 뜻이다. Delta값에 음수를 주면 화면 밖에서부터 움직이는 것도 가능하다.
액티비티 역시 메인액티비티와, 고객정보 입력 액티비티가 있는데, 액티비티에 애니메이션을 적용하는 것은 간단하다.
액티비티 전환 시 overridePendingTransition(새 액티비티에 적용할 애니메이션, 기존 액티비티에 적용할 애니메이션)을 활용하면 화면 전환시 애니메이션이 적용된다.
finish 이후에 사라지는 애니메이션까지 한번 더 적용해 주면 잘 바뀐다.

public class MainActivity extends AppCompatActivity {
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.textView2);

        Button button = findViewById(R.id.Button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), CustomerInfo.class);
                startActivity(intent);
                overridePendingTransition(R.anim.move_right, R.anim.not_move); //애니메이션 적용
                finish();
                overridePendingTransition(R.anim.move_left, R.anim.not_move);
            }
        });

        Intent intent = getIntent();
        String name = intent.getStringExtra("name");
        if(name != null ){
            textView.setText( name + "\n" + intent.getStringExtra("age") + "\n" + intent.getStringExtra("date"));
        }

    }
}

결과

Do it 안드로이드 앱 프로그래밍 도전과제 - do it andeuloideu aeb peulogeulaeming dojeongwaje
잘 돌아간다

전체 소스 코드 : https://github.com/howtolivelikehuman/DoitAndroid/tree/master/DoitMission_15

howtolivelikehuman/DoitAndroid

Do it Android programing (JAVA). Contribute to howtolivelikehuman/DoitAndroid development by creating an account on GitHub.

github.com

Do it 안드로이드 앱 프로그래밍 도전과제 - do it andeuloideu aeb peulogeulaeming dojeongwaje

Do it 안드로이드 앱 프로그래밍 도전과제 - do it andeuloideu aeb peulogeulaeming dojeongwaje

Do it 안드로이드 앱 프로그래밍 도전과제 - do it andeuloideu aeb peulogeulaeming dojeongwaje

Do it 안드로이드 앱 프로그래밍 도전과제 - do it andeuloideu aeb peulogeulaeming dojeongwaje

도전과제 07,08

앱에서 사용될 수 있는 여러 화면을 구성하고 각 화면을 전환하면서 토스트로 메시지를 띄워주도록 만들어 보세요.

  1. 로그인 화면과 메뉴화면 그리고 세 개의 서브 화면(고객 관리 화면, 매출 관리 화면, 상품 관리 화면)을 각각 액티비티로 만듭니다.
  2. 로그인 화면에는 두 개의 입력상자와 하나의 버튼이 들어가도록 합니다.
  3. 메뉴 화면에는 세 개의 버튼이 들어가도록 하고 각각 '고객 관리', '매출 관리', '상품 관리' 라는 이름으로 표시 합니다.
  4. 로그인 화면의 [로그인] 버튼을 누르면 메뉴 화면으로 이동합니다. 만약 사용자 이름이나 비밀번호가 입력되어 있지 않은 상태에서 [로그인] 버튼을 누르면 토스트로 입력하라는 메시지를 보여주고 대기합니다.
  5. 메뉴 화면의 버튼 중에서 하나를 누르면 해당 서브 화면으로 이동합니다. 메뉴 화면에 있는 [로그인] 버튼을 누르면 로그인 화면으로 이동하고 각 서브 화면에 있는 [메뉴] 버튼을 누르면 메뉴 화면으로 이동합니다.

참고할점
각 화면은 액티비티로 만들고 startActivityForResult() 메서드로 새로 띄우거나
finish() 메서드를 사용해서 원래의 화면으로 돌아올 수 있게 합니다.
그리고 어떤 화면으로부터 보내온 응답인지 모두 확인하여 토스트 메시지로 보여줍니다.

풀이

Do it 안드로이드 앱 프로그래밍 도전과제 - do it andeuloideu aeb peulogeulaeming dojeongwaje

우선 로그인 화면인 activity_main, 버튼 3개가 있는 activity_menu, 메뉴에서 갈 수 있는 activity_customer, activity_sales, acitivity_product 세 화면을 만든다. 이때 로그인 화면에서 아이디, 비밀번호 입력창은 maxLine = 1로 정의해서 한 줄만 입력되게 한다. 

public class MainActivity extends AppCompatActivity {
    public static final int MENU_CODE_FROM_MAIN = 101;
    public static final int MAIN_CODE_FROM_CUSTOMER = 112;
    public static final int MAIN_CODE_FROM_SALES = 113;
    public static final int MAIN_CODE_FROM_PRODUCT = 114;

    EditText editID;
    EditText editPW;
    String ID;
    String PW;

    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == MAIN_CODE_FROM_CUSTOMER) {
            Toast.makeText(getApplicationContext(),"고객 관리 -> 로그인",Toast.LENGTH_LONG).show();
        }
        else if(resultCode == MAIN_CODE_FROM_SALES) {
            Toast.makeText(getApplicationContext(),"매출 분석 -> 로그인",Toast.LENGTH_LONG).show();
        }
        else if(resultCode == MAIN_CODE_FROM_PRODUCT){
            Toast.makeText(getApplicationContext(),"상품 분석 -> 로그인",Toast.LENGTH_LONG).show();
        }

    }

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

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

        editID = findViewById(R.id.editText1);
        editPW = findViewById(R.id.editText2);

        editID.getText().toString();

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(checkID()){
                    Intent intent = new Intent(getApplicationContext(), MenuActivity.class);
                    SimpleData data = new SimpleData(ID,PW);
                    intent.putExtra("data",data);
                    startActivityForResult(intent,MENU_CODE_FROM_MAIN);
                }
                else{
                    Toast.makeText(getApplicationContext(),"ID/PW를 입력하세요", Toast.LENGTH_LONG).show();
                }
            }
        });

    }
    private boolean checkID(){
       ID = editID.getText().toString();
       PW = editPW.getText().toString();

       if(ID.length() < 1 || PW.length() < 1){
           return false;
       }
       else return true;
    }
}

메인 액티비티에서 로그인 버튼을 누르면 checkID()로 ID, PASSWORD를 다 쳤는지 확인하고, 메뉴 액티비티로 코드를 넘기며넘어간다. 이때 인텐트에 ID, PW 데이터가 담겨있다.

public class MenuActivity extends AppCompatActivity {

    public static final int MENU_CODE_FROM_MAIN = 101;
    public static final int CUSTOMER_CODE_FROM_MENU = 102;
    public static final int MAIN_CODE_FROM_CUSTOMER = 112;
    public static final int MENU_CODE_FROM_CUSTOMER = 122;
    public static final int SALES_CODE_FROM_MENU = 103;
    public static final int MAIN_CODE_FROM_SALES = 113;
    public static final int MENU_CODE_FROM_SALES = 123;
    public static final int PRODUCT_CODE_FROM_MENU = 104;
    public static final int MAIN_CODE_FROM_PRODUCT = 114;
    public static final int MENU_CODE_FROM_PRODUCT = 124;
    SimpleData data;


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode ==  MENU_CODE_FROM_MAIN) {
                Toast.makeText(getApplicationContext(),"메인 -> 메뉴",Toast.LENGTH_LONG).show();
            }
        else if(resultCode == MENU_CODE_FROM_CUSTOMER) {
                Toast.makeText(getApplicationContext(),"고객 관리 -> 메뉴",Toast.LENGTH_LONG).show();
            }
        else if(resultCode == MAIN_CODE_FROM_CUSTOMER){	//고객관리에서 메인일때
            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
            setResult(MAIN_CODE_FROM_CUSTOMER,intent);	//메뉴를 거쳤다가 메인으로 가게 만듦 (코드를 메인으로 전달)
            finish();
            }
        else if(resultCode == MENU_CODE_FROM_SALES) {
                Toast.makeText(getApplicationContext(),"매출 분석 -> 메뉴",Toast.LENGTH_LONG).show();
            }
        else if(resultCode == MAIN_CODE_FROM_SALES){
            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
            setResult(MAIN_CODE_FROM_SALES,intent);
            finish();
        }
        else if(resultCode == MENU_CODE_FROM_PRODUCT){
                Toast.makeText(getApplicationContext(),"상품 분석 -> 메뉴",Toast.LENGTH_LONG).show();
            }
        else if(resultCode == MAIN_CODE_FROM_PRODUCT){
            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
            setResult(MAIN_CODE_FROM_PRODUCT,intent);
            finish();
        }
    }

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

        data = getData(getIntent());

        Button button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), CustomerActivity.class);
                intent.putExtra("data",data);
                startActivityForResult(intent, CUSTOMER_CODE_FROM_MENU);
            }
        });
        Button button3 = findViewById(R.id.button3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), SalesActivity.class);
                intent.putExtra("data",data);
                startActivityForResult(intent,SALES_CODE_FROM_MENU);
            }
        });
        Button button4 = findViewById(R.id.button4);
        button4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), ProductActivity.class);
                intent.putExtra("data",data);
                startActivityForResult(intent,  PRODUCT_CODE_FROM_MENU );
            }
        });
    }
    private SimpleData getData(Intent intent){
        if(intent != null){
            Bundle bundle = intent.getExtras();
            SimpleData data = bundle.getParcelable("data");
            return data;
        }
        else{
            return null;
        }
    }
}

메뉴 액티비티에서의 버튼 3개는 각각의 액티비티로 전환되게 연결해놓았고, 메인에서 온 데이터 (ID,PW)값을 그대로 전달한다. 이때 각 화면 전환별로 토스트 메세지는 onActivityResult()함수로 resultcode에 따라 출력하게 만들었다. 각각의 토스트 메세지를 인텐트에 넣어서 전달해도 되지만, onActivityResult 함수를 사용해보고 싶어서 이런 방식으로 했다. 이때 액티비티 진행 방식은 다음과 같다.

Do it 안드로이드 앱 프로그래밍 도전과제 - do it andeuloideu aeb peulogeulaeming dojeongwaje

따라서 각각의 액티비티 실행 이후 메뉴, 메인으로 돌아갈때 setResult함수로 돌아갈 코드값을 넣고 종료한다.

public class CustomerActivity extends AppCompatActivity {
    public static final int CUSTOMER_CODE_FROM_MENU = 102;
    public static final int MAIN_CODE_FROM_CUSTOMER = 112;
    public static final int MENU_CODE_FROM_CUSTOMER = 122;
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_customer);
        Toast.makeText(getApplicationContext(), "메뉴 -> 고객 분석", Toast.LENGTH_LONG).show();

        textView = findViewById(R.id.textView2);
        Intent intent = getIntent();
        getData(intent);

        Button main = findViewById(R.id.main_button);
        main.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), MenuActivity.class);
                setResult(MAIN_CODE_FROM_CUSTOMER,intent);
                finish();
            }
        });

        Button menu = findViewById(R.id.menu_button);
        menu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), MenuActivity.class);
                setResult(MENU_CODE_FROM_CUSTOMER,intent);
                finish();
            }
        });
    }

    private void getData(Intent intent){
        if(intent != null){
            Bundle bundle = intent.getExtras();
            SimpleData data = bundle.getParcelable("data");
            if(intent != null){
                textView.setText("ID : " + data.ID +"\nPW : " + data.PW);
            }
        }
    }
}

만약 메인으로 돌아간다면, 중간에 메뉴를 거쳤다가 가는데 그 이유는 최초에 startActivityForResult()로 메인 -> 메뉴였기 때문에 메뉴가 종료해야지만 onActivityResult()함수가 발동하기 때문이다. 따라서 이때 메뉴는 코드값을 그대로 set해주고 종료하는 역할만 한다.

결과
Do it 안드로이드 앱 프로그래밍 도전과제 - do it andeuloideu aeb peulogeulaeming dojeongwaje
물론 나머지 액티비티(ProductActivity, SalesActivity)도 다 잘 작동한다.

다 만들고 나서 생각했는데, 일일히 이렇게 onResult를 사용한 코드로 진행한다면 로그인에서 메뉴로 갈 때의 뾰족한 수가 떠오르지 않았다. 그냥 맘 편하게 인텐트에 이전 페이지의 정보 or 메세지를 넣는게 나을 것 같다.

전체 프로젝트 소스코드 : https://github.com/howtolivelikehuman/DoitAndroid/tree/master/DoitMission_08