Dismiss Android PopupWindow when switching to a new Tab in TabActivity?
I have a MapActivity as one of four tabs in a TabActivity. This MapActivity can launch a PopupWindow that is a legend. The PopupWindow remains on the screen, on top of the map, until the "Show Legend" button is clicked again (back and forth, etc.).
The problem is that, when a user switches to another tab, the PopupWindow remains persistent over the view.
I've tried implementing the onPause() method in the MapActivity class, and dismissing it from there. The application force closes with this method in place.
Any help? Thanks!
EDIT: Here's some of my code:
In the MainActivity, which establishes the four tabs:
Resources res = getResources(); // Resource object to get Drawables
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec; // Reusable TabSpec for each tab
Intent intent; // Reusable Intent for each tab
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, FirstActivity.class);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("game").setIndicator("First",
res.getDrawable(R.drawable.ic_tab_game))
.setContent(intent);
tabHost.addTab(spec);
// Do the same for the other tabs
intent = new Intent().setClass(this, SecondActivity.class);
spec = tabHost.newTabSpec("alerts").setIndicator("Second",
res.getDrawable(R.drawable.ic_tab_alert))
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, MapActivity.class);
spec = tabHost.newTabSpec("map").setIndicator("Map",
res.getDrawable(R.drawable.ic_tab_map))
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, LastActivity.class);
spec = tabHost.newTabSpec("experience").setIndicator("Last",
res.getDrawable(R.drawable.ic_tab_experience))
.setContent(intent);
tabHost.addTab(spec);
tabHost.setCurrentTab(0);
Now in my MapActivity class (which extends MapActivity):
// Declare the Legend PopupWindow
mapLegendInflater = (LayoutInflater) MapActivity.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mapLegendPopupLayout = mapLegendInflater.inflate(
R.layout.maptablegendpopuplayout, null, false);
mapLegendPopup = new PopupWindow(mapLegendPopupLayout,
(int) (0.45 * getApplicationContext().getResources()
.getDisplayMetrics().widthPixels),
(int) (0.33 * getApplicationContext().getResources()
.getDisplayMetrics().heightPixels), true);
mapLegendPopup.setFocusable(false);
mapLegendPopup.setOutside开发者_如何学运维Touchable(true);
Boolean legendIsShown = false;
mapLegendButton = (Button) findViewById(R.id.buttonMapLegend);
mapLegendButton.setOnClickListener(mapLegendListener);
private OnClickListener mapLegendListener = new OnClickListener() {
public void onClick(View v) {
// Launch or dismiss the map legend popup
if (legendIsShown) {
mapLegendPopup.dismiss();
mapLegendButton.getBackground().clearColorFilter();
legendIsShown = false;
} else {
mapLegendPopup.showAtLocation(
findViewById(R.id.buttonMapLegend), Gravity.TOP
| Gravity.LEFT, 8,
(int) (0.23 * getApplicationContext().getResources()
.getDisplayMetrics().heightPixels));
mapLegendButton.getBackground().setColorFilter(
new LightingColorFilter(0xFFFFFFFF, 0xFFAA0000));
// mapLegendButton.getBackground().setColorFilter(0xFFFFFF00,
// PorterDuff.Mode.MULTIPLY);
legendIsShown = true;
}
}
};
I hope this provides an idea of where I'm at. Everything works perfectly well on the Map tab. It's only when you have the Legend shown and switch tabs that it is still displayed on other views.
I know you said that implementing onPause() did not work for you, but I tried it and implementing onResume() and onPause() in the MapActivity does work for me.
I needed to do a View.post(new Runnable() { ... }) in onResume() since I could not recreate the popupWindow during the onResume() so I had to schedule it to occur immediately afterwards:
package com.esri.android.tabdemo;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
public class MapActivity extends Activity
{
private TextView textView = null;
private PopupWindow popupWindow = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
textView = new TextView(this);
textView.setText("Hello World from MapActivity");
setContentView(textView);
}
@Override
protected void onPause()
{
super.onPause();
if (popupWindow != null)
{
popupWindow.dismiss();
popupWindow = null;
}
}
@Override
protected void onResume()
{
super.onResume();
final Context context = this;
textView.post(
new Runnable()
{
public void run()
{
popupWindow = new PopupWindow(context);
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
Button button = new Button(context);
button.setText("Hello");
button.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Toast.makeText(context, "Hello", Toast.LENGTH_SHORT).show();
}
});
linearLayout.addView(button);
popupWindow.setContentView(linearLayout);
popupWindow.showAtLocation(linearLayout, Gravity.LEFT | Gravity.BOTTOM, 10, 10);
popupWindow.update(256, 64);
}
}
);
}
}
You can init your popupwindown like this:
mapLegendPopup = new PopupWindow(this);
mapLegendPopup.setContentView (itemizeView);
mapLegendPopup.setBackgroundDrawable (new BitmapDrawable()); // key is here
mapLegendPopup.setWidth ((int) (0.45 * getApplicationContext().getResources()
.getDisplayMetrics().widthPixels));
mapLegendPopup.setHeight((int) (0.33 * getApplicationContext().getResources()
.getDisplayMetrics().heightPixels));
mapLegendPopup.setFocusable(false);
mapLegendPopup.setOutsideTouchable(true);
You should manage your Dialogs by using the onCreateDialog() method, as recommended by the framework.
That way your Dialog will become part of your Activity and it will do it by itself.
If you really don't want to use that (I can't see any reason why that would be the case, but still), you can use the setOwnerActivity() on your Dialog to assign it to your Activity.
精彩评论