之前把预备知识都介绍完了,话说学以致用,接下来我们要通过重载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>
最后看一下效果吧:
搞定收工!
最后附上源代码:源代码在此,请猛戳!(虽然本来不想给的,省得大家都不懂脑筋,但回头想想又不忍心,毕竟本人也经历过到处看教程却苦于没代码的岁月。被项目压着的日子不好过啊!!!看着嗷嗷待哺的诸位着实有点于心不忍)
LinearLayout详解四:彻底解决软键盘遮挡输入框的问题
时间: 2024-10-12 14:31:38