보통의 경우는 안드로이드에서 주어지는 AlertDialog나 xml로 필요한 뷰를 만들고 인플레이트한뒤 뷰에서 해당 innerView 들을 찾아서 사용하곤 했었는데 어느순간 불편한 부분도 있었고, keyboard 같은 것들이 마음대로 움직이지 않아서 하드코딩해야 하는 부분이 많았다.
불편해서 어느 순간부터 커스텀 다이얼 로그를 만들어 사용하고 있는데 꽤나 편리한거 같아
다른 분들과 공유하고싶다! (물론 잘 만들어진 머터리얼 다이얼로그 사용하는게 제일 좋긴하다...하지만 직접 만들어 사용한다는 것에 의의를 두자....) 매우 허접함으로 꼭! 안드로이드를 처음 접하는 분들이 보셨으면 좋겠다.
여기서 만들어 볼려하는 커스텀 다이얼 로그는 아주 간단하게 텍스트를 입력 받아 추가 시켜주는 기능이다.
[디자인은 보지말자]
그렇다면 바로 고고씽!
일단은 xml 로 원하는 화면을 만든다.
팁이 있다면,
<android.support.v7.widget.AppCompatEditText
android:textSize="@dimen/font_50"
tools:text="@string/dialog_todo_edit_contents"
android:id="@+id/dialog_todo_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
tools:text를 사용하면 앱을 릴리즈 할시 보이지 않아 테스트 하기 수월하다.
또한 리싸이클러뷰 등에 mock 데이터도 넣을수 있고 활용 방법이 매우매우 많다.
나중에는 tools에 대해서도 포스팅 하려한다.
레이아웃을 완성했으면 자바 코드로 넘어 갈 차례이다.
Dialog를 상속받은 TodoDialog를 만들고 필요한 생성자를 추가 하였다. 또한 필요한 뷰들을 선언하고 버터나이프를 통해 이어주었다.
public class TodoDialog extends Dialog {
@BindView(R.id.dialog_todo_edit) AppCompatEditText todoEditText;
@BindView(R.id.dialog_todo_cancel_btn) AppCompatTextView cancleBtn;
@BindView(R.id.dialog_todo_done_btn) AppCompatTextView doneBtn;
private Context context;
public TodoDialog(@NonNull Context context) {
super(context);
this.context = context;
requestWindowFeature(Window.FEATURE_NO_TITLE);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_todo);
ButterKnife.bind(this);
}
}
또한 EditText의 글자 수를 비교하여 추가 버튼의 색을 변화 시켜주는 함수를 추가 해주었다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_todo);
ButterKnife.bind(this);
checkBlanck();
}
RxBinding을 사용하여, EditText의 글자 수가 0 보다 클 경우는 map을 통해 true 값을 주어 파란색 색을 지정해주었고 나머지 경우는 false 값을 주어 회색 색이 나오게 하였다.
private void checkBlanck() {
Observable<CharSequence> observable1 = RxTextView.textChanges(todoEditText);
observable1.map(charSequence -> charSequence.length() > 0).subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Boolean aBoolean) {
if(aBoolean){
doneBtn.setTextColor(context.getResources().getColor(R.color.point_5FA9D0));
} else {
doneBtn.setTextColor(context.getResources().getColor(R.color.dialog_todo_font_color));
}
}
});
}
추가와 취소 이벤트를 위한 인터페이스를 이너클래스로 선언해주었다.
public interface TodoListener {
void addTodoList(String contents);
void onCancel();
}
필드에
private TodoListener todoListener;
도 추가했고, 리스너 setter도 만들었다.
public void setTodoListener(TodoListener todoListener){
this.todoListener = todoListener;
}
마지막으로 추가와 취소 버튼에 대한 온클릭메소드를 구현하였다,
@OnClick(R.id.dialog_todo_done_btn)
public void doneOnClick() {
String contents = todoEditText.getText().toString();
if (TextUtils.isEmpty(contents)) {
Toast.makeText(context, context.getString(R.string.dialog_todo_content), Toast.LENGTH_SHORT).show();
return;
} else {
todoListener.addTodoList(contents);
dismiss();
}
}
@OnClick(R.id.dialog_todo_cancel_btn)
public void cancleOnClick(){
if (todoListener != null) {
todoListener.onCancel();
}
cancel();
}
비로소 끝이 났다.
여기서 중요한 것이 커스텀 다이얼로그를 사용했을때, 키보드를 올려주고 내려주는 헬퍼가 필요하다.
그래서 헬퍼를 구현해보았다. (아는 분이 짜주신 코드를 인용하였다!)
public class KeyboardHelper {
/**
* 올리기
* @param act
*/
public static void show(Activity act){
View view = act.getCurrentFocus();
if (view == null) view = new View(act);
InputMethodManager imm = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.showSoftInputFromInputMethod(view.getWindowToken(), 0);
}
/**
* 내리기
* @param act
*/
public static void hide(Activity act){
View view = act.getCurrentFocus();
if (view == null) view = new View(act);
InputMethodManager imm = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
public static void show(EditText et) {
InputMethodManager imm = (InputMethodManager) et.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.showSoftInput(et, 0);
}
public static void hide(EditText et) {
InputMethodManager imm = (InputMethodManager) et.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(et.getWindowToken(), 0);
}
public static void show(SearchView sv) {
InputMethodManager imm = (InputMethodManager) sv.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.showSoftInput(sv, 0);
}
public static void hide(SearchView sv) {
InputMethodManager imm = (InputMethodManager) sv.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(sv.getWindowToken(), 0);
}
public static void show(Dialog dialog) {
if(dialog != null) dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
}
이제 정말 끝이 났다 원하는 곳에서 사용해주기만 하면 된다.
TodoDialog dialog = new TodoDialog(PlanActivity.this);
KeyboardHelper.show(dialog);
dialog.show();
dialog.setTodoListener(new TodoDialog.TodoListener() {
@Override
public void addTodoList(String contents) {
//Todo send to server
}
@Override
public void onCancel() {
}
});
가끔식 하는 안드로이드는 참 재미있다. (서버로 보내는 코드는 첨부하지 않았다. 깃헙에서 볼수있다.)
끝!
'Android' 카테고리의 다른 글
Grab, Kakao T 같은 모빌리티 샘플 앱 구현하기 (0) | 2020.06.29 |
---|---|
안드로이드 Q (API 29) 관련 파일 저장 퍼미션 문제 (0) | 2019.11.17 |
인텐트 및 인텐트 필터에 대해 알아보자. (0) | 2017.05.06 |
Apk는 어떻게 만들어지는 걸까? (0) | 2017.05.04 |
초보 개발자의 아주 간단한 커스텀 뷰 개발기 (0) | 2017.05.01 |