之前把预备知识都介绍完了,话说学以致用,接下来我们要通过重载LinearLayout类来解决软键盘覆盖的问题。
首先阐述一下这个问题,如下图所示:
然后看挡住输入框的情况
然后我们给出xml的源代码:
<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"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="6"
android:background="#ff0000"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/login_title" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:layout_weight="3"
android:orientation="vertical" >
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_alignParentBottom="true"
android:layout_gravity="center_vertical"
android:hint="用户名"
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_alignParentBottom="true"
android:layout_gravity="center_vertical"
android:hint="用户名"
android:ems="10" >
<requestFocus />
</EditText>
</LinearLayout>
</LinearLayout>
虽然我知道,看代码是多么让人蛋。疼的事情,但请大家还是忍住对我的菊,花猛踹一脚的愤怒看一下我辛辛苦苦垒的代码吧。
这个层次其实一点都不复杂就是外面一层linearlayout,他内部包含两个linearlayout,这是再正常不过的登录界面了:上面是logo,下面是用户名,密码输入框。困扰大家的问题就是弹出来的软键盘会遮挡输入框。这个比iOS的烦人多了,iOS解决这类问题还是比较简单的,直接代码搞定就可以了。
现在讲一下通常的解决方案就是:监听键盘弹出,然后隐藏上面的logo,然后自然而然的下面的也就顶上去了。怎么实现呢,我们只要写一个类继承自LinearLayout即可。
我们写一个类:LinearLayoutView.java 源代码如下:
package com.example.overidelinearlayout;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.LinearLayout;
public class LinearLayoutView extends LinearLayout{
public static final int KEYBORAD_HIDE = 0;
public static final int KEYBORAD_SHOW = 1;
private static final int SOFTKEYPAD_MIN_HEIGHT = 50;
private Handler uiHandler = new Handler();
public LinearLayoutView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public LinearLayoutView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void onSizeChanged(int w,final int h, int oldw,final int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
uiHandler.post(new Runnable() {
@Override
public void run() {
if (oldh - h > SOFTKEYPAD_MIN_HEIGHT){
Log.e("lp", "up");
System.out.println("弹起");
keyBordStateListener.stateChange(KEYBORAD_SHOW);
}
else {
System.out.println("隐藏");
Log.e("lp", "down");
if(keyBordStateListener != null){
keyBordStateListener.stateChange(KEYBORAD_HIDE);
}
}
}
});
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private KeyBordStateListener keyBordStateListener;
public void setKeyBordStateListener(KeyBordStateListener keyBordStateListener) {
this.keyBordStateListener = keyBordStateListener;
}
public interface KeyBordStateListener{
public void stateChange(int state);
}
}
然后我们把xml最上层的linearlayout改为LinearLayoutView即可,然后给他们加上id,更新后的xml如下:
<com.example.overidelinearlayout.LinearLayoutView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="@+id/login_root_layout"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/login_layout_logo"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="6"
android:background="#ff0000"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/login_title" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:layout_weight="3"
android:orientation="vertical" >
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_alignParentBottom="true"
android:layout_gravity="center_vertical"
android:hint="用户名"
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_alignParentBottom="true"
android:layout_gravity="center_vertical"
android:hint="用户名"
android:ems="10" >
<requestFocus />
</EditText>
</LinearLayout>
</com.example.overidelinearlayout.LinearLayoutView>
然后我们再写MainActivity里面的代码:
package com.example.overidelinearlayout;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import com.example.overidelinearlayout.LinearLayoutView.KeyBordStateListener;
public class MainActivity extends Activity implements KeyBordStateListener {
private LinearLayoutView resizeLayout;
private LinearLayout logoLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resizeLayout = (LinearLayoutView) findViewById(R.id.login_root_layout);
logoLayout = (LinearLayout) findViewById(R.id.login_layout_logo);
resizeLayout.setKeyBordStateListener(this);
}
@Override
public void stateChange(int state) {
// TODO Auto-generated method stub
switch (state) {
case LinearLayoutView.KEYBORAD_HIDE:
logoLayout.setVisibility(View.VISIBLE);
break;
case LinearLayoutView.KEYBORAD_SHOW:
logoLayout.setVisibility(View.GONE);
break;
}
}
}
最后别忘了在manifest中这样写:
<activity
android:name="com.example.overidelinearlayout.MainActivity"
android:windowSoftInputMode="adjustResize" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
最后看一下效果吧:
搞定收工!
最后附上源代码:源代码在此,请猛戳!(虽然本来不想给的,省得大家都不懂脑筋,但回头想想又不忍心,毕竟本人也经历过到处看教程却苦于没代码的岁月。被项目压着的日子不好过啊!!!看着嗷嗷待哺的诸位着实有点于心不忍)