1 You can use android:windowSoftInputMode attribute within the <activity>
element in your Manifest.xml
to select amongst various resizing strategies when the IME pops up. These include (not limited to):
adjustResize
, which will resize your Activity's content view (and the WebView in it) to fit the remaining space.
adjustPan
, which will leave the content view to fill the entire screen, partially occluded by the IME's Window.
Playing with these may already give you the behavior you are looking for.
2 Android's default behavior when it comes to scrolling a (Web)View when the IME pops up is that it tries to keep the cursor visible. In your case you are putting your cursor (or: focus) on a hidden view. This explains the weird behavior you are seeing and I think you would do well to change your implementation. Why are you not using a visible textarea in the first place? Your text will have to end up somewhere, right? And then Android will handle the focus/scroll automatically.
As a workaround: something you could try is to position your hidden view smarter and clear its contents from time to time, thereby dodging your scrolling issue. Of course the viability of this option depends on your exact use case.
3 This will be the answer to the question you are asking, but I am unsure how this will help you (maybe because of my inexperience with html):
To get the height of the WebView (which is Screen size - IME height) in your javascript do the following:
- In your manifest, add the
android:windowSoftInputMode="adjustResize"
attribute to your element.
extend your outer layout like this:
public class RelativeLayoutWithLayoutListener extends RelativeLayout {
public interface LayoutListener {
public void onLayout();
}
private LayoutListener mListener;
public RelativeLayoutWithLayoutListener(Context context) {
super(context);
}
public RelativeLayoutWithLayoutListener(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public RelativeLayoutWithLayoutListener(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setLayoutListener(LayoutListener aListener) {
mListener = aListener;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (mListener != null) {
mListener.onLayout();
}
}
}
Swap out your old layout for the newly created one in your layout.xml file.
In your Activity code, do something like this:
public class MainActivity extends Activity {
private RelativeLayoutWithLayoutListener mMainLayout;
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMainLayout = (RelativeLayoutWithLayoutListener)findViewById(R.id.main_layout);
mMainLayout.setLayoutListener(new LayoutListener() {
@Override
public void onLayout() {
mWebView.loadUrl("javascript:setSize(" + mMainLayout.getWidth() + "," + mMainLayout.getHeight() + ")");
}
});
mWebView = (WebView)findViewById(R.id.webview);
}
}
Of course in the loadUrl() call you will have to call a javascript method you defined. You can of course also pass in the height of the IME if you do some calculations first.