2012-05-02 11 views
10

に触れた後、PopupWindowの解雇の回避:私は以下の動作/機能をPopupWindowを使用したいの外

  • それがフォーカス可能である(例えば内部のインタラクティブなコントロールをしているボタン。)
  • ビューはpopupwindow「下」しました
  • 適切にポップアップ外のタッチを消費..しかしpopupwindowは私がPopupWindoに関する記事の束を見つけたとしても外​​

クリックした後、画面に滞在していしますどのようにそのような状況に対処するのか質問していません。

私はsetOutsideTouchable()、setFocusable()、setTouchable()のすべての可能な組み合わせを試してみましたが、私は立ち往生しています。ポップアップは適切なクリックを処理しますが、外に触れるときは常に破棄されます。

私の現在のコードは次のとおりです。

View.OnTouchListener customPopUpTouchListenr = new View.OnTouchListener(){ 

    @Override 
    public boolean onTouch(View arg0, MotionEvent arg1) { 
     Log.d("POPUP", "Touch false"); 
     return false; 
    } 

}; 


LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
LinearLayout layout= (LinearLayout)inflater.inflate(R.layout.insert_point_dialog, null); 
PopupWindow pw = new PopupWindow(layout,400,200,true); 
pw.setOutsideTouchable(true); 
pw.setTouchable(true); 
pw.setBackgroundDrawable(new BitmapDrawable()); 
pw.setTouchInterceptor(customPopUpTouchListenr); 
pw.showAtLocation(frameLayout, Gravity.BOTTOM, 0, 0); 

私の一般的な目標は、GIMPのようなソフトウェアの「ツールパレット」のように振る舞うフローティングウィンドウを作成することです:によって閉じられるまで上にとどまり、内部のいくつかのコントロールを持っています'X'ボタンを押して、その下にあるコントロールと対話することができます。 PopupWindowではなく、これを行うにはもっと良い方法がありますか?しかし、私はまだより適切なコントロールを見つけていません。

答えて

2

pw.setOutsideTouchable(false);

+2

これは機能しません(外部をクリックしてから、オンタッチに入るとポップアップが消えます)。ここで述べたように:[link](http://stackoverflow.com/questions/7271784/open-a-popupwindow-and-let-the-outsides-still-touchable)フォーカス可能なポップアップはsetOutsideTouchableの設定を無視します。 –

6

だけpw.setBackgroundDrawable(new BitmapDrawable());

2

pw.setBackgroundDrawable(null)を試してみてくださいを削除します。

7

それは手遅れになるが、このようなもの グーグルの人がちょうど

pw.setOutsideTouchable(true); 
pw.setTouchable(true); 
pw.setBackgroundDrawable(new BitmapDrawable()); 
pw.setTouchInterceptor(customPopUpTouchListenr); 
pw.showAtLocation(frameLayout, Gravity.BOTTOM, 0, 0); 

がshowatlocationメソッドの後に何を置くの

pw.showAtLocation(frameLayout, Gravity.BOTTOM, 0, 0); 
pw.setOutsideTouchable(true); 
pw.setTouchable(true); 
pw.setBackgroundDrawable(new BitmapDrawable()); 
pw.setTouchInterceptor(customPopUpTouchListenr); 

代わりに行の順序を変更するためにそこに何も

+0

うまくいきません...私のために手配した後でも働いています.. – charlie

0
ようにそれを作ります

PopupWindowに対してFocusable(false)を設定することが可能です

オプション「常にトップに」フローティングウィンドウに近い

元のレイアウトが完全であると以下

ボタンはまだなく、視覚的なクリック動作なしで、(ショーのクリックを強制的にいくつかのカスタムハンドラ?)クリック可能

はフローティングウィンドウのサンプルですどちらの場合も、動作は、さらに、窓はまだ窓も

に浮いている時にダイアログや他のポップアップを使用することが可能である再利用可能な

final static int buttonAlpha = 0xDF; 
final static float buttonTextSize = 12f; 

public final void addPopupButton(LinearLayout linearLayout, String title, android.view.View.OnClickListener onClickListener) 
{ 
    Button button = new Button(this.getContext()); 
    button.setText(title); 
    button.setTextSize(buttonTextSize); 
    button.getBackground().setAlpha(buttonAlpha); 
    button.setOnClickListener(onClickListener); 
    linearLayout.addView(button, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); 
} 

public final Button addPopupCheckbox(LinearLayout linearLayout, String title, boolean isChecked, android.view.View.OnClickListener onClickListener) 
{ 
    final Button button = new Button(getContext()); 
    button.setText(title); 
    button.setTextSize(buttonTextSize); 
    final int buttonHeight = button.getHeight(); 
    setButtonChecked(button, isChecked); 
    button.setHeight(buttonHeight); 
    button.getBackground().setAlpha(buttonAlpha); 
    button.setOnClickListener(onClickListener); 
    linearLayout.addView(button, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); 
    return button; 
} 

public final void setButtonChecked(Button button, boolean isChecked) 
{ 
    button.setCompoundDrawablesWithIntrinsicBounds(Resources.getSystem().getIdentifier(isChecked ? "android:drawable/btn_check_on" : "android:drawable/btn_check_off", null, null), 0, 0, 0); 
} 

private boolean isMenuAlwaysOnTop = true; 
private PopupWindow popupWindowMenuV2 = null; 

public final void popupMenuNav2() 
{ 
    if (popupWindowMenuV2 == null) 
    { 
     // [start] layout 

     ScrollView scrollView = new ScrollView(this.getContext()); 

     final LinearLayout linearLayoutNavigation = new LinearLayout(this.getContext()); 
     linearLayoutNavigation.setOrientation(LinearLayout.VERTICAL); 
     linearLayoutNavigation.setBackgroundColor(0x7FFFFFFF); 
     linearLayoutNavigation.setPadding(20, 10, 20, 10); 

     scrollView.addView(linearLayoutNavigation, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); 

     popupWindowMenuV2 = new PopupWindow(this); 
     popupWindowMenuV2.setBackgroundDrawable(new BitmapDrawable()); 
     popupWindowMenuV2.setWidth(WindowManager.LayoutParams.WRAP_CONTENT); 
     popupWindowMenuV2.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); 
     popupWindowMenuV2.setTouchable(true); 
     popupWindowMenuV2.setOutsideTouchable(!isMenuAlwaysOnTop); 
     popupWindowMenuV2.setFocusable(!isMenuAlwaysOnTop); 
     popupWindowMenuV2.setTouchInterceptor(new OnTouchListener() 
     { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) 
      { 
       if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_OUTSIDE) 
       { 
        if (!isMenuAlwaysOnTop) 
         popupWindowMenuV2.dismiss(); 
        else 
         return false; 
        return true; 
       } 
       return false; 
      } 
     }); 
     popupWindowMenuV2.setContentView(scrollView); 

     // [end] layout 

     // [start] always on top checkbox 

     final Button buttonMenuAlwaysOnTop = addPopupCheckbox(linearLayoutNavigation, "always on top", isMenuAlwaysOnTop, null); 
     buttonMenuAlwaysOnTop.setOnClickListener(
       new OnClickListener() 
       { 
        @Override 
        public void onClick(View vv) 
        { 
         isMenuAlwaysOnTop = !isMenuAlwaysOnTop; 
         setButtonChecked(buttonMenuAlwaysOnTop, isMenuAlwaysOnTop); 
         popupWindowMenuV2.dismiss(); 
         popupWindowMenuV2.setOutsideTouchable(!isMenuAlwaysOnTop); 
         popupWindowMenuV2.setFocusable(!isMenuAlwaysOnTop); 
         popupWindowMenuV2.showAtLocation(((Activity) getContext()).getWindow().getDecorView(), Gravity.CENTER_VERTICAL + Gravity.RIGHT, 0, 0); 
        } 
       }); 

     // [end] always on top checkbox 

     addPopupButton(linearLayoutNavigation, "some button", 
       new OnClickListener() 
       { 
        @Override 
        public void onClick(View vv) 
        { 
         if (!isMenuAlwaysOnTop) 
          popupWindowMenuV2.dismiss(); 
         someAction(); 
        } 
       }); 

    } 

    popupWindowMenuV2.showAtLocation(((Activity) getContext()).getWindow().getDecorView(), Gravity.CENTER_VERTICAL + Gravity.RIGHT, 0, 0); 
} 

// somewhere in handler: 
      if (someCondition) 
      { 
       if (popupWindowMenuV2 != null && popupWindowMenuV2.isShowing()) 
        popupWindowMenuV2.dismiss(); 
       else 
        popupMenuNav2(); 
       return true; 
      } 
0

まず第一に、あなたは外に触れたときに、なぜpopupWindowが却下されていることを把握しなければなりません。 PopupWindowのソースコードとリソースファイルのstyles.xmlを読んだ後

<style name="Widget.PopupWindow"> 
    <item name="popupBackground">@drawable/editbox_dropdown_background_dark</item> 
    <item name="popupAnimationStyle">@style/Animation.PopupWindow</item> 
</style> 
<style name="Widget"> 
    <item name="textAppearance">?textAppearance</item> 
</style> 

だからであるダイアログテーマのような何もない:

<style name="Theme.Dialog"> 
<item name="windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item> 
</style name="Theme.Dialog"> 

しかし代が起こるPopupWindow.setBackgroundDrawable( )が呼び出されると、

private void preparePopup(WindowManager.LayoutParams p) { 
    if (mContentView == null || mContext == null || mWindowManager == null) { 
     throw new IllegalStateException("You must specify a valid content view by " 
       + "calling setContentView() before attempting to show the popup."); 
    } 

    if (mBackground != null) { 
     final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); 
     int height = ViewGroup.LayoutParams.MATCH_PARENT; 
     if (layoutParams != null && 
       layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { 
      height = ViewGroup.LayoutParams.WRAP_CONTENT; 
     } 

     // when a background is available, we embed the content view 
     // within another view that owns the background drawable 
     PopupViewContainer popupViewContainer = new PopupViewContainer(mContext); 
     PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams(
       ViewGroup.LayoutParams.MATCH_PARENT, height 
     ); 
     popupViewContainer.setBackgroundDrawable(mBackground); 
     popupViewContainer.addView(mContentView, listParams); 

     mPopupView = popupViewContainer; 
    } else { 
     mPopupView = mContentView; 
    } 
    mPopupViewInitialLayoutDirectionInherited = 
      (mPopupView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT); 
    mPopupWidth = p.width; 
    mPopupHeight = p.height; 
} 

コンテナビュー "PopupViewContainer"はcです。 reated。

private class PopupViewContainer extends FrameLayout { 
    private static final String TAG = "PopupWindow.PopupViewContainer"; 

    public PopupViewContainer(Context context) { 
     super(context); 
    } 


    @Override 
    public boolean dispatchTouchEvent(MotionEvent ev) { 
     if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) { 
      return true; 
     } 
     return super.dispatchTouchEvent(ev); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     final int x = (int) event.getX(); 
     final int y = (int) event.getY(); 

     if ((event.getAction() == MotionEvent.ACTION_DOWN) 
       && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) { 
      dismiss(); 
      return true; 
     } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { 
      dismiss(); 
      return true; 
     } else { 
      return super.onTouchEvent(event); 
     } 
    } 

}

今、あなたが重要な理由を知っています。 外部に触れた後にaviod PopupWindowを解除できる方法は2つあります。 1. @ Raagaと同じように。 pw.setBackgroundDrawable(新しいBitmapDrawable())を削除します。

  1. OnTouchListenerを実装して、PopupWindowの外でtoucheイベントをフィルタリングすることができます。
関連する問題