Android 개발 노트 (66) 사용자 정의 대화상자

AlertDialog Android에서 가장 자주 사용하는 대화상자는 AlertDialog입니다. 알림, 확인, 선택 등 일반적인 상호작용을 완성할 수 있습니다. 그 다음에 진도 대화상자인 ProgressDialog입니다. (Android 개발 노트 (49) 비동기 작업 처리 AsyncTask 참조)
AlertDialog는 공개된 구조 함수가 없기 때문에 AlertDialog의 도움을 빌려야 한다.Builder를 사용해야 매개변수 설정을 완료할 수 있습니다.Builder의 일반적인 방법은 다음과 같습니다.
setIcon: 제목의 아이콘을 설정합니다.
setTitle: 제목의 텍스트를 설정합니다.
setCustomTitle: 사용자 정의 제목 뷰를 설정합니다.
-- 위의 방법은 제목 섹션을 설정하는 데 사용됩니다.setTitle과 setCustomTitle은 둘 중 하나만 설정할 수 있고 중복 설정은 할 수 없습니다.
setMessage: 컨텐트의 텍스트를 설정합니다.
setView: 사용자 정의 컨텐트 뷰를 설정합니다.
setAdapter: List 방식의 컨텐츠 뷰를 설정합니다.사용이 비교적 번거로워서 일반적으로 쓰지 않는다.
setItems: Spinner 방식의 컨텐츠 뷰를 설정합니다.창 표시는 대화 상자 모드의 Spinner와 매우 비슷하며, 밑에 있는 단추가 없으며, 선택하면 바로 대화 상자를 닫습니다.
setSingleChoiceItems: 라디오 목록의 내용 보기를 설정합니다.setItems와는 달리 밑에 있는 상호작용 단추가 있고, 항목마다 오른쪽에 선택 단추가 있습니다.
setMultiChoiceItems: 다중 선택 목록의 내용 보기를 설정합니다.밑에 상호작용 단추가 있고, 항목마다 오른쪽에 체크 단추가 있습니다.
-- 위의 방법은 컨텐츠 섹션을 설정하는 데 사용됩니다.이 방법들이 서로 충돌하는 것을 주의하며, 동시에 하나만 설정할 수 있다.
setPositive Button: 텍스트, 감청기 등 긍정적인 단추를 설정합니다.
setNegativeButton: 텍스트, 감청기 등 부정 단추를 설정합니다.
setNeutral Button: 텍스트, 감청기 등 중성 단추를 설정합니다.
-- 이러한 방법을 사용하여 상호 작용 버튼을 설정합니다.
Builder를 통해 매개 변수를 설정하고 create 방법을 호출해야 AlertDialog 객체를 생성할 수 있습니다.그러나 페이지에 AlertDialog를 표시하려면 이 대상의 show 방법을 호출해야 합니다.
Dialog의 실제 개발에서 AlertDialog는 개성화된 요구를 만족시키지 못한다. 예를 들어 레이아웃이 원활하지 않고 단추의 양식이 맞춤형으로 만들어지지 못하기 때문에 자주 스스로 대화상자를 사용자 정의해야 한다.AlertDialog 소스를 살펴보면 Dialog에서 상속된 소스이기 때문에 사용자 정의 대화 상자의 방향은 Dialog를 기반으로 확장하는 것입니다.다음은 Dialog의 일반적인 방법입니다.
Dialog 구조 함수: 대화상자의 테마 스타일을 정의할 수 있습니다(styles.xml에서 정의).제목이 있는지, 반투명인지, 대화상자의 배경이 있는지 등.
isshowing: 대화상자가 표시되는지 여부를 판단합니다.
show: 대화상자를 표시합니다.
hide: 대화 상자를 숨깁니다.
dismiss: 대화 상자를 닫습니다.
setCancelable: 대화상자를 취소할 수 있는지 설정합니다.
setCanceled OnTouch Outside: 대화상자 외부 영역을 클릭하고 대화상자를 자동으로 닫을지 여부입니다.기본값은 자동으로 꺼짐
getWindow: 대화상자의 인터페이스 대상을 가져옵니다.
그 중에서 getWindow 방법은 사용자 정의 대화상자의 관건이다. 먼저 대화상자가 있는 인터페이스 대상을 가져와야 이 인터페이스에 사용자 정의 보기를 추가할 수 있다.쓸데없는 말 하지 말고, 이전 사용자 정의 대화상자의 코드 예를 들어 설명하십시오.
import com.example.exmdialog.R;

import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.TextView;

public class CustomDialog implements OnClickListener {
	private final static String TAG = "CustomDialog";
	
	private Dialog dialog;
	private View view;
	private TextView tv_title;
	private TextView tv_message;
	private Button btn_ok;
	private OnCustomListener mOnCustomListener;

	public CustomDialog(Context context) {
		view = LayoutInflater.from(context).inflate(R.layout.dialog_custom, null);
		dialog = new Dialog(context, R.style.CustomDialog);
		tv_title = (TextView) view.findViewById(R.id.tv_title);
		tv_message = (TextView) view.findViewById(R.id.tv_message);
		btn_ok = (Button) view.findViewById(R.id.btn_ok);
		btn_ok.setOnClickListener(this);
	}
	
	public void setTitle(String title) {
		tv_title.setText(title);
	}

	public void setMessage(String message) {
		tv_message.setText(message);
	}

	public void setOnCustomListener(OnCustomListener listener) {
		mOnCustomListener = listener;
	}
	
	public interface OnCustomListener {
		public void onClick();
	}

	public void show() {
		dialog.getWindow().setContentView(view);
		dialog.getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
		dialog.show();
	}

	public void dismiss() {
		if (dialog != null && dialog.isShowing()) {
			dialog.dismiss();
		}
	}

	public boolean isShowing() {
		if (dialog != null) {
			return dialog.isShowing();
		} else {
			return false;
		}
	}

	@Override
	public void onClick(View v) {
		dismiss();
		if (mOnCustomListener != null) {
			mOnCustomListener.onClick();
		}
	}

}

윈도 앞에서 사용자 정의 대화상자에서 get 윈도가 인터페이스 대상인 윈도를 얻을 수 있다고 언급했는데 마침 윈도 클래스의 관련 사용법을 깊이 있게 연구해 보겠습니다.사실 Dialog뿐만 아니라 액티비티도 윈도를 기반으로 하기 때문에 윈도가 없었다면 액티비티는 핸드폰에 보기를 보여줄 수 없었을 것이다.
다음은 Window에서 자주 사용하는 몇 가지 방법입니다.
setContentView: 컨텐츠 뷰를 설정합니다.이 방법은 아주 익숙하지 않습니까?우리가 매일 교제하는Activity의 첫 번째 문장은 set Content View입니다. 내부에서 원래 윈도우의 동명 방법을 사용합니다: get 윈도우 ().setContentView
setLayout: 컨텐츠 뷰의 크기를 설정합니다.
setBackgroundDrawable: 컨텐트 뷰의 배경을 설정합니다.
getDecorView: 현재 창의 맨 윗부분 보기를 가져옵니다. 루트 보기로 이해할 수 있습니다.하나의 활용 예는 안드로이드 개발 노트(19) 밑에 있는 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭 탭
getcurrentFocus: 현재 초점이 있는 보기를 가져옵니다.
findViewById: 리소스 ID를 기준으로 뷰의 객체를 가져옵니다.이 방법은 더욱 익숙해졌다. Activity는 모두 여러 번 사용하고, Activity 원본 코드를 보아야 한다. 원래 이 방법도 윈도우의 동명 방법인 getWindow () 를 호출하는 것이다.findViewById
requestFeature: 창의 특징을 설정합니다.이것도 어디서 본 것 같은데, 여기에'안드로이드 개발 노트(20) 맨 위 내비게이션 표시줄 Action Bar'가 있는지 보세요. 원래 Activity의 Request Window Feature 방법도 Window:get Window()를 사용했어요.requestFeature
setType: 창 유형을 설정합니다.Service 팝업 대화 상자를 열려면 WindowManager로 설정해야 합니다.LayoutParams.TYPE_SYSTEM_ALERT.Service에 창이 없으므로 TYPE 와 동시에 시스템 경고를 사용하여 창을 튕길 수 있습니다.SYSTEM_ALERT 유형에는 다음과 같은 권한이 추가됩니다.
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

ios를 모방한 롤러 대화상자 사용자 정의 대화상자는 많은 말문이 막혔으니, 이제는 제대로 된 응용을 말해 보자.아이폰을 해 본 사람들은 모두 알다시피 애플 휴대전화에 롤러 컨트롤러가 매우 멋있다. 안드로이드의 딱딱한 스핀너나 Alert Dialog보다 훨씬 자랑스럽다.그러나 이 롤러 컨트롤러는 본고의 중점이 아니라 소스 코드를 이용하여 롤러를 실현할 수 있다. 여기서 해야 할 일은 페이지 밑에 대화상자를 팝업하고 중간에 롤러를 삽입하여 롤러를 통해 구체적인 항목을 선택하여 스핀너가 선택한 것과 비슷한 기능을 완성하는 것이다.
롤러의 소스 코드는github에서 찾을 수 있습니다. 패키지 이름은 "kankan.wheel.widget"이고, 사용 방법은 Spinner와 유사하며, 선택할 수 있는 문자열 그룹과 선택한 감청기를 설정해야 합니다.이어서 다이아로그 레이아웃 파일을 정의합니다. 왼쪽 상단에 취소 단추를 놓고, 오른쪽 상단에 확인 단추를 놓고, 중간에 롤러 컨트롤을 놓습니다.그리고 두 단추의 클릭 이벤트, 롤러의 선택 이벤트와 같은 이벤트 감청기를 등록합니다.마지막으로 제목, 현재 위치, 문자 크기, 문자 색상 등을 포함한 매개 변수 설정이 있습니다.
다음은 스크롤 휠 컨트롤의 몇 가지 기본값을 기록하여 나중에 수정을 사용자 정의할 수 있도록 합니다.
1. 휠의 기본 배경, 코드는 WheelView.java의 SHADOWSCOLORS
2. 문자의 기본 크기와 색깔, 코드는AbstractWheelTextAdapter.java의 DEFAULTTEXT_SIZE 및 DEFAULTTEXT_COLOR
다음은 스크롤 휠 대화 상자의 코드 예입니다.
import com.example.exmdialog.R;

import android.app.Dialog;
import android.content.Context;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.TextView;
import kankan.wheel.widget.OnWheelChangedListener;
import kankan.wheel.widget.WheelView;
import kankan.wheel.widget.adapters.ArrayWheelAdapter;

/**
 *        
 */
public class WheelDialog implements OnWheelChangedListener, OnClickListener {

	private Dialog dialog;
	private View view;
	private Context mContext;
	private WheelView id_relation;
	private ArrayWheelAdapter<String> arrayWheelAdapter;
	private String[] relation;
	private String[] value;

	private TextView tv_cancel;
	private TextView tv_sure;
	private TextView wheelTitle;
	private int pCurrent = 0;

	public WheelDialog(Context context) {
		mContext = context;
		view = LayoutInflater.from(context).inflate(R.layout.dialog_wheel, null);
		dialog = new Dialog(context, R.style.WheelDialog);

		Window dialogWindow = dialog.getWindow();
		dialogWindow.setGravity(Gravity.BOTTOM);

		relation = context.getResources().getStringArray(R.array.relation_name);
		value = context.getResources().getStringArray(R.array.relation_value);

		tv_cancel = (TextView) view.findViewById(R.id.tv_cancel);
		tv_sure = (TextView) view.findViewById(R.id.tv_sure);
		wheelTitle = (TextView) view.findViewById(R.id.wheelTitle);
		id_relation = (WheelView) view.findViewById(R.id.id_relation);

		arrayWheelAdapter = new ArrayWheelAdapter<String>(context, relation);
		id_relation.setViewAdapter(arrayWheelAdapter);
		id_relation.addChangingListener(this);

		tv_cancel.setOnClickListener(this);
		tv_sure.setOnClickListener(this);
	}

	public void show() {
		dialog.getWindow().setContentView(view);
		dialog.getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
		dialog.show();
	}

	public void dismiss() {
		if (dialog != null && dialog.isShowing()) {
			dialog.dismiss();
		}
	}

	public boolean isShowing() {
		if (dialog != null)
			return dialog.isShowing();
		return false;
	}

	public void setCancelable(boolean flag) {
		dialog.setCancelable(flag);
	}

	public void setCancelableOnTouchOutside(boolean flag) {
		dialog.setCanceledOnTouchOutside(flag);
	}

	@Override
	public void onChanged(WheelView wheel, int oldValue, int newValue) {
		if (wheel == id_relation) {
			pCurrent = id_relation.getCurrentItem();
		}
	}

	private OnWheelChangeListener onWheelChangeListener;

	public void setOnWheelChangeListener(OnWheelChangeListener onWheelChangeListener) {
		this.onWheelChangeListener = onWheelChangeListener;
	}

	public interface OnWheelChangeListener {
		public void ScollChange(String nickname, String nickvalue);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.tv_cancel:
			dismiss();
			break;
		case R.id.tv_sure:
			if (onWheelChangeListener != null) {
				onWheelChangeListener.ScollChange(relation[pCurrent], value[pCurrent]);
			}
			dismiss();
			break;
		default:
			break;
		}
	}

	public void setNewWheelData(String[] relation, String[] value) {
		this.relation = relation;
		this.value = value;
		arrayWheelAdapter = new ArrayWheelAdapter<String>(mContext, relation);
		id_relation.setViewAdapter(arrayWheelAdapter);
	}

	public void setWheelTitle(String title) {
		wheelTitle.setText(title);
	}

	public void setCurrentItem(int index) {
		id_relation.setCurrentItem(index);
	}

	public void setTextSize(int size) {
		arrayWheelAdapter.setTextSize(size);
	}

	public void setTextColor(int color) {
		arrayWheelAdapter.setTextColor(color);
	}
	
}

코드 예시 다음은 각종 대화상자의 코드 예시이다. 예를 들어 간단한 AlertDialog, 유사한Spinner 대화상자, 단일 선택 대화상자, 다중 선택 대화상자, 사용자 정의 대화상자, 롤러 대화상자 등이다.
import com.example.exmdialog.dialog.CustomDialog;
import com.example.exmdialog.dialog.CustomDialog.OnCustomListener;
import com.example.exmdialog.dialog.WheelDialog;
import com.example.exmdialog.dialog.WheelDialog.OnWheelChangeListener;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

	private Button btn_wheel;
	private String[] mTypeArray = {"0", "1", "2", "3", "4", "5", "6", "7"}; 
	private String[] mEatArray = {"    ", "   ", "    ", 
			"   ", "    ", "    ", "    ", "    "}; 
	private boolean[] mCheckedArray = {true, false, false, 
			false, false, false, true, false};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Button btn_alert = (Button) findViewById(R.id.btn_alert);
		Button btn_alert_spinner = (Button) findViewById(R.id.btn_alert_spinner);
		Button btn_alert_single = (Button) findViewById(R.id.btn_alert_single);
		Button btn_alert_multi = (Button) findViewById(R.id.btn_alert_multi);
		Button btn_custom = (Button) findViewById(R.id.btn_custom);
		btn_wheel = (Button) findViewById(R.id.btn_wheel);
		btn_alert.setOnClickListener(this);
		btn_alert_spinner.setOnClickListener(this);
		btn_alert_single.setOnClickListener(this);
		btn_alert_multi.setOnClickListener(this);
		btn_custom.setOnClickListener(this);
		btn_wheel.setOnClickListener(this);
		initWheelDialog();
	}

	private int mPosition = 0;
	private WheelDialog mWheelDialog;
	private void initWheelDialog() {
		mWheelDialog = new WheelDialog(this);
		mWheelDialog.setWheelTitle("     ?");
		mWheelDialog.setOnWheelChangeListener(new OnWheelChangeListener() {
			public void ScollChange(String nickname, String nickvalue) {
				mPosition = Integer.parseInt(nickvalue);
				btn_wheel.setText(mEatArray[mPosition]);
				showToast("     :"+nickname+"|"+nickvalue);
			}
		});
	}
	
	private void showToast(String hint) {
		Toast.makeText(MainActivity.this, hint, Toast.LENGTH_LONG).show();
	}
	
	private void showAlert() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("       ");
		builder.setMessage("        ");
		builder.setPositiveButton("  ", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				showToast("  ,        ");
			}
		});
		builder.setNegativeButton("  ", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				showToast("   ,        ");
			}
		});
		builder.setNeutralButton("  ", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				showToast(" ,     ,     ");
			}
		});
		AlertDialog alert = builder.create();
		alert.show();
	}
	
	private void showAlertSpinner() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("     ");
		builder.setItems(mEatArray, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				showToast("     "+mEatArray[which]);
			}
		});
		builder.create().show();
	}

	private int mSingleChoice = 1;
	private void showAlertSingle() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("       ");
		builder.setPositiveButton("  ", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				showToast("       "+mEatArray[mSingleChoice]);
			}
		});
		builder.setSingleChoiceItems(mEatArray, mSingleChoice, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				mSingleChoice = which;
				showToast("     "+mEatArray[which]);
			}
		});
		builder.create().show();
	}

	private void showAlertMulti() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("       ");
		builder.setPositiveButton("  ", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				String meals = "";
				String meal = "";
				for (int i=0; i<mCheckedArray.length; i++) {
					if (mCheckedArray[i] == true) {
						if (meals.length() > 0) {
							meal = "、" + mEatArray[i];
						} else {
							meal = mEatArray[i];
						}
						meals = meals + meal;
					}
				}
				showToast("       :"+meals);
			}
		});
		builder.setMultiChoiceItems(mEatArray, mCheckedArray, new DialogInterface.OnMultiChoiceClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which, boolean isChecked) {
				mCheckedArray[which] = isChecked;
				showToast("  "+(isChecked?"  ":"  ")+mEatArray[which]);
			}
		});
		builder.create().show();
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.btn_alert) {
			showAlert();
		} else if (v.getId() == R.id.btn_alert_spinner) {
			showAlertSpinner();
		} else if (v.getId() == R.id.btn_alert_single) {
			showAlertSingle();
		} else if (v.getId() == R.id.btn_alert_multi) {
			showAlertMulti();
		} else if (v.getId() == R.id.btn_custom) {
			CustomDialog custom = new CustomDialog(this);
			custom.setTitle("    ");
			custom.setMessage("      ");
			custom.setOnCustomListener(new OnCustomListener() {
				@Override
				public void onClick() {
					showToast("               ");
				}
			});
			custom.show();
		} else if (v.getId() == R.id.btn_wheel) {
			mWheelDialog.setNewWheelData(mEatArray, mTypeArray);
			mWheelDialog.setCurrentItem(mPosition);
			mWheelDialog.setTextSize(20);
			mWheelDialog.setTextColor(0xff1144aa);
			mWheelDialog.show();
		}
	}

}

안드로이드 개발 노트의 전체 디렉터리를 보려면 누르십시오

좋은 웹페이지 즐겨찾기