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가 바뀌는 것입니다.
'프로그래밍 언어 > Java' 카테고리의 다른 글
java 6강 상속이란? (0) | 2021.11.07 |
---|---|
Android title 바 없앨 때 xml 전체 변경 오류 해결 방법 (0) | 2021.11.06 |
Android MPAndroidChart gradle 에러 (0) | 2021.11.05 |
[Android] Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by build file 'app\build.gradle' 오류 해결 (0) | 2021.11.04 |
java 5강 생성자란? (0) | 2021.11.03 |