仿微信朋友圈回覆資訊-點選空白處軟鍵盤以及回覆佈局消失
開啟微信朋友圈,點選回覆按鈕,會立馬跳出一個回覆欄和一個軟鍵盤,點選其他空白處這2個又消失了。這種功能我們怎麼實現呢?
類似下面這種功能,由於用的是夜神模擬器,沒有軟鍵盤,大家可以自行腦補,或者去自己的朋友圈看看效果。
思路是這樣的:點選這個回覆狀態列以外的其他區域,讓這個回覆欄目GONE掉,軟鍵盤沒關閉的話,把它關了。
這就涉及到了2個知識點:1、觸屏事件分發機制;
2、得到某個View在螢幕上的位置。
Activity中有2個觸屏事件分發的相關方法:dispatchTouchEvent()和onTouchEven()。
dispatchTouchEvent()是用來分發事件的,onTouchEven()是用來消費事件的。
一般的事件生命週期是這樣的:
1、Activity的dispatchTouchEvent()傳遞給ViewGrouop的dispatchTouchEvent()
2、ViewGrouop的dispatchTouchEvent()傳遞給ViewGrouop的onInterceptTouchEven();
3、ViewGrouop的onInterceptTouchEven()判斷是否攔截事件,不攔截事件的話分發給ChildView(子View);
4、子View的dispatchTouchEvent()判斷子
我們這是在Activity中點選,所以考慮是用Activity的dispatchTouchEvent()還是onTouchEven()。
onTouchEven()是子View以及ViewGroup都不消費事件的時候,傳遞迴Activity才會觸發的。若是使用者點到了有點選事件的東西(比如上個動圖的搜尋按鈕、回覆按鈕、返回按鈕),那麼這個事件就被消費了。Activity就沒辦法得到這個觸控事件了。所以我們要在Activity的dispatchTouchEvent()方法中做這些邏輯。
然後下面程式碼說的是如何判斷點選的是回覆欄之外的區域。用到的是getLocationInWindow這個方法。
可能有人會問為什麼不用getLoacationOnScreen(),對於這個專案而言,這個回覆欄的父佈局就是最外層的Layout,所以用哪個都是一樣的。
這裡普及下知識:
int[] location = new int[2] ; view.getLocationInWindow(location); //獲取在當前視窗內的絕對座標 view.getLocationOnScreen(location); //獲取在整個螢幕內的絕對座標 location [0]--->x座標 location [1]--->y座標 public boolean isShouldHideInput(View v, MotionEvent event)
{
if (v != null && (v instanceof RelativeLayout))//這個view就是我們回覆欄的佈局
{
int[] leftTop = new int[2];
v.getLocationInWindow(leftTop);
int left = leftTop[0];//回覆欄左上角x軸座標
int top = leftTop[1];//回覆欄左上角y軸座標
int bottom = top + v.getHeight();//回覆欄右下角x軸座標
int right = left + v.getWidth();//回覆欄右下角y軸座標
if (event.getX() > left && event.getX() < right
&& event.getY() > top && event.getY() < bottom) return false;
else return true;
}
return false;
}
最後我們就重寫dispatchTouchEvent(),然後當這個回覆欄可見,觸控事件是按下,且當前觸控點在這個回覆欄之外的時候,執行下面的程式碼,回覆欄GONE掉,軟鍵盤關閉。
@Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
if (rl_bottom.getVisibility() == View.VISIBLE && ev.getAction() == MotionEvent.ACTION_DOWN && isShouldHideInput(rl_bottom, ev))
{
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null)
{
rl_bottom.setVisibility(View.GONE);
imm.hideSoftInputFromWindow(rl_bottom.getWindowToken(), 0);
}
}
return super.dispatchTouchEvent(ev);
}
然後到這裡大家已經懂了吧