Demand analysis:

When we click on the input box, it will bring up the input method soft keyboard. If we do not do anything, the PopupWindow comment window may be crowded to the top of the screen. Even worse, we can’t see our input box, and we can’t even see what we type, which will make the user experience very bad! Let’s take a look at our renderings below:

1. As can be seen from the above figure, the input method pops up and hides. For our comment window, the height is always the same, which can bring users a better experience!

2. By default, we set the PopupWindow popup height to 80% of the screen, but you can set other proportions in your code.

First, we rewrote the RelativeLayout root layout to listen for input method state

KeyboardLayout.java

package com.t20.commentdemo.view;

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.RelativeLayout;

RelativeLayout with keyboard listener
public class KeyboardLayout extends RelativeLayout {

	private KeyboardLayoutListener mListener;
	private boolean mIsKeyboardActive = false; // Whether the input method is active
	private int mKeyboardHeight = 0; // Input method height
	private Context mContext;

	public KeyboardLayout(Context context) {
		this(context, null.0);
	}

	public KeyboardLayout(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public KeyboardLayout(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		mContext = context;
		// Listen for layout changes
		getViewTreeObserver().addOnGlobalLayoutListener(
				new KeyboardOnGlobalChangeListener());
	}

	private class KeyboardOnGlobalChangeListener implements
			OnGlobalLayoutListener {

		int mScreenHeight = 0;

		private int getScreenHeight(a) {
			if (mScreenHeight > 0) {
				return mScreenHeight;
			}
			mScreenHeight = ((Activity) mContext).getWindowManager()
					.getDefaultDisplay().getHeight();
			return mScreenHeight;
		}

		@Override
		// Called when the global layout in the view tree changes or the visual state of a view in the view tree changes
		public void onGlobalLayout(a) {
			Rect rect = new Rect();
			// Get the display range of the current page window
			((Activity) getContext()).getWindow().getDecorView()
					.getWindowVisibleDisplayFrame(rect);
			int screenHeight = getScreenHeight();
			int keyboardHeight = screenHeight - rect.bottom; // Input method height
			boolean isActive = false;
			if (Math.abs(keyboardHeight) > screenHeight / 5) {
				isActive = true; // Over 1/5 of the screen indicates that the input method is popped up
				mKeyboardHeight = keyboardHeight;
			}
			mIsKeyboardActive = isActive;
			if(mListener ! =null) { mListener.onKeyboardStateChanged(isActive, keyboardHeight); }}}public void setKeyboardListener(KeyboardLayoutListener listener) {
		mListener = listener;
	}

	public KeyboardLayoutListener getKeyboardListener(a) {
		return mListener;
	}

	public boolean isKeyboardActive(a) {
		return mIsKeyboardActive;
	}

	/** * Get the input method height **@return* /
	public int getKeyboardHeight(a) {
		return mKeyboardHeight;
	}

	public interface KeyboardLayoutListener {
		/ * * *@paramIsActive * indicates whether the input method isActive@paramKeyboardHeight * Input panel height */
		void onKeyboardStateChanged(boolean isActive, int keyboardHeight); }}Copy the code

Second, we have a custom PopupWindow that we can reference directly to other projects later

CommentPopupWindow.java

package com.t20.commentdemo.view;

import com.t20.commentdemo.R;
import com.t20.commentdemo.view.KeyboardLayout.KeyboardLayoutListener;

import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class CommentPopupWindow extends PopupWindow {
	private Context mContext;
	private OnClickListener mOnClickListener;
	private OnFocusChangeListener mOnFocusChangeListener;

	private View mPopupWindowView;
	// popupWindow layout
	private RelativeLayout mPopupWindowViewLayout;
	// The entire screen width
	private int mScreenWidth;
	// The height of the entire screen
	private int mScreenHeight;
	// popupWindow specifies the height of the layout as a percentage of the screen
	private final double mPopupWindowHeightForScreenPercent = 0.8;
	private LinearLayout mCommentPopupWindowHead;
	private LinearLayout mCommentPopupWindowFoot;
	// Total number of comments
	private TextView mTextViewCommentCount;
	// Close the window
	private TextView mTextViewClose;
	// List view of comments
	private ListView mListViewComments;
	// Enter the comment content
	private EditText mEditTextInput;
	// Send button
	private TextView mTextViewSend;

	// Set the width and height of the control
	private android.widget.LinearLayout.LayoutParams mLayoutParams;
	
	public EditText getmEditTextInput(a) {
		return mEditTextInput;
	}

	public void setmEditTextInput(EditText mEditTextInput) {
		this.mEditTextInput = mEditTextInput;
	}

	public CommentPopupWindow(Context context, OnClickListener onClickListener, OnFocusChangeListener onFocusChangeListener) {
		super(context);
		mContext = context;
		mOnClickListener = onClickListener;
		mOnFocusChangeListener = onFocusChangeListener;
		initDate();
		initView();
		setPopupWindowSize();
		initEvent();
	}

	private void initDate(a) {
		// Get the screen width and height.
		DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
		mScreenWidth = dm.widthPixels;
		mScreenHeight = dm.heightPixels;
	}

	private void initView(a) {
		// Get the layout
		mPopupWindowView = View.inflate(mContext, R.layout.comment_dialog, null);
		// Get the control
		mPopupWindowViewLayout = (RelativeLayout) mPopupWindowView.findViewById(R.id.commentPopupWindow_comment_layout);
		mCommentPopupWindowHead = (LinearLayout) mPopupWindowView.findViewById(R.id.commentPopupWindow_comment_head);
		mCommentPopupWindowFoot = (LinearLayout) mPopupWindowView.findViewById(R.id.commentPopupWindow_comment_foot);
		mTextViewCommentCount = (TextView) mPopupWindowView.findViewById(R.id.commentPopupWindow_comment_tv_commentsCount);
		mTextViewClose = (TextView) mPopupWindowView.findViewById(R.id.commentPopupWindow_comment_tv_close);
		mListViewComments = (ListView) mPopupWindowView.findViewById(R.id.commentPopupWindow_comment_lv);
		mEditTextInput = (EditText) mPopupWindowView.findViewById(R.id.commentPopupWindow_comment_et_input);
		mTextViewSend = (TextView) mPopupWindowView.findViewById(R.id.commentPopupWindow_comment_tv_send);
		mLayoutParams = (android.widget.LinearLayout.LayoutParams) mPopupWindowViewLayout.getLayoutParams();
	}

	private void setPopupWindowSize(a) {
		// Add a margin to the ListView -- note the BUG: the maximum layout cannot be relative
		mCommentPopupWindowHead.measure(0.0);
		int headHeight = mCommentPopupWindowHead.getMeasuredHeight();// Get the head height
		mCommentPopupWindowFoot.measure(0.0);
		int footHeight = mCommentPopupWindowFoot.getMeasuredHeight();// Get the tail height
		mListViewComments.setPadding(0, headHeight, 0, footHeight);
		this.setContentView(mPopupWindowView);
		// Click outside the window (click outside the area to close the window)
		this.setOutsideTouchable(true);
		// Form is clickable
		this.setFocusable(true);
		// Fix bugs in earlier versions of Android (clicking "Back" will also make them disappear, without affecting your background)
		this.setBackgroundDrawable(new BitmapDrawable());
		// Set the height of the content layout (as a percentage of the screen height)
		mLayoutParams.height = (int) (mScreenHeight * mPopupWindowHeightForScreenPercent);
		mPopupWindowViewLayout.setLayoutParams(mLayoutParams);
		// Set the popupWindow width to be the same as the screen width
		this.setWidth(mScreenWidth);
		// Set the popupWindow height to the same as the content height
		this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
		// Pop overlays the input method
		this.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
		// This sentence lets pop adapt to the input state
		this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
	}

	private void initEvent(a) {
		mTextViewClose.setOnClickListener(mOnClickListener);
		mEditTextInput.setOnFocusChangeListener(mOnFocusChangeListener);
		mTextViewSend.setOnClickListener(mOnClickListener);
	}
	
	/** * Changes the height of the comment popupWindow layout * depending on whether the input keyboard pops up@param keyboardLayout
	 */
	public void setPopupWindowFroKeyboard(KeyboardLayout keyboardLayout ){
		if(keyboardLayout ! =null) {
			keyboardLayout.setKeyboardListener(new KeyboardLayoutListener() {

				@Override
				public void onKeyboardStateChanged(boolean isActive,int keyboardHeight) {
					if (isActive) { // The input method is displayed
						setpopupWindowHeight(keyboardHeight);
					} else {// The input method is hidden
						setpopupWindowHeight(0); }}}); }}// Set the height of the comment window
	public void setpopupWindowHeight(int keyboardHeight) {
		mLayoutParams.height = (int) (mScreenHeight * mPopupWindowHeightForScreenPercent)- keyboardHeight; mPopupWindowViewLayout.setLayoutParams(mLayoutParams); }}Copy the code

Three, we activity_main. XML layout, com.t20.com mentdemo. The KeyboardLayout is KeyboardLayout Java the full path

<com.t20.commentdemo.view.KeyboardLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/keyboardLayout_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="# 000"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:onClick="openCommentWindow"
        android:textColor="#fff"
        android:text="Click to pop up the comment window" />

</com.t20.commentdemo.view.KeyboardLayout>
Copy the code

Finally, the popup call to the CommentPopupWindow in the activity mainActivity. Java

package com.t20.commentdemo;

import com.t20.commentdemo.view.CommentPopupWindow;
import com.t20.commentdemo.view.KeyboardLayout;

import android.os.Bundle;
import android.app.Activity;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;

public class MainActivity extends Activity {
	// Maximum KeyboardLayout(RelativeLayout rewrite)
	private KeyboardLayout mKeyboardLayoutRoot;
	/ / comment
	private CommentPopupWindow mCommentPopupWindow;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 1, hide the title bar, set before loading the layout (compatible with Android2.3.3 version)
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		// hide the status bar
		//getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);								
		setContentView(R.layout.activity_main);
		// Get the control
		mKeyboardLayoutRoot=(KeyboardLayout) findViewById(R.id.keyboardLayout_root);
	}

	/** * Click the pop-up comment window event *@param view
	 */
	public void openCommentWindow(View view) {
		// Define the popup window
		mCommentPopupWindow=new CommentPopupWindow(MainActivity.this, onClickListener, onFocusChangeListener);
		/ / display PopupWindow
		mCommentPopupWindow.showAtLocation(mKeyboardLayoutRoot, Gravity.BOTTOM,0.0);
		// Make the input box lose focus
		mCommentPopupWindow.getmEditTextInput().clearFocus();	
		// Change the height of the comment popupWindow layout depending on whether the input keyboard pops up
		mCommentPopupWindow.setPopupWindowFroKeyboard(mKeyboardLayoutRoot);
	}
	/** * listen for click events in comments */
	private OnClickListener onClickListener=new OnClickListener() {
		
		@Override
		public void onClick(View view) {
			// TODO Auto-generated method stub
			switch (view.getId()) {
			// Close the button
			case R.id.commentPopupWindow_comment_tv_close:
				mCommentPopupWindow.dismiss();
				break;
			// Click to comment
			case R.id.commentPopupWindow_comment_tv_send:
				break; }}};/** * listen for focus change events in comments */
	private OnFocusChangeListener onFocusChangeListener=new OnFocusChangeListener() {
		
		@Override
		public void onFocusChange(View view, boolean hasFocus) {
			// TODO Auto-generated method stub
			switch (view.getId()) {
			case R.id.commentPopupWindow_comment_et_input:
				// Get the focus
				if (hasFocus) { 
					// During focusing, determine whether the user is logged in. If not, the login interface can be redirected
				}
				break; }}}; }Copy the code