DialogFragment 운행 원리 및 사용 방법 상세 설명

사유 지도

1.왜 DialogFragment 를 배 워 야 합 니까?
아직도 Dialog 쓰 세 요?당신 은 아직도 화면 이 뒤 집 힐 때,Dialog 의 각종 기이 한 상황 에 대해 자주 고민 하고 있 습 니까?결합 을 낮 추고 싶 습 니까?만약 당신 이 그 중의 한 가지 고민 이 있다 면,축하합니다.DialogFragment 를 만 났 습 니 다.그 는 마침 위 에서 말 한 문 제 를 해결 하 였 습 니 다.관심 이 있다 면 수필 자 를 만 나 보 세 요!
배경
Android 공식 에 서 는 Dialog 대신 DialogFragment 를 사용 하 는 것 을 추천 합 니 다.더 높 은 재 활용 성(결합 감소)과 더 좋 은 편의 성(화면 반전 을 잘 처리 하 는 경우)을 가 질 수 있 습 니 다.DialogFragment 를 만 드 는 방법 은 두 가지 가 있 습 니 다.
"법 1:onCreate Dialog 를 덮어 쓰 는 방법"
일반적으로 전통 적 인 Dialog 대화 상 자 를 대체 하 는 장면 을 만 드 는 데 사 용 됩 니 다.UI 는 간단 하고 기능 이 단일 하 며 다 중 스 레 드(예:네트워크 요청)를 사용 한 경우 에는 적용 되 지 않 습 니 다.(현재 Fragment 의 상 태 를 정확하게 가 져 올 수 없 기 때문에 빈 포인터 이상 이 발생 합 니 다)
"법 2:onCreateView 방법 을 복사 합 니 다."
일반적으로 복잡 한 콘 텐 츠 창 이나 전체 화면 전시 효 과 를 만 드 는 장면,UI 가 복잡 하고 기능 이 복잡 하 며 네트워크 요청 등 비동기 작업 이 있 습 니 다.
응용
3.1 기본 용법 은 무엇 입 니까
법 1:
a.간단 한 Dialog 를 만 들 고 되 돌려 주면 됩 니 다.

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
  AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
  //          
  // AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.CustomDialog);
  builder.setTitle("  :")
      .setMessage("      ?")
      .setPositiveButton("  ", null)
      .setNegativeButton("  ", null)
      .setCancelable(false);
      //builder.show(); //         show()   
  return builder.create();
}

b.사용자 정의 View 를 사용 하여 만 들 수 있 습 니 다.

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
  AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
  //          
  // AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.CustomDialog);
  LayoutInflater inflater = getActivity().getLayoutInflater(); 
  View view = inflater.inflate(R.layout.fragment_dialog, null); 
  builder.setView(view) 
  // Do Someting,eg: TextView tv = view.findViewById(R.id.tv);
  return builder.create();
}

PS:Dialog 를 만 드 는 방식 은 여러 가지 가 있 습 니 다.예 를 들 어 아래 와 같이 사용 할 때 약간 차이 가 있 으 므 로 주의해 야 합 니 다.

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
  LayoutInflater inflater = getActivity().getLayoutInflater();
  View view = inflater.inflate(R.layout.fragment_dialog, null);
  Dialog dialog = new Dialog(getActivity());
  //          
  // Dialog dialog = new Dialog(getActivity(), R.style.CustomDialog);
  dialog.setContentView(view);
  // Do Someting
  return dialog;
}

이 경우 제목 내용 위의 흰색 부분 은 기본 제목 표시 줄 입 니 다.필요 하 다 면 숨겨 진 제목 표시 줄 을 설정 할 수 있 습 니 다.
3.2 화면 뒤 집기 처리 방법
전통 적 인 Dialog 를 사용 하려 면 화면 이 뒤 집 히 는 상황 을 수 동 으로 처리 해 야 하지만 DialogFragment 를 사용 하면 처리 할 필요 가 없습니다.Fragment Manager 는 DialogFragment 의 수명 주 기 를 자동 으로 관리 합 니 다.
3.3 제목 표시 줄 을 숨 기 는 방법
기본 적 인 용법 에서 코드 주석 은 테 마 를 설정 하 는 곳 이 있 습 니 다.다음은 두 가지 방법 에서 제목 없 는 표시 줄 을 설정 하 는 방식 입 니 다.법 1:

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
  LayoutInflater inflater = Objects.requireNonNull(getActivity()).getLayoutInflater();
  @SuppressLint("InflateParams") View view = inflater.inflate(R.layout.fragment_i_o_s_dialog, null);
  Dialog dialog = new Dialog(getActivity());
  //      ,setContentView()     
  dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
  dialog.setContentView(view);
  dialog.setCanceledOnTouchOutside(true);
  return dialog;
}
법 2:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setStyle(DialogFragment.STYLE_NO_TITLE, 0);
}
3.4 전체 화면 을 어떻게 실현 하 는가
자주 사용 하 는 형식 은 대부분 너비 가 화면 과 같이 넓 고 높이 가 적응 되 며 아래 는 코드 를 직접 봅 니 다.
법 1:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
  LayoutInflater inflater = getActivity().getLayoutInflater();
  View view = inflater.inflate(R.layout.fragment_dialog, null);
  Dialog dialog = new Dialog(getActivity(), 0);
  dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
  dialog.setContentView(view);
  dialog.setCanceledOnTouchOutside(true);
  //Do something
  //        、        
  Window window = dialog.getWindow();
  //            ,       
  // <color name="transparent">#50000000</color>
  window.setBackgroundDrawableResource(R.color.transparent);
  WindowManager.LayoutParams wlp = window.getAttributes();
  wlp.gravity = Gravity.BOTTOM;
  //         MATCH_PARENT,           
  wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
  wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
  window.setAttributes(wlp);
  return dialog;
}
법 2:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setStyle(DialogFragment.STYLE_NO_TITLE, 0);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    getDialog().setCanceledOnTouchOutside(true);
    View rootView = inflater.inflate(R.layout.fragment_dialog, container, false);
    //Do something
    //        、      。
    final Window window = getDialog().getWindow();
   //      
    window.setBackgroundDrawableResource(R.color.transparent);
   //  ,   padding,        ,             
    window.getDecorView().setPadding(0, 0, 0, 0);
    WindowManager.LayoutParams wlp = window.getAttributes();
    wlp.gravity = Gravity.BOTTOM;
    wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
    wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
    window.setAttributes(wlp);
    return rootView;
}
3.5 응용 장면 의 차 이 는 무엇 입 니까?
글 은 처음에 법 1 과 법 2 의 응용 장면 을 간단하게 정리 했다.여기 서 설명 한다.
법 1:Dialog 를 간단하게 대체 하기 위해 매우 편리 한 생 성 방식 을 제공 합 니 다.그러나 다 중 스 레 드(예 를 들 어 네트워크 요청)를 사용 한 상황 에서 현재 Fragment 의 상 태 를 정확하게 가 져 오지 못 하면 빈 포인터 이상 법 이 발생 합 니 다.2:위의 빈 포인터 와 같은 문제 가 없습니다.그리고 그 생 성 방식 은 기본적으로 사용자 정의 View 를 사용 하여 복잡 한 UI 장면 에 더욱 쉽게 대응 할 수 있 습 니 다.
3.6 Activity 와 어떻게 상호작용 을 합 니까?
리 셋 방식 을 사용 하 다
a.DialogFragment 에서:

public interface OnDialogListener {
  void onDialogClick(String person);
}

private OnDialogListener mlistener;

public void setOnDialogListener(OnDialogListener dialogListener){
  this.mlistener = dialogListener;
}
DialogFragment 의 클릭 이벤트 중:

public OnDialogListener mlistener;
@Override
public void onClick(View view) {
  switch (view.getId()) {
    case R.id.tv1:
      mlistener.onDialogClick("1");
      dismiss();
      break; 
    case R.id.tv2:
      mlistener.onDialogClick("2");
      dismiss();
      break;
    case R.id.tv3:
      mlistener.onDialogClick("3");
      dismiss();
      break;
    case R.id.tv4:
      mlistener.onDialogClick("4");
      dismiss();
      break;
  }
}
b.Activity 에서

dialogFragment.setOnDialogListener(new PersonDialogFragment.OnDialogListener() {
  @Override
  public void onDialogClick(String person) {
    ToastUtil.showToast(person);
  }
});
3.7 애니메이션 과 결합 하여 a.아래 에서 위로 팝 업 되 는 애니메이션 을 설정 하 는 방법

private void slideToUp(View view) {
  Animation slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0);
  slide.setDuration(400);
  slide.setFillEnabled(true);
  slide.setFillAfter(true);
  view.startAnimation(slide);
}
b.위 에서 아래로 팝 업 되 는 애니메이션 설정

private boolean isAnimation = false;//          。      

public void slideToDown(View view) {
  Animation slide = new TranslateAnimation(
      Animation.RELATIVE_TO_SELF, 0.0f,
      Animation.RELATIVE_TO_SELF, 0.0f, 
      Animation.RELATIVE_TO_SELF, 0.0f,
      Animation.RELATIVE_TO_SELF, 1.0f);
  slide.setDuration(400);
  slide.setFillEnabled(true);
  slide.setFillAfter(true);
  view.startAnimation(slide);
  slide.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {
    }

    @Override
    public void onAnimationEnd(Animation animation) {
      //          。      
      isAnimation = false;
      //    
      IOSDialogFragment.this.dismiss();
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
    }
  });
}
c.위 에서 아래로 팝 업 된 애니메이션 을 봉인 합 니 다.
여러 번 클릭 했 는 지 판단 하 는 것 까지.여러 번 의 집행 을 방지 하 다

private void dialogFinish() {
  if (isAnimation) {
    return;
  }
  isAnimation = true;
  slideToDown(rootView);
}
3.8 Activity 에서 어떻게 DialogFragment 를 팝 업 합 니까?

mBtn.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
    IOSDialogFragment fragment = new IOSDialogFragment();
    //       tag
    fragment.show(getSupportFragmentManager(), "android");
  }
});
3.9 공백 을 클릭 할 때 닫 을 때 애니메이션 도 사용 할 수 있 습 니까?
DecorView 에 onTouchListener 를 직접 설정 합 니 다.

window.getDecorView().setOnTouchListener(new View.OnTouchListener() {
  public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_UP) {
      //             
      ....
      ....
    
    }
    return true;
  }
});
결어
드디어 오리!피곤 해 죽 겠 어!또 잘 모 르 는 것 이 있다 면 필자 가 쓴 예제 Demo 를 살 펴 볼 수 있다.
https://github.com/LoveLifeEveryday/TestDialogFragment
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기