今天在幫同學(xué)實現(xiàn)一個PopupWindow嵌套PopupWindow時報了異常,導(dǎo)致第二個POP不能顯示:
企業(yè)建站必須是能夠以充分展現(xiàn)企業(yè)形象為主要目的,是企業(yè)文化與產(chǎn)品對外擴展宣傳的重要窗口,一個合格的網(wǎng)站不僅僅能為公司帶來巨大的互聯(lián)網(wǎng)上的收集和信息發(fā)布平臺,成都創(chuàng)新互聯(lián)公司面向各種領(lǐng)域:石涼亭等成都網(wǎng)站設(shè)計、營銷型網(wǎng)站解決方案、網(wǎng)站設(shè)計等建站排名服務(wù)。
android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@4340e618 is not valid; is your activity running? |
先貼代碼:
volleytest_lay.xml,pop_first_lay.xml,pop_second_lay:
android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:orientation="vertical" > |
PopupWindowActivity.java :
public class PopupWindowActivity extends Activity { private Button popBtn = null, mButton; private Context mContext; private PopupWindow mSecondPOPWindow, mFirstPOPWindow = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.volleytest_lay); mContext = this; popBtn = (Button) findViewById(R.id.popBtn); initPopFirst(); initListener(); } private void initListener() { // TODO Auto-generated method stub popBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if (mFirstPOPWindow.isShowing()) { // 隱藏窗口,如果設(shè)置了點擊窗口外小時即不需要此方式隱藏 mFirstPOPWindow.dismiss(); } else { // 顯示窗口 mFirstPOPWindow.showAsDropDown(v); } } }); } /** * 初始化第一個POP */ private void initPopFirst() { View firstView = getLayoutInflater().inflate(R.layout.pop_first_lay, null); mFirstPOPWindow = new PopupWindow(firstView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, true); mFirstPOPWindow.setTouchable(true); mFirstPOPWindow.setOutsideTouchable(true); mFirstPOPWindow.setFocusable(true); mFirstPOPWindow.setBackgroundDrawable(new BitmapDrawable()); initPopSecond(); Button btn = (Button) firstView.findViewById(R.id.popFirstBtn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { if (mSecondPOPWindow.isShowing()) { // 隱藏窗口,如果設(shè)置了點擊窗口外小時即不需要此方式隱藏 mSecondPOPWindow.dismiss(); } else { // 顯示窗口 mSecondPOPWindow.showAsDropDown(v, 500, 500); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } /*//測試AlertDialog new AlertDialog.Builder(mContext) .setTitle("確認") .setMessage("確定嗎?") .setPositiveButton("是", null) .setNegativeButton("否", null) .show();*/ } }); } /** * 初始化第二個POP */ private void initPopSecond() { View popSecView = PopupWindowActivity.this.getLayoutInflater().inflate( R.layout.pop_second_lay, null); mSecondPOPWindow = new PopupWindow(popSecView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, true); mSecondPOPWindow.setTouchable(true); mSecondPOPWindow.setOutsideTouchable(true); mSecondPOPWindow.setFocusable(true); mSecondPOPWindow.setBackgroundDrawable(new BitmapDrawable()); Button popSecondBtn = (Button) popSecView .findViewById(R.id.popSecondBtn); popSecondBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(PopupWindowActivity.this, "第二個POP", 100).show(); } }); } } |
此時是報異常的,經(jīng)過不斷的排查和網(wǎng)上搜查,問題依然沒有解決。比如這里http://stackoverflow.com/questions/8782250/popupwindow-badtokenexception-unable-to-add-window-token-null-is-not-valid 只是提出討論并么有實際解決出來。
異常的原因是因為第一個PopupWindow已經(jīng)顯示后,他就控制了整個Window的焦點,此時第一個POP則成為了父Window,而PopupWindow是不能以子window的形式展現(xiàn)的,他們必須都要以父Window顯示,所以第二個POP無法添加上去。
修改后:
public class PopupWindowActivity extends Activity { private Button popBtn = null, mButton; private Context mContext; private PopupWindow mSecondPOPWindow, mFirstPOPWindow = null; private View parientView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.volleytest_lay); mContext = this; popBtn = (Button) findViewById(R.id.popBtn); initPopFirst(); initListener(); } private void initListener() { // TODO Auto-generated method stub popBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if (mFirstPOPWindow.isShowing()) { // 隱藏窗口,如果設(shè)置了點擊窗口外小時即不需要此方式隱藏 mFirstPOPWindow.dismiss(); } else { // 顯示窗口 mFirstPOPWindow.showAsDropDown(v); } // 給第二個POP顯示時用,解決了嵌套時出現(xiàn)的Unable to add window的問題 parientView = v; } }); } /** * 初始化第一個POP */ private void initPopFirst() { View firstView = getLayoutInflater().inflate(R.layout.pop_first_lay, null); mFirstPOPWindow = new PopupWindow(firstView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, true); mFirstPOPWindow.setTouchable(true); mFirstPOPWindow.setOutsideTouchable(true); mFirstPOPWindow.setFocusable(true); mFirstPOPWindow.setBackgroundDrawable(new BitmapDrawable()); initPopSecond(); Button btn = (Button) firstView.findViewById(R.id.popFirstBtn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { if (mSecondPOPWindow.isShowing()) { // 隱藏窗口,如果設(shè)置了點擊窗口外小時即不需要此方式隱藏 mSecondPOPWindow.dismiss(); } else { // 顯示窗口 mSecondPOPWindow.showAsDropDown(parientView, 500, 500); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } /*//測試AlertDialog new AlertDialog.Builder(mContext) .setTitle("確認") .setMessage("確定嗎?") .setPositiveButton("是", null) .setNegativeButton("否", null) .show();*/ } }); } /** * 初始化第二個POP */ private void initPopSecond() { View popSecView = PopupWindowActivity.this.getLayoutInflater().inflate( R.layout.pop_second_lay, null); mSecondPOPWindow = new PopupWindow(popSecView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, true); mSecondPOPWindow.setTouchable(true); mSecondPOPWindow.setOutsideTouchable(true); mSecondPOPWindow.setFocusable(true); mSecondPOPWindow.setBackgroundDrawable(new BitmapDrawable()); Button popSecondBtn = (Button) popSecView .findViewById(R.id.popSecondBtn); popSecondBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(PopupWindowActivity.this, "第二個POP", 100).show(); } }); } } |
解決方式請看紅色標出的部分,而且解決的方式相當簡單(此方案得益于一個同學(xué)),有時候我們把問題想得太復(fù)雜了,反而會使我們陷入一定的僵局,換一種思路去看待問題,必然會柳暗花明。
其實這個問題可以換一種方式解決,那就是第二個POP用AlertDialog顯示也是可以,看代碼中我注釋點的幾句就會明白,只是你非要用POP時就用我提供的這個就可以了,當然還有可能有更多的解決方案,如果有其他解決方案時,請分享一起學(xué)習,寫此博文,只是希望對目前還沒解決的人提供一點幫助。
×××