真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Android項(xiàng)目:輸入法軟鍵盤顯示/隱藏的監(jiān)聽和控制,InputMethodManager用法研究

    在項(xiàng)目開發(fā)中,用到編輯框的地方經(jīng)常涉及到要監(jiān)聽或者控制軟鍵盤的顯示/隱藏狀態(tài)。本以為這是很容易解決的一個(gè)小問題,沒想到當(dāng)初碰到這個(gè)問題才明白還得花點(diǎn)小心思才能整好?,F(xiàn)將針對(duì)軟鍵盤的顯示/隱藏狀態(tài)的監(jiān)聽/監(jiān)控方法做一些總結(jié),以備后用。

10年積累的成都網(wǎng)站建設(shè)、成都網(wǎng)站制作經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有紅崗免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

一、點(diǎn)擊空白處隱藏軟鍵盤

這是具有編輯框焦點(diǎn)的頁面對(duì)輸入法軟鍵盤狀態(tài)監(jiān)聽的一般需求和解決方法.

首先獲得InputMethodManager:

       InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

監(jiān)聽點(diǎn)擊:

    /**
     * 點(diǎn)擊監(jiān)聽
     */
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        onHideSoftInput(event);
        return super.onTouchEvent(event);
    }
    
    /**
     * 點(diǎn)擊空白處,關(guān)閉輸入法軟鍵盤
     */
    public void onHideSoftInput(MotionEvent event)
    {
        if (event.getAction() == MotionEvent.ACTION_DOWN)
        {
            if (getCurrentFocus() != null && getCurrentFocus().getWindowToken() != null)
            {
                manager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
        }
    }

二、popwindow與輸入法軟鍵盤的結(jié)合

    先說下自己想實(shí)現(xiàn)的效果:點(diǎn)擊頂部按鈕,打開編輯菜單popwindow并自動(dòng)彈出軟鍵盤;再次點(diǎn)擊頂部按鈕,或者點(diǎn)擊編輯菜單popwindow上面的底部按鈕,關(guān)閉菜單并隱藏軟鍵盤;菜單打開狀態(tài),點(diǎn)擊返回鍵,若菜單已顯示先關(guān)閉軟鍵盤,再點(diǎn)擊則關(guān)閉菜單。

    大致效果圖如下:

Android項(xiàng)目:輸入法軟鍵盤顯示/隱藏的監(jiān)聽和控制,InputMethodManager用法研究

1.重寫根布局,監(jiān)聽根布局高度變化

對(duì)于這個(gè)需求,簡單的用上面第一點(diǎn)的方法是無效的。這里沒法直接通過getCurrentFocus()方法判斷頁面是否獲取焦點(diǎn)來控制,需要通過對(duì)popwindow的高度變化進(jìn)行判斷。同時(shí)也試過下面的方法,同樣無效。

InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
boolean isOpen=imm.isActive();//isOpen若返回true,則表示輸入法打開

    popwindow的根布局我這里用的是RelativeLayout,RelativeLayout類可以通過重寫onSizeChanged方法來監(jiān)聽布局大小變化。重寫一個(gè)RelativeLayout類便實(shí)現(xiàn)了對(duì)popwindow的高度變化的監(jiān)聽了。

代碼如下:

/**
 * 監(jiān)聽輸入法軟鍵盤顯示狀態(tài)的自定義RelativeLayout
 * 
 * @author zeng
 * 
 */
public class ResizeRelativeLayout extends RelativeLayout
{
    
    public ResizeRelativeLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }
    
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);
        if (mListener != null)
        {
            mListener.OnResizeRelative(w, h, oldw, oldh);
        }
    }
    
    // 監(jiān)聽接口
    private OnResizeRelativeListener mListener;
    
    public interface OnResizeRelativeListener
    {
        void OnResizeRelative(int w, int h, int oldw, int oldh);
    }
    
    public void setOnResizeRelativeListener(OnResizeRelativeListener l)
    {
        mListener = l;
    }
    
}

2.配置布局文件,初始化UI等,代碼如下:

初始化UI代碼:

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        initUI();
    }

    private void initUI()
    {
        mBtn_open = findViewById(R.id.button1);
        mBtn_open.setOnClickListener(this);
        
        // 編輯窗口
        LayoutInflater inflater = getLayoutInflater();
        View menuLayout = inflater.inflate(R.layout.menu_window, null);
        
        mEditMenuWindow = new PopupWindow(menuLayout, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, true);
        mEditMenuWindow.setBackgroundDrawable(getResources().getDrawable(R.color.white));
        mEditMenuWindow.setTouchable(true);
        mEditMenuWindow.setFocusable(true);
        mEditMenuWindow.setAnimationStyle(R.style.MenuAnimation);
        mEditMenuWindow.setOutsideTouchable(false);
        mEditMenuWindow.update();
        //監(jiān)聽菜單消失
        mEditMenuWindow.setOnDismissListener(this);
        
        
        // 菜單控件
        mEt_menu = (EditText) menuLayout.findViewById(R.id.menu_edit);
        TextView btn_send = (TextView) menuLayout.findViewById(R.id.menu_send);
        btn_send.setOnClickListener(this);
        
        
        // 監(jiān)聽主布局大小變化,監(jiān)控輸入法軟鍵盤狀態(tài)
        listenerKeyBoardState(menuLayout);
    }

其中menu_window.xml文件代碼如下:




    

        
    

    


3.打開或關(guān)閉編輯窗口,同時(shí)自動(dòng)顯示或隱藏輸入法軟鍵盤。

  此方法兩者的控制順序:先顯示軟鍵盤,再打開編輯窗口;先關(guān)閉編輯窗口,若軟鍵盤當(dāng)前已顯示則再隱藏軟鍵盤。代碼如下:

    //點(diǎn)擊頂部發(fā)送按鈕,打開/關(guān)閉編輯窗口
    private void clickTopSend()
    {
        if (mEditMenuWindow.isShowing())
        {
            //先關(guān)閉窗口再隱藏軟鍵盤
            mEditMenuWindow.dismiss();
            
            // 隱藏輸入法軟鍵盤
//            hideKeyBoard();
        }
        else
        {
            // 窗口顯示前顯示輸入法軟鍵盤
            showKeyBoard();
            
            // 顯示輸入窗口
            mEditMenuWindow.showAsDropDown(mBtn_open, 0, 0);
        }
    }

    
    // 窗口顯示前顯示輸入法軟鍵盤
    private void showKeyBoard()
    {
        InputMethodManager inputMgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);// 調(diào)用此方法才能自動(dòng)打開輸入法軟鍵盤
        mEditMenuWindow.setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        mEditMenuWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); // 在顯示popupwindow之后調(diào)用,否則輸入法會(huì)在窗口底層
    }
    
    // 隱藏輸入法軟鍵盤
    private void hideKeyBoard()
    {
        InputMethodManager inputMgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMgr.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS, 0);// 輸入法軟鍵盤打開時(shí)關(guān)閉,關(guān)閉時(shí)打開
        mEditMenuWindow.setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        mEditMenuWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); // 在顯示popupwindow之后調(diào)用,否則輸入法會(huì)在窗口底層

        //此方法無效
        //        if(this.getCurrentFocus().getWindowToken() != null)
//        {
//            ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(),
//                    InputMethodManager.HIDE_NOT_ALWAYS);// 關(guān)閉輸入法軟鍵盤
//        }
        
    }

    
    //點(diǎn)擊底部發(fā)送按鈕,關(guān)閉編輯窗口
    private void closeButtomSend()
    {
        mEditMenuWindow.dismiss();        
    }

    //編輯窗口關(guān)閉時(shí),隱藏輸入法軟鍵盤
    @Override
    public void onDismiss()
    {
        // 如果軟鍵盤打開,隱藏輸入法軟鍵盤
        if(mIsKeyboardOpened)
        {
            hideKeyBoard();
        }
    }

4.判斷軟鍵盤的顯示/隱藏狀態(tài)。

  通過對(duì)編輯窗口的根布局高度變化來判斷軟鍵盤是否處于顯示狀態(tài),在接口方法OnResizeRelative(int w, int h, int oldw, int oldh)里實(shí)現(xiàn)對(duì)高度變化的判斷。這里主要判斷以下幾種高度變化場景:

(1)布局的當(dāng)前高度小于上一次的高度,即h < oldh,因?yàn)椴季直卉涙I盤頂上去了,高度變小了。這種場景同樣適用于點(diǎn)擊按鈕第一次打開窗口時(shí)的場景,雖然點(diǎn)擊按鈕時(shí),肉眼看到的是窗口一下就充滿了大半個(gè)屏幕,也就是當(dāng)前h > oldh(oldh = 0)。但事實(shí)上是,第一次打開窗口時(shí),窗口菜單首先是充滿整個(gè)屏幕然后再根據(jù)軟鍵盤高度自動(dòng)縮進(jìn)的。以下是點(diǎn)擊【打開/發(fā)送】按鈕后,根布局的高度變化日志:

Android項(xiàng)目:輸入法軟鍵盤顯示/隱藏的監(jiān)聽和控制,InputMethodManager用法研究

可以看出,首次打開時(shí),窗口高度先是1038,然后自動(dòng)縮進(jìn)成544,并非一打開便已計(jì)算好填充高度。

(2)還有一種特殊情況,就是三星輸入法在軟鍵盤初次打開時(shí),輸入字符后軟鍵盤高度會(huì)產(chǎn)生變化,同時(shí)造成根布局高度變??;若再清除已輸入的字符,此時(shí)軟鍵盤高度變小,根布局高度變大。而這兩種情況下,也就是h < oldh 或者 h > oldh時(shí),軟鍵盤都是處于顯示狀態(tài)。

Android項(xiàng)目:輸入法軟鍵盤顯示/隱藏的監(jiān)聽和控制,InputMethodManager用法研究

針對(duì)這種情況,我的解決方法是記錄下初次打開時(shí)根布局的初始高度值,由于h < oldh時(shí)在第(1)步已經(jīng)進(jìn)行了判斷了,所以這里只要判斷 h > oldh時(shí)的情況。而無論 h > oldh變化多大,只要h不超過初始高度值(且初始高度值不為0),那么便可認(rèn)為當(dāng)前軟鍵盤仍是處于打開狀態(tài)。

此方法運(yùn)行后的日志如下:

Android項(xiàng)目:輸入法軟鍵盤顯示/隱藏的監(jiān)聽和控制,InputMethodManager用法研究

兩種狀況下,軟鍵盤都是顯示狀態(tài)。

以下是監(jiān)聽高度變化判斷的代碼:

    /**
     * 監(jiān)聽主布局大小變化,監(jiān)控輸入法軟鍵盤狀態(tài)
     * @param menuLayout
     */
    private void listenerKeyBoardState(View menuLayout)
    {
        ResizeRelativeLayout mMenuLayout = (ResizeRelativeLayout) menuLayout.findViewById(R.id.menu_layout);
        mMenuLayout.setOnResizeRelativeListener(new ResizeRelativeLayout.OnResizeRelativeListener()
        {
            @Override
            public void OnResizeRelative(int w, int h, int oldw, int oldh)
            {
                mIsKeyboardOpened = false;
                Log.e("菜單高度", "h = " + h + ",oldh = " + oldh);
                
                //記錄第一次打開輸入法時(shí)的布局高度
                if (h < oldh &&  oldh > 0 && mMenuOpenedHeight == 0)
                {
                    mMenuOpenedHeight = h;
                }
                
                // 布局的高度小于之前的高度
                if (h < oldh )
                {
                    mIsKeyboardOpened = true;
                }
                //或者輸入法打開情況下, 輸入字符后再清除(三星輸入法軟鍵盤在輸入后,軟鍵盤高度增加一行,清除輸入后,高度變小,但是軟鍵盤仍是打開狀態(tài))
                else if((h <= mMenuOpenedHeight) && (mMenuOpenedHeight != 0))
                {
                    mIsKeyboardOpened = true;
                }

                Log.e("是否打開", "軟鍵盤  = " + mIsKeyboardOpened);
            }
        });
    }

最后附上DEMO源碼,詳見附件。

三、InputMethodManager的一些相關(guān)方法(未有效使用過,僅作筆記)

1.調(diào)用顯示系統(tǒng)默認(rèn)的輸入法

方法一、

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

imm.showSoftInput(m_receiverView,InputMethodManager.SHOW_FORCED);

m_receiverView(接受軟鍵盤輸入的視圖(View)

InputMethodManager.SHOW_FORCED(提供當(dāng)前操作的標(biāo)記,SHOW_FORCED表示強(qiáng)制顯示)

方法二、

InputMethodManager m=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
m.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);

這個(gè)InputMethodManager類里面的toggleSoftInput方法的API中的解釋是:

This method toggles the input method window display. If the input window is already displayed, it gets hidden. If not the input window will be displayed.

這個(gè)方法在界面上切換輸入法的功能,如果輸入法出于現(xiàn)實(shí)狀態(tài),就將他隱藏,如果處于隱藏狀態(tài),就顯示輸入法。

2.調(diào)用隱藏系統(tǒng)默認(rèn)的輸入法

((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(WidgetSearchActivity.this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

(WidgetSearchActivity是當(dāng)前的Activity)

3.獲取輸入法打開的狀態(tài)

InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
boolean isOpen=imm.isActive();

isOpen若返回true,則表示輸入法打開

四、SoftInputMode輸入法軟鍵盤模式相關(guān)說明

輸入法軟鍵盤模式選項(xiàng):

public int softInputMode;

以下與輸入法模式有關(guān)的各選項(xiàng)說明:

軟輸入?yún)^(qū)域是否可見。

public static final int SOFT_INPUT_MASK_STATE = 0x0f;

未指定狀態(tài)。

public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0;

不要修改軟輸入法區(qū)域的狀態(tài)。

public static final int SOFT_INPUT_STATE_UNCHANGED = 1;

隱藏輸入法區(qū)域(當(dāng)用戶進(jìn)入窗口時(shí))。

public static final int SOFT_INPUT_STATE_HIDDEN = 2;

當(dāng)窗口獲得焦點(diǎn)時(shí),隱藏輸入法區(qū)域。

public static final int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3;

顯示輸入法區(qū)域(當(dāng)用戶進(jìn)入窗口時(shí))。

public static final int SOFT_INPUT_STATE_VISIBLE = 4;

當(dāng)窗口獲得焦點(diǎn)時(shí),顯示輸入法區(qū)域。

public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5;

窗口應(yīng)當(dāng)主動(dòng)調(diào)整,以適應(yīng)軟輸入窗口。

public static final int SOFT_INPUT_MASK_ADJUST = 0xf0;

未指定狀態(tài),系統(tǒng)將根據(jù)窗口內(nèi)容嘗試選擇一個(gè)輸入法樣式。

public static final int SOFT_INPUT_ADJUST_UNSPECIFIED = 0x00;

當(dāng)輸入法顯示時(shí),允許窗口重新計(jì)算尺寸,使內(nèi)容不被輸入法所覆蓋。

不可與SOFT_INPUT_ADJUSP_PAN混合使用;如果兩個(gè)都沒有設(shè)置,系統(tǒng)將根據(jù)窗口內(nèi)容自動(dòng)設(shè)置一個(gè)選項(xiàng)。

public static final int SOFT_INPUT_ADJUST_RESIZE = 0x10;

輸入法顯示時(shí)平移窗口。它不需要處理尺寸變化,框架能夠移動(dòng)窗口以確保輸入焦點(diǎn)可見。

不可與SOFT_INPUT_ADJUST_RESIZE混合使用;如果兩個(gè)都沒有設(shè)置,系統(tǒng)將根據(jù)窗口內(nèi)容自動(dòng)設(shè)置一個(gè)選項(xiàng)。

public static final int SOFT_INPUT_ADJUST_PAN = 0x20;

當(dāng)用戶轉(zhuǎn)至此窗口時(shí),由系統(tǒng)自動(dòng)設(shè)置,所以你不要設(shè)置它。

當(dāng)窗口顯示之后該標(biāo)志自動(dòng)清除。

public static final int SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100;


本文名稱:Android項(xiàng)目:輸入法軟鍵盤顯示/隱藏的監(jiān)聽和控制,InputMethodManager用法研究
本文URL:http://weahome.cn/article/jsdojo.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部