Open paynd opened 9 years ago
Providing a sample code to reproduce the issue would be very helpful. I don't understand the "When I tried to use as parent other view (for example root view of my activity) I got wrong placement of PopupIndicator" part.
Sorry for my bad english. Code to reproduce:
private PopupWindow mShapeDialog = null;
public void showShapeSettingsDialog() {
LayoutInflater inflater = LayoutInflater.from(getContext());
LinearLayout container = (LinearLayout) inflater.inflate(R.layout.dialog_shape_settings, null);
// mShapeDialog = new PopupWindow(getContext());
mShapeDialog = new PopupWindow( SmartObjLayer.this, 1000, 1500, true);
DiscreteSeekBar discreteSeekBar1 = (DiscreteSeekBar) container.findViewById(R.id.discrete1);
discreteSeekBar1.setProgress(Math.round(mSelectedView.getCurrentFillColorAlpha() * 100 / 255));
mShapeDialog.showAtLocation(SmartObjLayer.this, Gravity.NO_GRAVITY, 0, 0);
}
I`ve tried to fix it by adding this to DiscreteSeekBar
private View tokenView = null;
public void setTokenView(View tokenView) {
this.tokenView = tokenView;
}
and modifying this method:
private void showFloater() {
if (!isInEditMode()) {
mThumb.animateToPressed();
if(tokenView!=null){
mIndicator.showIndicator(tokenView, mThumb.getBounds());
}else {
mIndicator.showIndicator(this, mThumb.getBounds());
}
notifyBubble(true);
}
}
As a tokenView I used my root view. I get rid of BadTokenException but PopupIndicator was placed in wrong place.
Oh, I see. A PopupWindow cannot be parent of another PopupWindow so you need a bit of hackery here, so both PopupWindows use the same token:
Instead a method to pass a "View tokenView", create a method to pass an "IBinder windowToken"
private IBinder token = null;
public void setToken(IBinder token) {
this.token = token;
}
then, showFloater would be this way:
private void showFloater() {
if (!isInEditMode()) {
mThumb.animateToPressed();
if (token != null) {
mIndicator.showIndicatorWithToken(this, mThumb.getBounds(), token);
} else {
mIndicator.showIndicator(this, mThumb.getBounds());
}
notifyBubble(true);
}
}
You need to create this method inside PopupIndicator.java
public void showIndicatorWithToken(View parent, Rect touchBounds, IBinder windowToken) {
if (isShowing()) {
mPopupView.mMarker.animateOpen();
return;
}
if (windowToken != null) {
WindowManager.LayoutParams p = createPopupLayout(windowToken);
p.gravity = Gravity.TOP | GravityCompat.START;
updateLayoutParamsForPosiion(parent, p, touchBounds.bottom);
mShowing = true;
translateViewIntoPosition(touchBounds.centerX());
invokePopup(p);
}
}
and finally, when you create your popup:
private PopupWindow mShapeDialog = null;
public void showShapeSettingsDialog() {
View yourPopupAnchorView = SmartObjLayer.this;
LayoutInflater inflater = LayoutInflater.from(getContext());
LinearLayout container = (LinearLayout) inflater.inflate(R.layout.dialog_shape_settings, null);
mShapeDialog = new PopupWindow(container, 1000, 1500, true);
DiscreteSeekBar discreteSeekBar1 = (DiscreteSeekBar) container.findViewById(R.id.discrete1);
discreteSeekBar1.setToken(yourPopupAnchorView.getWindowToken());
discreteSeekBar1.setProgress(Math.round(mSelectedView.getCurrentFillColorAlpha() * 100 / 255));
mShapeDialog.showAtLocation(yourPopupAnchorView, Gravity.NO_GRAVITY, 0, 0);
}
Anyways, unless your settings popup is constantly being shown/hidden, You should better create a DialogFragment instead of a PopupWindow.
Unfortunately I cant use DialogFragment here. :( And thank you for your fix! It works, but I still have problem with positioning of indicator when I place popup window
mShapeDialog.showAtLocation(SmartObjLayer.this, Gravity.NO_GRAVITY, locationX, locationY);
May be I`ll try some offset correction.
P.S. Also I've found an article http://www.androiddesignpatterns.com/2013/07/binders-window-tokens.html IBinder principles isn't clear for me now.
Hi! I found the bug when I tried to use this widget into my floating menu that was implemented using PopupWindow.
It fall on PopupIndicator:166 when I tried to
Looks like parent view`s token (so parent are Popupwindow) are wrong. When I tried to use as parent other view (for example root view of my activity) I got wrong placement of PopupIndicator. so it goes :(