让我来详细讲解一下“Android UI设计系列之自定义ViewGroup打造通用的关闭键盘小控件ImeObserverLayout(9)”的完整攻略。
简介
本篇攻略主要是讲解如何自定义ViewGroup来实现通用的关闭键盘小控件ImeObserverLayout。通过本文的学习,你将会了解到如何使用较少的代码实现一个通用的小控件,并掌握自定义ViewGroup的基本知识。
步骤
本篇攻略的步骤分为以下几个部分:
- 准备工作
- 继承RelativeLayout实现ImeObserverLayout
- 布局设计
- 代码实现
- 示例演示
1. 准备工作
在开始之前,我们需要了解一下自定义ViewGroup的基本概念和使用方法。可以先去查看一下官方文档,了解一下相关知识。
2. 继承RelativeLayout实现ImeObserverLayout
在这里,我们使用RelativeLayout作为基类,继承它来实现我们的ImeObserverLayout。
public class ImeObserverLayout extends RelativeLayout {
public ImeObserverLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
...
}
3. 布局设计
我们的布局需要包含两部分,一部分是要使用该控件的页面布局,另一部分则是一个用于拦截弹出键盘事件的view。
<com.example.ImeObserverLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/input_holder">
<!-- 布局代码 -->
<com.example.ImeObserverLayout.ObserveKeyBoardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/observe_keyboard" />
</com.example.ImeObserverLayout>
其中,ObserveKeyBoardView是继承自View的一个自定义类,目的是用来拦截并消费弹出键盘的事件。
4. 代码实现
在这里,我们需要实现一些方法,来监听键盘的弹出与隐藏事件,并根据这些事件来进行相应的操作。在这里,我写了五个方法,分别是onTouchEvent、onInterceptTouchEvent、onSizeChanged、dispatchKeyEvent和onLayout。这些方法具体实现可以参见完整的代码,这里不再赘述。
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (isShown()) {
hideIme();
}
}
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (isInputMethodActive(getContext())) {
hideIme();
}
}
return super.onInterceptTouchEvent(ev);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (w == oldw && h == oldh) {
return;
}
if (oldh > h) {
if (isInputMethodActive(getContext())) {
hideIme();
}
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
if (isInputMethodActive(getContext())) {
hideIme();
return true;
}
}
return super.dispatchKeyEvent(event);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (changed) {
hideIme();
}
}
public static boolean isInputMethodActive(Context context) {
InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputMethodManager != null) {
return inputMethodManager.isActive();
}
return false;
}
public void hideIme() {
InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputMethodManager != null) {
inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
}
}
5. 示例演示
在代码实现完成之后,我们需要进行示例演示,来验证我们的代码是否能够正常工作。以下是两个简单的示例:
示例一
在这个示例中,我们使用ImeObserverLayout来包裹一个EditText,并且在xml中直接设置android:focusable="true" 和android:focusableInTouchMode="true"属性。
<com.example.ImeObserverLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/input_holder">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/input_area"
android:hint="@string/input_hint"
android:inputType="text"
android:focusable="true"
android:focusableInTouchMode="true"/>
<com.example.ImeObserverLayout.ObserveKeyBoardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/observe_keyboard" />
</com.example.ImeObserverLayout>
在代码中,我们需要找到input_holder和observe_keyboard两个view,并设置ImeObserverLayout。代码如下:
ImeObserverLayout container = findViewById(R.id.input_holder);
ImeObserverLayout.ObserveKeyBoardView observerView = findViewById(R.id.observe_keyboard);
container.setListener(() -> Toast.makeText(MainActivity.this, "Keyboard is hidden", Toast.LENGTH_SHORT).show());
observerView.setListener(() -> Toast.makeText(MainActivity.this, "Keyboard is shown", Toast.LENGTH_SHORT).show());
以上代码设置了输入框弹出键盘和关闭键盘的回调方法,并实现Toast的提示。
示例二
在这个示例中,我们使用ScrollView来包裹ImeObserverLayout,并添加一个Button来触发弹出键盘。
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/input_holder">
<com.example.ImeObserverLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/input_holder2">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/btn_show_keyboard"
android:id="@+id/show_keyboard"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/input_area2"
android:hint="@string/input_hint"
android:inputType="text"/>
</LinearLayout>
<com.example.ImeObserverLayout.ObserveKeyBoardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/observe_keyboard2" />
</com.example.ImeObserverLayout>
</ScrollView>
在代码中,我们需要找到show_keyboard并设置点击事件,用于触发键盘弹出,同样实现了弹出键盘和关闭键盘的回调方法。
Button showKeyboardButton = findViewById(R.id.show_keyboard);
showKeyboardButton.setOnClickListener(v -> {
EditText inputArea2 = findViewById(R.id.input_area2);
inputArea2.requestFocus();
InputMethodManager inputMethodManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(inputArea2, InputMethodManager.SHOW_IMPLICIT);
});
ImeObserverLayout container2 = findViewById(R.id.input_holder2);
ImeObserverLayout.ObserveKeyBoardView observerView2 = findViewById(R.id.observe_keyboard2);
container2.setListener(() -> Toast.makeText(MainActivity.this, "Keyboard is hidden", Toast.LENGTH_SHORT).show());
observerView2.setListener(() -> Toast.makeText(MainActivity.this, "Keyboard is shown", Toast.LENGTH_SHORT).show());
总结
通过本篇攻略的学习,我们掌握了如何自定义ViewGroup来实现通用的关闭键盘小控件ImeObserverLayout并学习了自定义VIewGroup的基本知识。我们通过示例的方式来验证代码的正确性,相信你现在已经了解了如何使用自定义ViewGroup来实现一个小控件,希望本篇攻略对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android UI设计系列之自定义ViewGroup打造通用的关闭键盘小控件ImeObserverLayout(9) - Python技术站