프로그래밍 언어/Java

[Android java] Dialog 에서 MainActivity로 값 전달

happy_life 2021. 11. 5. 11:19

Dialog 에서 MainActivity로 값 전달  

 

Dialog 에서 MainActivity로 값을 전달 하기위해 interface를 사용하겠습니다.

 

이런식으로 Listener라는 인터페이스를 만들어 주고 changeText라는 함수를 사용할 것입니다. 

 

먼저 코드를 보여드리겠습니다. ▼

 

Dialog 코드입니다.

package com.example.myapplication;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;

import java.util.List;

public class NoticeDialog extends Dialog {
  private final String TAG = NoticeDialog.class.getSimpleName();

  private final Context mContext;
  private TextView tvContent;
  private Button btnOk, btnCancel;
  private LinearLayout layoutButtons;

  private String msg;

  // interface
  Listener listener;

  // 생성자 통해서 interface 값을 보내줌
  public NoticeDialog(Context context, String msg, Listener listener) {
    super(context);
    mContext = context;
    this.msg = msg;
    this.listener = listener;
  }


  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.dialog_notice);
    setCancelable(false);

    tvContent = (TextView) findViewById(R.id.tvContent);
    btnOk = (Button) findViewById(R.id.btnOk);
    layoutButtons = (LinearLayout) findViewById(R.id.layoutButtons);

    layoutButtons.setVisibility(View.VISIBLE);

    tvContent.setText(msg);


    // 확인 버튼
    btnOk.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        Log.d(TAG, "확인 선택");
        // interface null이 아닐 때 IResult 인터페이스로 결과 전달
        if (listener != null) {

          listener.changeText(tvContent.getText().toString());

        }
      }
    });


  }
}

 

이 부분이 바로 인터페이스를 통해 Main 으로 값을 전달해주는 부분인데요

사실 정확히 말하면 콜백을 통해 MainActivity에서 동작하도록 하는 것입니다.

 

Dialog에서 인터페이스의 메소드 (changeText) 를 호출하여 인자를 입력해주면

Main 에서 this로 받아왔던 listener가 인자를 받고 Main으로 다시 돌아가게 됩니다.

 

즉, Dialog 의 View 객체 btnOk가 클릭 될때 마다, 인터페이스인 listener의 changeText 메소드에

값을 입력받고 다시 그  값이 Main으로 콜백 되는 것입니다. 

 

단순하게 생각해서 Main에서 동작할 것을 btn에서 대신 하기 위해 콜백이라는 개념이 필요한 것입니다. 

 

 

MainActivity 코드입니다.

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;


import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity implements Listener {
    private final String TAG = MainActivity.class.getSimpleName();
    TextView hello;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

         hello = findViewById(R.id.Hello);
        // 다이얼로그 호출
        NoticeDialog dialog = new NoticeDialog(this, "Dialog값", this);
        dialog.show();

    }

    // IResult interface 구현
    @Override
    public void changeText(String str) {
        Log.d(TAG, "다이얼로그 닫힘. isOk : " + str);
        hello.setText(str);
    }
}

1)interface를 implements 했기 때문에 Oncreate 밑에 changeText를 구현해주었습니다.

2)this 를 통해 MainActivity의 Listener를 Dialog로 보내주었습니다. 

 

 

 

 

activity_main.xml 입니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <TextView

        android:layout_width="match_parent"
        android:layout_height="600dp"
        android:text=""
        />

    <TextView
        android:layout_gravity="center"
        android:id="@+id/Hello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Main에 있는 TextView"
         />

</LinearLayout>

 

dialog_notice.xml 입니다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="274dp"
            android:layout_centerInParent="true"
            android:layout_height="wrap_content"
            android:minHeight="370dp"
            android:padding="20dp">

                <TextView
                    android:gravity="center"
                    android:id="@+id/tvContent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:minHeight="144dp"
                    android:textSize="18sp"
                    android:text="1234 "
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"/>
                <LinearLayout
                    android:gravity="center"
                    android:id="@+id/layoutButtons"
                    android:layout_width="match_parent"
                    android:layout_height="40dp"
                    android:layout_marginTop="10dp">

                        <Button
                            android:id="@+id/btnOk"
                            android:layout_width="112dp"
                            android:layout_height="40dp"
                            android:text="확인"
                            android:layout_gravity="center"
                            android:layout_marginLeft="5dp"/>
                </LinearLayout>
        </LinearLayout>

</RelativeLayout>

 

간단히 요약하자면 순서는 다음과 같습니다.

 

1)Main 에 implement 된 listener 인터페이스를 다이얼로그 생성자를 통해 Dialog 로  호출해줍니다. (Main -> Dialog) 

 

2) Dialog의 생성자를 통해 Dialog에서 listener 로 동작하게 됩니다. (Dialog로 콜 된 상태) 

 

3)Dialog의 버튼을 클릭할 때 마다 인터페이스의 changeText 메소드에 인자가 들어갑니다.(Dialog로 콜 된 상태)

 

 

4)인자가 들어간 직후  Dialog에 있었던 listener 인터페이스는 다시 Main으로 콜백 됩니다. (Dialog -> Main)

 

str엔 tvContent.getText().toString() 인자가 들어간 채로 Main에서 changeText메소드가 호출됩니다.

그렇게 되면서 밑에 있는 hello.setText(str); 를 통해 Main에 있는 TextView가 바뀌는 것입니다.