developer tip

Android 팝업 창 닫기

optionbox 2020. 11. 29. 10:13
반응형

Android 팝업 창 닫기


내 목록 활동에서 항목을 클릭하면 팝업 창이 표시됩니다. 문제는 뒤로 키가 닫히지 않는다는 것입니다. 내 목록 활동에서 뒤로 키를 잡으려고 시도했지만 등록하지 않았습니다. 그런 다음 팝업 창에 전달하는 뷰에 onkeylistener를 등록하려고했습니다. 이렇게 :

pop.setOnKeyListener(new View.OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // TODO Auto-generated method stub
            boolean res=false;
            if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
                // do something on back.
                Log.e("keydown","back");
                if (pw.isShowing()) {
                    Log.e("keydown","pw showing");
                    pw.dismiss();
                    res = true;
                }
            } else {
                res = false;
            }
            return res;
        }
    });

다음과 같은 팝업에 전달됩니다.

pw = new PopupWindow(
       pop, 
       240, 
       70, 
       true);

그러나 그 청취자는 어느 쪽도 발사하지 않습니다. 도와주세요? 나는 아이디어가 없다 :)


이는 팝업 창이! = null 인 배경이없는 한 onTouch 또는 onKey 이벤트에 응답하지 않기 때문입니다. 이것을 돕기 위해 내가 작성한 코드를 확인하십시오 . 기본적인 경우에는 호출 PopupWindow#setBackgroundDrawable(new BitmapDrawable())하여 예상대로 작동하도록 할 수 있습니다. 고유 한 onKey 리스너가 필요하지 않습니다. 사용자가 PopupWindow#setOutsideTouchable(true)창 경계 외부를 클릭 할 때 사라지도록 하려면 전화를해야 할 수도 있습니다 .

확장 된 난해한 대답 :

배경이 null이 될 수없는 이유는 PopupWindow#preparePopup. 감지 background != null하면 인스턴스를 생성하고이를 PopupViewContainer호출 setBackgroundDrawable하고 콘텐츠보기를 그 안에 넣습니다. PopupViewContainer기본적으로 FrameLayout터치 이벤트와 KeyEvent.KEYCODE_BACK창을 닫는 이벤트를 수신 하는 입니다 . background == null이면 해당 작업을 수행하지 않고 콘텐츠보기 만 사용합니다. PopupWindow이를 처리하는 것에 대한 대안으로 루트 ViewGroup확장하여 원하는 방식으로 동작 할 수 있습니다.


다음과 같이 잘 작동합니다.

PopupWindow pw;
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)findViewById(R.id.linlay_weight_popup));
pw = new PopupWindow(layout,LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT, true);
pw.setBackgroundDrawable(new BitmapDrawable());
pw.setOutsideTouchable(true);
pw.showAsDropDown(btnSelectWeight);

새 프로젝트의 경우 사용하는 것이 좋습니다.

popupWindow.setBackgroundDrawable(new ColorDrawable());

대신에

popupWindow.setBackgroundDrawable(new BitmapDrawable());

BitmapDrawable은 더 이상 사용되지 않습니다. 또한이 경우 ShapeDrawable보다 낫습니다. PopupWindow가 모서리가 둥근 사각형 일 때 ShapeDrawable이 모서리를 검정색으로 채 웁니다.


정말 간단한 해결책은 pw.setFocusable (true)를 작성하는 것이지만 MapActivity가 터치 이벤트를 처리하지 않기 때문에이 작업을 원하지 않을 것입니다.

더 나은 해결책은 다음과 같이 뒤로 키를 재정의하는 것입니다.

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

    // Override back button
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        if (pw.isShowing()) {
            pw.dismiss();
            return false;
        }
    }
    return super.onKeyDown(keyCode, event);
} 

행운을 빕니다!


새로운 검색 자의 경우를 만들 new BitmapDrawable수 없으므로 지금 ( The constructor BitmapDrawable() is deprecated)으로 변경해야하므로 다음 new ShapeDrawable()과 같이 변경해야합니다 .

pw.setBackgroundDrawable(new BitmapDrawable());

받는 사람 :

pw.setBackgroundDrawable(new ShapeDrawable());

그리고 전체 작업은 다음과 같습니다.

PopupWindow pw;
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)findViewById(R.id.linlay_weight_popup));
pw = new PopupWindow(layout,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT, true);
pw.setOutsideTouchable(true);
pw.setBackgroundDrawable(new ShapeDrawable());
pw.setTouchInterceptor(new OnTouchListener() { // or whatever you want
        @Override
        public boolean onTouch(View v, MotionEvent event)
        {
            if(event.getAction() == MotionEvent.ACTION_OUTSIDE) // here I want to close the pw when clicking outside it but at all this is just an example of how it works and you can implement the onTouch() or the onKey() you want
            {
               pw.dismiss();
               return true;
            }
            return false;
        }

});
pw.showAtLocation(layout, Gravity.CENTER, 0, 0);

그냥 사용하세요

mPopupWindow.setBackgroundDrawable(new BitmapDrawable(null,""));

더 이상 사용되지 않습니다. 화면을 다시 그려야 할 때 모양을 그리려고 할 때 천천히 렌더링되므로 new ShapeDrawable ()을 피할 것입니다.


나는 이것이 당신에게 도움이되기를 바랍니다.

 pw.setTouchInterceptor(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                pw.dismiss();
            }
            return true;
        }
    });

당신 setBackgroundDrawable(new BitmapDrawable())은 당신의 PopupWindow.


    private void initPopupWindow() {  
    // TODO Auto-generated method stub  

    View view = getLayoutInflater().inflate(R.layout.main_choice, null);  

    ListView main_menu_listview = (ListView) view.findViewById(R.id.main_menu_listview);  

    ShowMainChoice madapter = new ShowMainChoice(context);
    main_menu_listview.setAdapter(madapter);

    int width = (int)getWindowManager().getDefaultDisplay().getWidth()/2;
    popupWindow = new PopupWindow(view, width,WindowManager.LayoutParams.WRAP_CONTENT);  
    popupWindow.setBackgroundDrawable(new BitmapDrawable());//this is important,如果缺少这句将导致其他任何控件及监听都得不到响应
    popupWindow.setOutsideTouchable(true);
    popupWindow.setFocusable(true);

    main_menu_listview.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
            // TODO Auto-generated method stub

            Log.e("++++++>", arg2+"");

        }
    });
}

이 문제는 popupwindow입니다. 행운을 빌어 요.


pw.setBackgroundDrawable(new ColorDrawable());  

setContentView 전에 작성해야합니다.

이것은 나를 위해 작동합니다.

참고URL : https://stackoverflow.com/questions/3121232/android-popup-window-dismissal

반응형