Permalink
Browse files

Discussed enhancement refactor (Not static, leak free #2)

  • Loading branch information...
ervinmartirosyan
ervinmartirosyan committed Mar 24, 2016
1 parent 8da24c5 commit b4436b972cf9f78938df073faa4d8c84443fcde4
@@ -2,93 +2,85 @@
import android.app.Activity;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import java.lang.ref.WeakReference;
/**
* Created by froger_mcs on 21/03/16.
*/
public class KeyboardWatcher {
private Activity activity;
private ViewGroup rootView;
private WeakReference<Activity> activityRef;
private WeakReference<View> rootViewRef;
private WeakReference<OnKeyboardToggleListener> onKeyboardToggleListenerRef;
private ViewTreeObserver.OnGlobalLayoutListener viewTreeObserverListener;
private OnKeyboardToggleListener onKeyboardToggleListener;
public static KeyboardWatcher initWith(Activity activity) {
KeyboardWatcher keyboardWatcher = new KeyboardWatcher();
keyboardWatcher.activity = activity;
return keyboardWatcher;
public KeyboardWatcher(Activity activity) {
activityRef = new WeakReference<>(activity);
initialize();
}
public KeyboardWatcher bindKeyboardWatcher(OnKeyboardToggleListener onKeyboardToggleListener) {
this.onKeyboardToggleListener = onKeyboardToggleListener;
final View root = activity.findViewById(android.R.id.content);
if (hasAdjustResizeInputMode()) {
if (root instanceof ViewGroup) {
rootView = (ViewGroup) root;
viewTreeObserverListener = new GlobalLayoutListener();
rootView.getViewTreeObserver().addOnGlobalLayoutListener(viewTreeObserverListener);
}
public void setListener(OnKeyboardToggleListener onKeyboardToggleListener) {
onKeyboardToggleListenerRef = new WeakReference<>(onKeyboardToggleListener);
}
public void destroy() {
if (rootViewRef.get() != null && Build.VERSION.SDK_INT >= 16) {
rootViewRef.get().getViewTreeObserver().removeOnGlobalLayoutListener(viewTreeObserverListener);
} else {
Log.w("KeyboardWatcher", "Activity " + activity.getClass().getSimpleName() + " should have windowSoftInputMode=\"adjustResize\"" +
"to make KeyboardWatcher working. You can set it in AndroidManifest.xml");
rootViewRef.get().getViewTreeObserver().removeGlobalOnLayoutListener(viewTreeObserverListener);
}
return this;
}
private boolean hasAdjustResizeInputMode() {
return (activity.getWindow().getAttributes().softInputMode & WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) != 0;
private void initialize() {
if (hasAdjustResizeInputMode()) {
viewTreeObserverListener = new GlobalLayoutListener();
rootViewRef = new WeakReference<>(activityRef.get().findViewById(Window.ID_ANDROID_CONTENT));
rootViewRef.get().getViewTreeObserver().addOnGlobalLayoutListener(viewTreeObserverListener);
} else {
throw new IllegalArgumentException(String.format("Activity %s should have windowSoftInputMode=\"adjustResize\"" +
"to make KeyboardWatcher working. You can set it in AndroidManifest.xml", activityRef.get().getClass().getSimpleName()));
}
}
public void unbindKeyboardWatcher() {
if (rootView != null && viewTreeObserverListener != null) {
if (Build.VERSION.SDK_INT >= 16) {
rootView.getViewTreeObserver().removeOnGlobalLayoutListener(viewTreeObserverListener);
} else {
rootView.getViewTreeObserver().removeGlobalOnLayoutListener(viewTreeObserverListener);
}
this.onKeyboardToggleListener = null;
this.activity = null;
}
private boolean hasAdjustResizeInputMode() {
return (activityRef.get().getWindow().getAttributes().softInputMode & WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) != 0;
}
private class GlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
int initialValue;
private boolean hasSentInitialAction;
private boolean isKeyboardShown;
boolean hasSentInitialAction;
boolean isKeyboardShown;
@Override
public void onGlobalLayout() {
if (initialValue == 0) {
initialValue = rootView.getHeight();
initialValue = rootViewRef.get().getHeight();
} else {
if (initialValue > rootView.getHeight()) {
if (onKeyboardToggleListener != null) {
if (initialValue > rootViewRef.get().getHeight()) {
if (onKeyboardToggleListenerRef != null) {
if (!hasSentInitialAction || !isKeyboardShown) {
isKeyboardShown = true;
onKeyboardToggleListener.onKeyboardShown(initialValue - rootView.getHeight());
onKeyboardToggleListenerRef.get().onKeyboardShown(initialValue - rootViewRef.get().getHeight());
}
}
} else {
if (!hasSentInitialAction || isKeyboardShown) {
isKeyboardShown = false;
rootView.post(new Runnable() {
rootViewRef.get().post(new Runnable() {
@Override
public void run() {
if (onKeyboardToggleListener != null) {
onKeyboardToggleListener.onKeyboardClosed();
if (onKeyboardToggleListenerRef.get() != null) {
onKeyboardToggleListenerRef.get().onKeyboardClosed();
}
}
});
}
}
hasSentInitialAction = true;
}
}
@@ -15,22 +15,23 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
keyboardWatcher = KeyboardWatcher.initWith(this).bindKeyboardWatcher(this);
keyboardWatcher = new KeyboardWatcher(this);
keyboardWatcher.setListener(this);
}
@Override
protected void onDestroy() {
keyboardWatcher.unbindKeyboardWatcher();
keyboardWatcher.destroy();
super.onDestroy();
}
@Override
public void onKeyboardShown(int keyboardSize) {
textView.setText("Shown\nkeyboard size: " +keyboardSize + "px");
textView.setText(String.format("Shown\nkeyboard size: %dpx", keyboardSize));
}
@Override
public void onKeyboardClosed() {
textView.setText("Closed");
}
}
}
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -16,7 +15,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<requestFocus/>
<requestFocus />
</EditText>
<TextView
@@ -25,14 +24,13 @@
android:layout_marginTop="16dp"
android:gravity="center"
android:text="Keyboard state"
android:textSize="24sp"/>
android:textSize="24sp" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:textStyle="bold"
/>
</LinearLayout>
android:textStyle="bold" />
</LinearLayout>

0 comments on commit b4436b9

Please sign in to comment.