I have a custom View extending from RelativeLayout. It consists of an ImageView, a PullToRefresh View and an EditText. When my app receives push notification from GCM, I use WindowManager to add the custom View. Everything works fine except the fact that when I touch the EditText the Soft Keyboard shows up and covers the EditText, not resizes other views as it should be. I search around the internet, some people had the same problem as me but their solution didn't help me so I'm confused now. Please show me where I did wrong.
Here is my code:
-Add View using WindowManager:
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT);
ChatHeadCancelView chatheadTrashView = new ChatHeadCancelView(this, windowManager, params);
ChatHeadView chatheadView = new ChatHeadView(this, chatheadTrashView, windowManager, params, id);
chatheadView.setOnChatheadClickListener(this);
params.gravity = Gravity.TOP | Gravity.CENTER;
windowManager.addView(chatheadTrashView, params);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
params.x = 0;
params.y = 100;
windowManager.addView(chatheadView, params);
Part of my custom View constructor:
public ChatHeadView(Context context, ChatHeadCancelView trashView,
WindowManager windowManager, WindowManager.LayoutParams params, int id) {
super(context);
this.context = context;
Activity parent = (Activity)this.context;
// using the activity, get Window reference
Window window = parent.getWindow();
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
this.chatheadView = this;
id = id;
this.windowManager = windowManager;
this.params = params;
this.trashView = trashView;
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.chat_head_fragment_layout, this, true);
// capture views
this.primarySenderAvatar = (ImageView) findViewById(R.id.chathead_sender_user_avatar);
this.chatView = (LinearLayout) findViewById(R.id.chat_view);
this.chatView.setScaleX(0.0f);
this.chatView.setScaleY(0.0f);
ViewGroup.LayoutParams contentParams = chatView.getLayoutParams();
contentParams.width = getDisplayWidth();
contentParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
chatView.setLayoutParams(contentParams);
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
public void onGlobalLayout() {
chatView.setPivotX(findViewById(R.id.chathead_sender_user_avatar).getWidth() / 2);
if (Build.VERSION.SDK_INT >= 16) {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
this.bubbleSpringParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
PixelFormat.TRANSLUCENT);
this.bubbleSpringParams.gravity = Gravity.TOP | Gravity.LEFT;
this.bubbleSpringParams.x = mPos[0];
this.bubbleSpringParams.y = mPos[1];
this.bubbleSpringParams.dimAmount = 0.6f;
SpringSystem system;
Spring sBubbleSpring;
Spring sContentSpring;
system = SpringSystem.create();
SpringConfig springConfig = new SpringConfig(sSpringTension, sSpringFriction);
sContentSpring = system.createSpring();
sContentSpring.setSpringConfig(springConfig);
sContentSpring.setCurrentValue(0.0);
sBubbleSpring = system.createSpring();
sBubbleSpring.setSpringConfig(springConfig);
sBubbleSpring.setCurrentValue(1.0);
this.mPullToRefreshListView = (PullToRefreshListView) findViewById(R.id.list_messages);
this.postMessageBoxView = (PostMessageBoxView) findViewById(R.id.post_message_layout);
this.topLayout = (LinearLayout) findViewById(R.id.top_layout);
this.messageListView = (ListView) mPullToRefreshListView
.getRefreshableView();
this.messageListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
this.mPullToRefreshListView.setMode(Mode.PULL_FROM_START);
this.mPullToRefreshListView.setScrollingWhileRefreshingEnabled(false);
this.messageListView.setAdapter(messageAdapter);
this.messageListView.setSelection(messageAdapter.getCount() - 1);
this.messageListView.setCacheColorHint(Color.TRANSPARENT);
this.setListeners(id, sContentSpring, sBubbleSpring);
this.removeTrash();
}
After received push notification, I will show the ImageView as a ChatHead. Then when user touch it it will pop up the chat view using Spring:
private void setListeners(final int id, final Spring sContentSpring, final Spring sBubbleSpring) {
sContentSpring.addListener(new SpringListener() {
@Override
public void onSpringUpdate(Spring spring) {
float value = (float) spring.getCurrentValue();
float clampedValue = (float) SpringUtil.clamp(value, 0.0, 1.0);
chatView.setScaleX(value);
chatView.setScaleY(value);
chatView.setAlpha(clampedValue);
}
@Override
public void onSpringAtRest(Spring spring) {
chatView.setLayerType(View.LAYER_TYPE_NONE, null);
if (spring.currentValueIsApproximately(0.0)) {
chatView.setVisibility(View.GONE);
}
}
@Override
public void onSpringActivate(Spring spring) {
chatView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
@Override
public void onSpringEndStateChange(Spring spring) {
}
});
this.primarySenderAvatar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sBubbleSpring.addListener(new SpringListener() {
@Override
public void onSpringUpdate(Spring spring) {
double value = spring.getCurrentValue();
bubbleSpringParams.x = (int) (SpringUtil.mapValueFromRangeToRange(value, 0.0, 1.0, 0.0, mPos[0]));
bubbleSpringParams.y = (int) (SpringUtil.mapValueFromRangeToRange(value, 0.0, 1.0, 0.0, mPos[1]));
windowManager.updateViewLayout(chatheadView, bubbleSpringParams);
if (spring.isOvershooting() && sContentSpring.isAtRest()) {
sContentSpring.setEndValue(1.0);
}
}
@Override
public void onSpringAtRest(Spring spring) {
}
@Override
public void onSpringActivate(Spring spring) {
}
@Override
public void onSpringEndStateChange(Spring spring) {
}
});
if (onChatheadListener != null) {
onChatheadListener.onClick(chatheadView);
}
chatView.setVisibility(VISIBLE);
if (! mbExpanded) {
getLocationOnScreen(mPos);
mPos[1] -= 72;
bubbleSpringParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
bubbleSpringParams.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
sBubbleSpring.setEndValue(0.0);
} else {
bubbleSpringParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
bubbleSpringParams.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
sBubbleSpring.setEndValue(1.0);
sContentSpring.setEndValue(0.0);
}
mbExpanded = ! mbExpanded;
}
});
I know my code is clumsy and ugly, I was testing to create a ChatHead. Any help is very much appreciated. Thanks in advanced.