基于dialog的可移动的自定义键盘

      因为android原生键盘很大,当键盘显示的时候,会遮住大部分的界面,有时候还会使界面移动(当Edittext在界面偏底部的时候),所以项目需要使用自定义键盘,看了系统源码,发现android原生键盘使用的是dialog构建键盘,所以决定用dialog,思路是这样:
      1.建一个键盘的layout(keyboard.xml),自定义一个单例模式的dialog(keyboard.java),使用R.layout.keyboard作为layout,设置dialog不获取焦点:
           getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
keyboard.xml:
	
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:localdefine = "http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/compoment_sharp_grey_grey1"
    android:padding="10px"
    >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="密码输入"
        android:textColor="@color/clr_black"
        android:id="@+id/id_title"
        android:visibility="gone"
        android:gravity="center"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="范围(无)"
        android:textSize="20sp"
        android:textColor="@color/clr_black"
        android:id="@+id/id_range"
        android:gravity="center"/>
    <LinearLayout
        android:layout_marginTop="10px"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    <Button
        style="@style/keypad_fun"
        android:text="@string/common_clear"
        android:id = "@+id/id_clear"
        android:background="@drawable/button_style_light"/>
    <Button
        style="@style/keypad_fun"
        android:text="@string/common_close"
        android:id = "@+id/id_close"
        android:layout_marginLeft="10px"
        android:background="@drawable/button_style_light"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10px"
        android:orientation="horizontal">
        <Button
            style="@style/keypad_num"
            android:text="7"
            android:id = "@+id/id_seven" />
        <Button
            style="@style/keypad_num"
            android:text="8"
            android:id = "@+id/id_eight"
            android:layout_marginLeft="10px" />
        <Button
            style="@style/keypad_num"
            android:text="9"
            android:id = "@+id/id_nigh"
            android:layout_marginLeft="10px"
            android:background="@drawable/button_style_light"/>
        <com.tomra.trsort.ui.view.LocalButton
            style="@style/keypad_num"
            android:layout_marginLeft="10px"
            android:id = "@+id/id_delete"
            localdefine:drawableUp="@drawable/back_delete"
            android:background="@drawable/button_style_light"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10px"
        android:orientation="horizontal">
        <Button
            style="@style/keypad_num"
            android:text="4"
            android:id = "@+id/id_four"
            android:background="@drawable/button_style_light"/>
        <Button
            style="@style/keypad_num"
            android:text="5"
            android:id = "@+id/id_five"
            android:layout_marginLeft="10px"
            android:background="@drawable/button_style_light"/>
        <Button
            style="@style/keypad_num"
            android:text="6"
            android:id = "@+id/id_six"
            android:layout_marginLeft="10px"
            android:background="@drawable/button_style_light"/>
        <Button
            style="@style/keypad_num"
            android:text="."
            android:id = "@+id/id_dot"
            android:layout_marginLeft="10px"
            android:background="@drawable/button_style_light"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10px"
        android:orientation="horizontal">
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                <Button
                    style="@style/keypad_num"
                    android:text="1"
                    android:id = "@+id/id_one"
                    android:background="@drawable/button_style_light"/>
                <Button
                    style="@style/keypad_num"
                    android:text="2"
                    android:id = "@+id/id_two"
                    android:layout_marginLeft="10px"
                    android:background="@drawable/button_style_light"/>
                <Button
                    style="@style/keypad_num"
                    android:text="3"
                    android:id = "@+id/id_three"
                    android:layout_marginLeft="10px"
                    android:background="@drawable/button_style_light"/>
            </LinearLayout>
            <Button
                style="@style/keypad_num1"
                android:text="0"
                android:id = "@+id/id_zero"
                android:layout_marginTop ="10px"
                android:background="@drawable/button_style_light"/>
        </LinearLayout>
        <Button
            style="@style/keypad_fun1"
            android:text="@string/dialog_open_btn_open"
            android:id = "@+id/id_ok"
            android:layout_marginLeft="10px"
            android:background="@drawable/button_style_light"/>
    </LinearLayout>


</LinearLayout>

自定义dialog代码:
 
 
public class Keyboard extends Dialog implements View.OnClickListener{
    private static KeyboardEditText mClientView;
    private Context mContext;
    private View mView;
    private float mX,mY;
    private static Keyboard mKeyboard;
    private TextView mTvTitle;
    private String mTitle = "Input";
    private Button mBtnClose;
    private boolean mIsClose = true;
    private TextView mTvRange;
    public static Keyboard getInstance(Context context,KeyboardEditText view)
    {
        if(mKeyboard == null)
        {
            mKeyboard = new Keyboard(context,view);
        }
        if(mClientView != null)
            mClientView.setSelected(false);
        mClientView = view;
        mClientView.setSelected(true);
        return mKeyboard;
    }

    public void setView(KeyboardEditText view)
    {
        if(mClientView != null)
            mClientView.setSelected(false);
        mClientView = view;
        mClientView.setSelected(true);
        KeyboardEditText next = mClientView.getNextEditText(true);
        if(mBtnClose != null) {
            if (next != null) {
                mBtnClose.setText(getContext().getString(R.string.common_next));
                mIsClose = false;
            }
            else {
                mBtnClose.setText(getContext().getString(R.string.common_close));
                mIsClose = true;
            }
            int[] rang = new int[2];
            if(mClientView.getRange(rang)) {
                StringBuilder sb = new StringBuilder();
                sb.append(Integer.toString(rang[0]));
                sb.append("~");
                sb.append(rang[1]);
                LogManager.LogEWithTag("KEYKEY", "show rang 0 = "+ rang[0]+" rang 1 = "+rang[1]+ "sb ="+sb.toString());
                mTvRange.setText(String.format(getContext().getString(R.string.common_range),sb.toString()));
            }
            else
                mTvRange.setText(String.format(getContext().getString(R.string.common_range),getContext().getString(R.string.common_none)));

        }
    }
    public Keyboard(Context context,EditText view)
    {
        this(context);

    }
    public Keyboard(Context context) {
        super(context,R.style.Dialog);
    }

    public Keyboard(Context context, int theme) {
        super(context, theme);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        mView = LayoutInflater.from(getContext()).inflate(R.layout.keyboard,null);
        setContentView(mView);
        setCanceledOnTouchOutside(false);
        mBtnClose = ((Button)findViewById(R.id.id_close));
        mBtnClose.setOnClickListener(this);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
        ((Button)findViewById(R.id.id_clear)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_zero)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_one)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_two)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_three)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_four)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_five)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_six)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_seven)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_eight)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_nigh)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_dot)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_ok)).setOnClickListener(this);
        ((Button)findViewById(R.id.id_delete)).setOnClickListener(this);
        mTvTitle = (TextView)findViewById(R.id.id_title);
        mTvTitle.setText(mTitle);
        mTvRange = (TextView)findViewById(R.id.id_range);
        mTvRange.setText(getContext().getString(R.string.common_range));
        //LogManager.LogEWithTag("KEYKEY", "onCreate keypadWidth = "+ mView.getWidth()+" keypadHeight = "+mView.getHeight());
        mView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                //LogManager.LogEWithTag("KEYKEY", "onGlobalLayout keypadWidth = "+ mView.getWidth()+" keypadHeight = "+mView.getHeight());
            }
        });

        KeyboardEditText next = mClientView.getNextEditText(false);
        if(mBtnClose != null) {
            if (next != null) {
                mBtnClose.setText(getContext().getString(R.string.common_next));
                mIsClose = false;
            }
            else {
                mBtnClose.setText(getContext().getString(R.string.common_close));
                mIsClose = true;
            }
        }
        int[] rang = new int[2];
        if(mClientView != null) {
            if (mClientView.getRange(rang)) {

                StringBuilder sb = new StringBuilder();
                sb.append(Integer.toString(rang[0]));
                sb.append("~");
                sb.append(rang[1]);
                LogManager.LogEWithTag("KEYKEY", "show rang 0 = "+ rang[0]+" rang 1 = "+rang[1]+ "sb ="+sb.toString());
                mTvRange.setText(String.format(getContext().getString(R.string.common_range), sb.toString()));
            } else
                mTvRange.setText(String.format(getContext().getString(R.string.common_range), getContext().getString(R.string.common_none)));
        }
    }

    private void reSize()
    {
        Window window = getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.gravity = Gravity.TOP | Gravity.LEFT;
        int[] location = new int[2];
        mClientView.getLocationOnScreen(location);

        // lp.x = location[0];
        // lp.y = location[1];
        // window.setAttributes(lp);
        int[] screenSize = CommonUtil.getScreenSize(getContext());

        int clientViewX = location[0];
        int clientViewY = location[1];

        int clientViewWidth = this.mClientView.getWidth();
        int clientViewHeight = this.mClientView.getHeight();

        int keypadWidth = 290;
         int keypadHeight = 389;

        if(clientViewY + clientViewHeight + keypadHeight <= screenSize[1])
        {
            if(clientViewX + keypadWidth > screenSize[0])
                lp.x = screenSize[0] - keypadWidth;
            else
                lp.x = clientViewX;

            lp.y = clientViewY + clientViewHeight;
        }
        else if(clientViewY >= keypadHeight)
        {
            if(clientViewX + keypadWidth > screenSize[0])
                lp.x = screenSize[0] - keypadWidth;
            else
                lp.x = clientViewX;
            lp.y = clientViewY - keypadHeight;
        }
        else if(clientViewX + clientViewWidth + keypadWidth <= screenSize[0])
        {
            lp.x = clientViewX + clientViewWidth;
            int delta = Math.abs((clientViewHeight - keypadHeight)/2);
            if(clientViewHeight > keypadHeight)
            {
                lp.y = clientViewY + delta;
            }
            else
            {
                lp.y = clientViewY - delta;
            }
        }
        else
        {
            lp.x = (screenSize[0] - keypadWidth)/2;
            lp.y = (screenSize[1] - keypadHeight)/2;
        }

       window.setAttributes(lp);
    }


    @Override
    public void show() {


        super.show();
        reSize();
        mClientView.setSelected(true);
    }

    public void setTitle(String str)
    {
        if(this.mTvTitle != null)
        {
            this.mTvTitle.setText(str);
        }
        this.mTitle = str;
    }

    @Override
    public void dismiss() {
        super.dismiss();
        mClientView.setSelected(false);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        Window window = getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.x = (int)mClientView.getX();
        lp.y = (int)mClientView.getY();
        window.setAttributes(lp);


    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {


        if(event.getAction() == MotionEvent.ACTION_DOWN)
        {
            mX = event.getRawX();
            mY = event.getRawY();
            if(mX < 0f || mY < 0)
            {
                WindowManager.LayoutParams ll =  getWindow().getAttributes();
                ll.x += (int)mX;
                ll.y += (int)mY;
                getWindow().setAttributes(ll);
            }
        }
        else if(event.getAction() == MotionEvent.ACTION_MOVE)
        {
            float deltaX = event.getRawX() - mX;
            float deltaY = event.getRawY() - mY;
            mX = event.getRawX();
            mY = event.getRawY();
            WindowManager.LayoutParams ll =  getWindow().getAttributes();
            ll.x += (int)deltaX;
            ll.y += (int)deltaY;
            getWindow().setAttributes(ll);
        }

        return super.onTouchEvent(event);
    }


    @Override
    public void onClick(View view) {
        switch(view.getId())
        {
            case R.id.id_close:
                if(mIsClose)
                    dismiss();
                else
                    setView(mClientView.getNextEditText(false));
                break;
            case R.id.id_clear:
                this.mClientView.setText("");
                break;
            case R.id.id_one:
                this.mClientView.selectAll();
                this.mClientView.setText(this.mClientView.getText().toString()+"1");
                break;
            case R.id.id_two:
                this.mClientView.setText(this.mClientView.getText().toString()+"2");
                break;
            case R.id.id_three:
                this.mClientView.setText(this.mClientView.getText().toString()+"3");
                break;
            case R.id.id_four:
                this.mClientView.setText(this.mClientView.getText().toString()+"4");
                break;
            case R.id.id_five:
                this.mClientView.setText(this.mClientView.getText().toString()+"5");
                break;
            case R.id.id_six:
                this.mClientView.setText(this.mClientView.getText().toString()+"6");
                break;
            case R.id.id_seven:
                this.mClientView.setText(this.mClientView.getText().toString()+"7");
                break;
            case R.id.id_eight:
                this.mClientView.setText(this.mClientView.getText().toString()+"8");
                break;
            case R.id.id_nigh:
                this.mClientView.setText(this.mClientView.getText().toString()+"9");
                break;
            case R.id.id_zero:
                this.mClientView.setText(this.mClientView.getText().toString()+"0");
                break;
            case R.id.id_dot:
                if(mClientView.getInputType() == EditorInfo.TYPE_CLASS_NUMBER )
                    break;
                this.mClientView.setText(this.mClientView.getText().toString()+".");
                break;
            case R.id.id_delete:
                String str = this.mClientView.getText().toString();
                if(str == null || str.equals(""))
                    break;
                int lengh = str.length();
                String newStr = str.substring(0,lengh - 1);
                this.mClientView.setText(newStr);
                break;
            case R.id.id_ok:
                dismiss();
                break;
        }
    }

}

      2.自定义Edittext,设置为InputType. TYPE_NULL类型,不使用系统键盘。

      3.重写Edittext的onTouchEvent方法,收到MotionEvent.ACTION_UP的时候,获取自定义键盘单例,显示,把对应的Edittext传给键盘,以便操作的时候更新:
@Override
    public boolean onTouchEvent(MotionEvent event) {
        if(!this.isEnabled())
            return super.onTouchEvent(event);
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                LogManager.LogEWithTag("KEYKEY", "ACTION_DOWN = ");
                requestFocus();
                requestFocusFromTouch();
                break;
            case MotionEvent.ACTION_UP:
                mKeyboard = Keyboard.getInstance(getContext(),this);
                mKeyboard.setView(this);
                if(!mKeyboard.isShowing()) {


                    mKeyboard.show();
                }
                break;
        }
        return super.onTouchEvent(event);
    }





                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值