keyboard_keyboardinterrupt - CSDN
精华内容
参与话题
  • 
 
 
 
 
 
 
 code小生,一个专注于 Android 领域的技术分享平台作者:Allen___地址:https:...
        

    code小生,一个专注于 Android 领域的技术分享平台

    作者:Allen___
    地址:https://www.jianshu.com/p/d2c6e6e59335
    声明:本文是 Allen___ 原创,转发等请联系原作者授权。

    起因

    各位小伙伴,开发过程中基本都要用到类似支付宝、微信那样自定义支付键盘和自定义输入框。也许,大家能找到一些差不多的类库,但是,自己搞懂逻辑,根据业务更改样式,岂不更爽?

    介绍

    关于这部分,网上有不少的实现方式。我之前有看过几个,有点耦合,不是太喜欢。所以,自己写了个,保证自己这个是完全解耦的,大家看懂即可拿着代码随意定制啦。

    效果

    keyboard.gif

    定制化

    上面是默认样式效果,具体的输入框扩展性可是很强的哦。
    具体的attrs.xml代码如下

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    //border 指定是带方框的样式
    <declare-styleable name="border">
       //border指的是边框
       <attr name="border_color" format="color"/>
        //item指定是方框里面区域(不包含圆)
       <attr name="item_color" format="color"/>
       //interval指的是间隔线
       <attr name="interval_color" format="color"/>
       //circle指最里面的圆
       <attr name="circle_color" format="color"/>
       <attr name="border_width" format="dimension"/>
       <attr name="border_angle" format="dimension"/>
       <attr name="interval_width" format="dimension"/>
       <attr name="circle_radius" format="dimension"/>
       //num指输入个数
       <attr name="item_num" format="integer"/>
    </declare-styleable>

    //circle指定是实心圆样式
    <declare-styleable name="circle">
       //分为填写、未填写颜色
       <attr name="circle_selector_color" format="color"/>
       <attr name="circle_un_selector_color" format="color"/>
       <attr name="circle_circle_radius" format="dimension"/>
        //num指输入个数
       <attr name="circle_item_num" format="integer"/>
    </declare-styleable>
    </resources>

    思路

    整体写成一个view自然不太合适,为了更大程度的思路清晰和易于修改。输入框、数字键盘分成了两个view,然后内部处理相关逻辑,对外暴漏接口方法。最后在相关的activity或者fragment完成相关逻辑的整合处理。

    输入框:
    输入框相对来说,view绘制要求高点。我这边考虑自定义view绘制的实现方案。

    数字键盘:
    这个既可以通过recyclerview、gridview实现。但是相对臃肿一点。我们可以把相关布局放到xml里面。之后填充到我们的自定义view里面,在自定义view里面处理相关逻辑。最后,暴露接口方法给使用者。

    输入框实现

    输入框分成了两类:边框类型和圆心类型

    边框类型输入框实现
    一:定义BorderEditText 类并继承editext,设置初始化状态。
    二: 创建了四个画笔。分别是:边框、item(矩形框)、实心圆、分割线、item个数。
    三:获取attr值,如果没有采用默认值。有颜色、边框宽度、半径等
    四:用不同画笔分别绘制边框、item、实心圆、分割线。
    五:监听onTextChanged()方法,获取当前字符串长度(长度决定填充圆心个数),调用invalidate()重新绘制,展示最新的圆心数。
    六:定义接口,当字符串长度为设置的item个数时,回调方法。在回调方法处理逻辑。

    public class BorderEditText extends android.support.v7.widget.AppCompatEditText {
    private Context mContext;
    private Paint mBorderPaint;
    private Paint mIntervalPaint;
    private Paint mCirclePaint;
    private int mNum;
    private int mLength;
    private float mCircleRadius;
    private float mBorderAngle;
    private Paint mItemPaint;
    private float mBorderWidth;

    public BorderEditText(Context context, AttributeSet attrs) {
       super(context, attrs);
       mContext = context;
       initPaints();
       initAttrs(attrs);
       setFilters(new InputFilter[]{new InputFilter.LengthFilter(mNum)});
       setInputType(InputType.TYPE_CLASS_NUMBER);
       setBackgroundDrawable(null);
       setFocusable(false);
    }

    private void initPaints() {
       mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
       mItemPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
       mIntervalPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
       mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

    private void initAttrs(AttributeSet attrs) {
       TypedArray typedArray = mContext.obtainStyledAttributes(attrs,
               R.styleable.border, 0, 0);
       //外边框相关
       int borderColor = typedArray.getColor(R.styleable.border_border_color, mContext.getResources().getColor(R.color.border_color));
       mBorderAngle = DensityUtil.dp2px(mContext, typedArray.getDimension(R.styleable.border_border_angle, 10));
       mBorderWidth = DensityUtil.dp2px(mContext, typedArray.getDimension(R.styleable.border_border_width, 1));
       //item颜色
       int itemColor = typedArray.getColor(R.styleable.border_border_color, mContext.getResources().getColor(R.color.withe));
       //间隔线相关
       int intervalColor = typedArray.getColor(R.styleable.border_interval_color, mContext.getResources().getColor(R.color.interval_color));
       float intervalWidth = DensityUtil.dp2px(mContext, typedArray.getDimension(R.styleable.border_interval_width, 1));
       //实心圆相关
       int circleColor = typedArray.getColor(R.styleable.border_circle_color, mContext.getResources().getColor(R.color.circle_color));
       mCircleRadius = DensityUtil.dp2px(mContext, typedArray.getDimension(R.styleable.border_circle_radius, 5));
       //num个数
       mNum = typedArray.getInteger(R.styleable.border_item_num, 6);

       mBorderPaint.setColor(borderColor);
       mBorderPaint.setStyle(Paint.Style.FILL);

       mItemPaint.setColor(itemColor);
       mItemPaint.setStyle(Paint.Style.FILL);

       mIntervalPaint.setColor(intervalColor);
       mIntervalPaint.setStyle(Paint.Style.STROKE);
       mIntervalPaint.setStrokeWidth(intervalWidth);

       mCirclePaint.setColor(circleColor);
       mCirclePaint.setStyle(Paint.Style.FILL);

       typedArray.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
       //画边框
       int width = getWidth();
       int height = getHeight();
       RectF borderRectF = new RectF(0, 0, width, height);
       canvas.drawRoundRect(borderRectF, mBorderAngle, mBorderAngle, mBorderPaint);
       //画item
       RectF itemRectF = new RectF(mBorderWidth, mBorderWidth, width - mBorderWidth, height - mBorderWidth);
       canvas.drawRoundRect(itemRectF, mBorderAngle, mBorderAngle, mItemPaint);
       //画间隔线
       int itemWidth = getWidth() / mNum;
       for (int i = 1; i < mNum; i++) {
           int offsetX = itemWidth * i;
           canvas.drawLine(offsetX, 0, offsetX, height, mIntervalPaint);
       }
       //画实心圆
       for (int i = 0; i < mLength; i++) {
           float circleX = (float) (itemWidth * i + itemWidth * 0.5);
           float circleY = (float) (getHeight() * 0.5);
           canvas.drawCircle(circleX, circleY, mCircleRadius, mCirclePaint);
       }

    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
       super.onTextChanged(text, start, lengthBefore, lengthAfter);
       mLength = text.toString().length();
       invalidate();
       if (mListener != null) {
           if (mLength == mNum) {
               mListener.OnBorderEditTextComplete(this, text.toString());
           }
       }
    }

    public void clear() {
       setText("");
    }

    public interface OnBorderEditTextListener {
       void OnBorderEditTextComplete(BorderEditText editText, String text);
    }

    public OnBorderEditTextListener mListener;

    public void setListener(OnBorderEditTextListener listener) {
       mListener = listener;
    }
    }

    实心圆类型输入框实现

    一:定义CircleEditText 类并继承editext,设置初始化状态。
    二: 创建了二个画笔。分别是:圆心填充,圆心未填画笔。
    三:获取attr值,如果没有定义则采用默认值。有颜色、边框宽度、半径等。
    四:根据状态,用不同画笔,绘制不同位置的实心圆。
    五:监听onTextChanged()方法,获取当前字符串长度(长度决定填充圆心个数),调用invalidate()重新绘制,更改状态。
    六:定义接口,当字符串长度为设置的item个数时,回调方法。在回调方法处理逻辑。

    public class CircleEditText extends android.support.v7.widget.AppCompatEditText {

    private Context mContext;
    private Paint mSelectorPaint;
    private Paint mUnSelectorPaint;
    private int mNum;
    private int mLength;
    private float mCircleRadius;

    public CircleEditText(Context context, AttributeSet attrs) {
       super(context, attrs);
       mContext = context;
       initPaints();
       initAttrs(attrs);
       setFilters(new InputFilter[]{new InputFilter.LengthFilter(mNum)});
       setInputType(InputType.TYPE_CLASS_NUMBER);
       setBackgroundDrawable(null);
       setFocusable(false);

    }

    private void initPaints() {
       mSelectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
       mUnSelectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

    private void initAttrs(AttributeSet attrs) {
       TypedArray typedArray = mContext.obtainStyledAttributes(attrs,
               R.styleable.circle, 0, 0);
       int selectorColor = typedArray.getColor(R.styleable.circle_circle_selector_color, mContext.getResources().getColor(R.color.selector_color));
       int unSelectorColor = typedArray.getColor(R.styleable.circle_circle_un_selector_color, mContext.getResources().getColor(R.color.un_selector_color));

       mCircleRadius = DensityUtil.dp2px(mContext, typedArray.getDimension(R.styleable.circle_circle_circle_radius, 10));

       mNum = typedArray.getInteger(R.styleable.circle_circle_item_num, 6);

       mSelectorPaint.setColor(selectorColor);
       mSelectorPaint.setStyle(Paint.Style.FILL);

       mUnSelectorPaint.setColor(unSelectorColor);
       mUnSelectorPaint.setStyle(Paint.Style.FILL);

       typedArray.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
       int itemWidth = getWidth() / mNum;
       for (int i = 0; i < mNum; i++) {
           float circleX = (float) (itemWidth * i + itemWidth * 0.5);
           float circleY = (float) (getHeight() * 0.5);
           if (i < mLength) {
               canvas.drawCircle(circleX, circleY, mCircleRadius, mSelectorPaint);
           } else {
               canvas.drawCircle(circleX, circleY, mCircleRadius, mUnSelectorPaint);
           }
       }

    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
       super.onTextChanged(text, start, lengthBefore, lengthAfter);
       mLength = text.toString().length();
       invalidate();
       if (mListener != null) {
           if (mLength == mNum) {
               mListener.OnCircleEditTextComplete(this, text.toString());
           }
       }
    }

    public void clear() {
       setText("");
    }

    public interface OnCircleEditTextListener {
       void OnCircleEditTextComplete(CircleEditText editText, String text);
    }

    public OnCircleEditTextListener mListener;

    public void setListener(OnCircleEditTextListener listener) {
       mListener = listener;
    }
    }

    数字键盘

    一:自定义NumberInputView ,在里面完成必要逻辑,对外暴漏接口。
    一:填充布局,布局在xml中主要通过TableLayout实现排版。
    三:获取xml里面的具体控件,并设置监听。为了简化不必要代码,我通过view数组方式,设置监听。
    四:定义接口方法。根据不同按钮,回调不同的方法。分了三类:数字按钮、清空按钮、回退按钮。

    public class NumberInputView extends LinearLayout {

    private Context mContext;
    private View[] mViews;

    public NumberInputView(Context context, @Nullable AttributeSet attrs) {
       super(context, attrs);
       mContext = context;
       initViews();
       initListeners();

    }

    private void initViews() {
       View inflate = LayoutInflater.from(mContext).inflate(R.layout.number_input_view, this, true);
       View zero = inflate.findViewById(R.id.zero);
       View one = inflate.findViewById(R.id.one);
       View two = inflate.findViewById(R.id.two);
       View three = inflate.findViewById(R.id.three);
       View four = inflate.findViewById(R.id.four);
       View five = inflate.findViewById(R.id.five);
       View six = inflate.findViewById(R.id.six);
       View seven = inflate.findViewById(R.id.seven);
       View eight = inflate.findViewById(R.id.eight);
       View nine = inflate.findViewById(R.id.nine);
       View clear = inflate.findViewById(R.id.clear);
       View delete = inflate.findViewById(R.id.backward);
       mViews = new View[]{zero, one, two, three, four, five, six, seven, eight, nine, clear, delete};
    }

    private void initListeners() {
       for (int i = 0; i < mViews.length; i++) {
           final int finalI = i;
           mViews[i].setOnClickListener(new OnClickListener() {
               @Override
               public void onClick(View v) {
                   if (mListener == null) {
                       return;
                   }
                   if (finalI == 10) {
                       mListener.onClearClick(NumberInputView.this);
                       return;
                   }
                   if (finalI == 11) {
                       mListener.onBackwardClick(NumberInputView.this);
                       return;
                   }
                   mListener.onNumberClick(NumberInputView.this, finalI);

               }
           });
       }
    }

    public interface OnNumberInputViewListener {
       void onNumberClick(NumberInputView view, int num);

       void onClearClick(NumberInputView view);

       void onBackwardClick(NumberInputView view);
    }

    public OnNumberInputViewListener mListener;

    public void setListener(OnNumberInputViewListener listener) {
       mListener = listener;
    }
    }

    回调的使用

       @Override
    protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_border);
       mBorderEditText = (BorderEditText) findViewById(R.id.edit);
       mBorderEditText.setListener(new BorderEditText.OnBorderEditTextListener() {
           @Override
           public void OnBorderEditTextComplete(BorderEditText editText, String text) {
            //输入123456模拟验证成功,其他模拟失败。
               if (text.equals("123456")) {
                   Toast.makeText(BorderActivity.this, " success  " + text, Toast.LENGTH_SHORT).show();
                   return;
               }
               Toast.makeText(BorderActivity.this," error  "+ text, Toast.LENGTH_SHORT).show();
               //开启错误动画  与下面clear(clear方式无动画) 二选一
               errorAnim();
             // mBorderEditText.clear();

           }
       });
       NumberInputView numberInputView = (NumberInputView) findViewById(R.id.input);
       numberInputView.setListener(new NumberInputView.OnNumberInputViewListener() {
           @Override
           //数字键回调
           public void onNumberClick(NumberInputView view, int num) {
               //mBorderEditText 字符串长度加1
               if (!mBorderEditText.isEnabled()) {   //错误样式动画执行期间,设置不可输入。
                   return;
               }
               String s = mBorderEditText.getText().toString();
               s += num;
               //自定义边框输入框,设置text(会触发里面的ontextChanged方法,从而执行重绘)
               mBorderEditText.setText(s);
           }

           @Override
           //清空按钮
           public void onClearClick(NumberInputView view) {
               //清空输入框内容
               mBorderEditText.clear();
           }

           @Override
           //回退一个按钮
           public void onBackwardClick(NumberInputView view) {
               //mBorderEditText 字符串长度减1
               String s = mBorderEditText.getText().toString();
               if (s.length() == 0) {
                   return;
               }
               String substring = s.substring(0, s.length() - 1);
                //自定义边框输入框,设置text(会触发里面的ontextChanged方法,从而执行重绘)
               mBorderEditText.setText(substring);
           }
       });
    }

    通过以上方法,输入框、数字键盘完全无耦合。方便大家书写自己的逻辑。

    总结

    无耦合,易修改的一套Keyboard,希望能帮助到大家。后期会在此基础上,开源完全解耦的应用锁(pin码)。尽请期待~

    地址:https://github.com/HoldMyOwn/Keyboard.git

    键盘

    仿微信表情输入键盘(支持 Gif 表情图文混排 )

    Android 键盘适配-中英文适配

    展开全文
  • React Native Keyboard使用详解

    千次阅读 2018-05-31 16:36:02
    但有时我们想在键盘弹出时对页面布局做个调整,或者在程序中使用代码收起这个软键盘,...一、Keyboard API提供的方法Keyboard API提供如下的静态函数供开发者使用:1、addListener(eventName, callback)(1)这个函...
    当我们点击输入框时,手机的软键盘会自动弹出,以便用户进行输入。但有时我们想在键盘弹出时对页面布局做个调整,或者在程序中使用代码收起这个软键盘,这些借助 React Native 框架提供的Keyboard API 就可以实现。


    一、Keyboard API提供的方法

    Keyboard API提供如下的静态函数供开发者使用:

    1、addListener(eventName, callback)
    (1)这个函数用来加载一个指定事件的事件监听器,函数中的 eventName 可以是如下值:
    keyboardWillShow:软键盘将要显示
    keyboardDidShow:软键盘显示完毕
    keyboardWillHide:软键盘将要收起
    keyboardDidHide:软键盘收起完毕
    keyboardWillChangeFrame:软件盘的 frame 将要改变
    keyboardDidChangeFrame:软件盘的 frame 改变完毕
    (2)这个函数返回一个对象。我们可以保存这个对象,在需要释放事件监听器时,调用这个对象的 remove 方法。


    2、removeListener(eventName, callback)
    这个函数用来释放一个特定的键盘事件监听器。

    3、removeAllListener(eventName)
    这个函数用来释放一个指定键盘事件的所有事件监听器。

    4、dissmiss()
    这个方法让操作系统收起软键盘


    二、使用样例

    在TextInput中输入文本,会弹出软键盘,点击空白部分,遗失焦点并隐藏软键盘,具体做法如下:

    监听软键盘的弹出和隐藏

    componentWillMount这个方法是在render渲染之前调用,只调用一次,componentWillUnmount这个方法在销毁的时候调用,移出软键盘。
    componentWillMount() {
            //监听键盘弹出事件
            this.keyboardDidShowListener = Keyboard.addListener(
                "keyboardDidShow",
                this.keyboardDidShowHandler.bind(this)
            );
            //监听键盘隐藏事件
            this.keyboardDidHideListener = Keyboard.addListener(
                "keyboardDidHide",
                this.keyboardDidHideHandler.bind(this)
            );
        }
    
        componentWillUnmount() {
            //卸载键盘弹出事件监听
            if (this.keyboardDidShowListener != null) {
                this.keyboardDidShowListener.remove();
            }
            //卸载键盘隐藏事件监听
            if (this.keyboardDidHideListener != null) {
                this.keyboardDidHideListener.remove();
            }
        }
    
        //键盘弹出事件响应
        keyboardDidShowHandler(event) {
            this.setState({ KeyboardShown: true });
        }
    
        //键盘隐藏事件响应
        keyboardDidHideHandler(event) {
            this.setState({ KeyboardShown: false });
        }

    在View的第一层包裹一个点击事件

    <View style={[styles.flex, styles.topStatus]}>
           <TouchableOpacity activeOpacity={1.0} onPress={this.dissmissKeyboard.bind(this)}>
                        ...
            </TouchableOpacity>
    </View>
    如果点击事件控件使用的是TouchableOpacity,如果不想看到点击效果的话,记得设置激活的透明度为1
    在点击onPress后隐藏软件盘
    //强制隐藏键盘
    dissmissKeyboard() {
        // Toast.info("点击", 1);
        Keyboard.dismiss();
    }

    完整代码:

    import React, { Component, PropTypes } from "react";
    import {
        AppRegistry,
        StyleSheet,
        Text,
        ScrollView,
        Image,
        Alert,
        FlatList,
        TextInput,
        View,
        Linking,
        TouchableOpacity,
        TouchableWithoutFeedback,
        Keyboard
    } from "react-native";
    import { Button, Modal, Toast } from "antd-mobile";
    import Communications from "react-native-communications";
    const Dimensions = require("Dimensions");
    export const screenW = Dimensions.get("window").width;
    export const screenH = Dimensions.get("window").height;
    
    const styles = StyleSheet.create({
        tabBarImage: {
            width: 24,
            height: 24
        },
        flex: {
            flex: 1
        },
        flex2: {
            // flex: 1
        },
        flexDirection: {
            flexDirection: "row"
        },
        topStatus: {
            marginTop: 10
        },
    
        textareaContent: {
            backgroundColor: "#fff",
            paddingLeft: 15
        },
        title: {
            fontSize: 16,
            color: "#333"
        },
        tcTitle: {
            fontSize: 16,
            color: "#333",
            marginBottom: 10,
            marginTop: 10
        },
        tcInput: {
            fontSize: 14,
            height: 100
        },
        inputHeight: {
            height: 45
        },
        inputContent: {
            backgroundColor: "#fff",
            paddingLeft: 15,
            marginTop: 10,
            height: 45
        },
        input: {
            height: 45,
            marginLeft: 5,
            paddingLeft: 5,
            fontSize: 14
        },
        icTitle: {
            height: 45,
            justifyContent: "center",
            // alignItems: "center",
            width: 90
        },
        phone: {
            backgroundColor: "#fff",
            paddingLeft: 15,
            marginTop: 10,
            height: 45
        },
        center: {
            justifyContent: "center",
            alignItems: "center"
        },
        phoneLeft: {
            marginLeft: 100
        }
    });
    class Feedback extends Component {
        
        constructor(props) {
            super(props);
            this.state = { text: "", textarea: "", KeyboardShown: false };
            this.submit = this.submit.bind(this);
            this.keyboardDidShowListener = null;
            this.keyboardDidHideListener = null;
        }
        render() {
            return (
                <View style={[styles.flex, styles.topStatus]}>
                    <TouchableOpacity activeOpacity={1.0} onPress={this.dissmissKeyboard.bind(this)}>
                        <View style={[styles.textareaContent, styles.flex2]}>
                            <Text style={styles.tcTitle}>反馈内容:</Text>
                            <TextInput
                                ref="textareaInput"
                                multiline={true}
                                style={styles.tcInput}
                                autoCapitalize="none"
                                placeholder="请填写您的宝贵意见,让58不断进步,谢谢!"
                                placeholderTextColor="#CCC"
                                onChangeText={(textarea) => this.setState({ textarea })}
                                // onEndEditing={this.dissmissKeyboard.bind(this)}
                            />
                        </View>
                        <View style={[styles.flexDirection, styles.inputContent, styles.flex2]}>
                            <View style={styles.icTitle}>
                                <Text style={styles.title}>联系方式:</Text>
                            </View>
                            <View style={styles.flex}>
                                <TextInput
                                    ref="phoneInput"
                                    style={styles.input}
                                    autoCapitalize="none" //不自动切换任何字符成大写
                                    keyboardType="numeric"
                                    placeholder="请填写有效的联系方式"
                                    onChangeText={(text) => this.setState({ text })}
                                    // onEndEditing={this.dissmissKeyboard.bind(this)}
                                />
                            </View>
                        </View>
                        <View style={[styles.flexDirection, styles.phone, styles.flex2]}>
                            <View style={styles.center}>
                                <Text style={[styles.title, styles.center]}>客服电话</Text>
                            </View>
                            {/* <TouchableOpacity onPress={() => Communications.phonecall('10105858', true)}>
                        <View style={styles.center}>
                            <Text style={styles.title}>10105858</Text>
                        </View>
                        </TouchableOpacity> */}
                            <View
                                style={[styles.center, styles.phoneLeft]}
                                onPress={() => Communications.phonecall("10105858", true)}>
                                <Text style={styles.title} onPress={() => this.linking("tel:10105858")}>
                                    10105858
                                </Text>
                            </View>
                        </View>
                        <View style={{ height: 200 }}>
                            <Text />
                        </View>
                       
                    </TouchableOpacity>
                </View>
            );
        }
    
        componentDidMount() {
            // 通过在componentDidMount里面设置setParams
            this.props.navigation.setParams({
                submit: this.submit
            });
        }
        //拨打电话
        linking(url) {
            Linking.canOpenURL(url)
                .then((supported) => {
                    if (!supported) {
                        Toast.info("Can't handle url: " + url);
                    } else {
                        return Linking.openURL(url);
                    }
                })
                .catch((err) => Toast.error("An error occurred", err));
        }
        //表单提交
        submit() {
            let self = this;
            let postData = {};
            postData.content = this.state.textarea;
            postData.phone = this.state.text;
            if (!postData.content) {
                Toast.fail("请输入反馈信息", 2);
                return;
            }
            if (postData.content.length < 15 || postData.content.length > 380) {
                Toast.fail("请输入反馈信息(字数在15-380之间)", 2);
                return;
            }
            if (!postData.phone) {
                Toast.fail("(必填)请输入有效电话号码", 2);
                return;
            }
            Toast.info(JSON.stringify(postData), 2);
            // Alert.alert(JSON.stringify(postData))
        }
    
        componentWillMount() {
            //监听键盘弹出事件
            this.keyboardDidShowListener = Keyboard.addListener(
                "keyboardDidShow",
                this.keyboardDidShowHandler.bind(this)
            );
            //监听键盘隐藏事件
            this.keyboardDidHideListener = Keyboard.addListener(
                "keyboardDidHide",
                this.keyboardDidHideHandler.bind(this)
            );
        }
    
        componentWillUnmount() {
            //卸载键盘弹出事件监听
            if (this.keyboardDidShowListener != null) {
                this.keyboardDidShowListener.remove();
            }
            //卸载键盘隐藏事件监听
            if (this.keyboardDidHideListener != null) {
                this.keyboardDidHideListener.remove();
            }
        }
    
        //键盘弹出事件响应
        keyboardDidShowHandler(event) {
            this.setState({ KeyboardShown: true });
        }
    
        //键盘隐藏事件响应
        keyboardDidHideHandler(event) {
            this.setState({ KeyboardShown: false });
        }
    
        //强制隐藏键盘
        dissmissKeyboard() {
            // Toast.info("点击", 1);
            Keyboard.dismiss();
        }
    }
    
    export default Feedback;

    效果:


    展开全文
  • keyBoard

    2019-07-10 06:00:09
    哈哈哈哈



    哈哈哈哈? ------------- 大哥原创

    
    

    请多多指教 .....................................................未完待续

     


    //
    // ViewController.m // KeyBoardTest // // Created by Hunter on 16/5/14. // Copyright © 2016年 海腾. All rights reserved. // #import "ViewController.h" @interface ViewController () @property (nonatomic, retain) UIView *aView; /**< 键盘背地图 */ @property (nonatomic, retain) UITextField *textField; /**< 键盘 */ @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor orangeColor]; [self initTextField]; } #pragma mark 键盘演示 /**键盘演示 */ - (void)initTextField { self.aView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - 40, self.view.frame.size.width, 40)]; self.aView.backgroundColor = [UIColor lightGrayColor]; [self.view addSubview:self.aView]; self.textField = [[UITextField alloc] initWithFrame:CGRectMake((self.view.frame.size.width - 250) / 2,5,250,30)]; self.textField.backgroundColor = [UIColor whiteColor]; self.textField.placeholder = @"请输入"; [self.aView addSubview:self.textField]; //UIKeyboardWillShow [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardwillAppear:) name:UIKeyboardWillShowNotification object:nil]; //UIKeyboardWillHide [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(UIKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; } /** UIKeyboardWillHide */ - (void)UIKeyboardWillHide:(NSNotification *)notifation { [UIView animateWithDuration:0.25 animations:^{ self.aView.frame = CGRectMake(0, self.view.frame.size.height - 40, self.view.frame.size.width, 40); }]; } /** keyBoardwillAppear */ - (void)keyBoardwillAppear:(NSNotification *)notifation { NSLog(@"%@",notifation); CGRect KeyboardFrame = [[notifation.userInfo objectForKey:@"UIKeyboardFrameEndUserInfoKey"] CGRectValue]; NSLog(@"%@",NSStringFromCGRect(KeyboardFrame)); //UIView动画 [UIView animateWithDuration:0.25 animations:^{ self.aView.frame = CGRectMake(0 , self.view.frame.size.height - KeyboardFrame.size.height -50, self.view.frame.size.width, 50); }]; } /** 触摸开始的时候回收键盘 */ - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self.textField resignFirstResponder]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:UIKeyboardWillShowNotification]; [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:UIKeyboardWillHideNotification]; } @end

     

    转载于:https://www.cnblogs.com/HaiTeng/p/5491723.html

    展开全文
  • keyboard.zip

    2020-07-27 23:30:22
    键盘记录c++程序及源代码,可以直接运行,有问题请在下方留言,不要喷,和谐
  • Keyboard(水题)

    千次阅读 2014-10-25 18:54:40
    Description Our good friend Mole is trying to code a big message. He is typing on an unusual keyboard with characters arranged in following way: qwertyuiop asdfghjkl; zxcvbnm,./ Unfortunate

    Description

    Our good friend Mole is trying to code a big message. He is typing on an unusual keyboard with characters arranged in following way:

    qwertyuiop
    asdfghjkl;
    zxcvbnm,./
    

    Unfortunately Mole is blind, so sometimes it is problem for him to put his hands accurately. He accidentally moved both his hands with one position to the left or to the right. That means that now he presses not a button he wants, but one neighboring button (left or right, as specified in input).

    We have a sequence of characters he has typed and we want to find the original message.

    Input

    First line of the input contains one letter describing direction of shifting ('L' or 'R' respectively for left or right).

    Second line contains a sequence of characters written by Mole. The size of this sequence will be no more than 100. Sequence contains only symbols that appear on Mole's keyboard. It doesn't contain spaces as there is no space on Mole's keyboard.

    It is guaranteed that even though Mole hands are moved, he is still pressing buttons on keyboard and not hitting outside it.

    Output

    Print a line that contains the original message.

    Sample Input

    Input
    R
    s;;upimrrfod;pbr
    
    Output
    allyouneedislove       
    
    
    题意:给出移动后的字符串。如果是R,证明给出的字符串是每个都右移的,你要输出原串就要每个字符都变成它键盘上左边的那个,如果是L则相反
    
    
    思路:数据很少,完全可以暴力枚举
    
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    char str1[110]="qwertyuiopasdfghjkl;zxcvbnm,./";
    char str2[110];
    char s;
    int main()
    {
        scanf("%c",&s);
        scanf("%s",str2);
        if(s=='L')
        {
            int len=strlen(str2);
            for(int i=0;i<len;i++)
            {
                for(int j=0;j<30;j++)
                {
                    if(str2[i]==str1[j])
                    {
                        printf("%c",str1[j+1]);
                        break;
                    }
                }
            }
        }
    
    else
    {
        int len=strlen(str2);
        for(int i=0;i<len;i++)
        {
            for(int j=0;j<30;j++)
                if(str2[i]==str1[j])
            {
                printf("%c",str1[j-1]);
                break;
            }
        }
    
    }
    printf("\n");
    return 0;
    }
    

    
    展开全文
  • 在学习Matlab程序设计时看到这样一段对keyboard命令的说明:然而在Matlab R2016a中实际运行程序进入keyboard模式后,键入return按回车并不能退出keyboard模式。查阅Matlab帮助文档后结果如下:可能是由于版本的原因...
  • [wait()](https://github.com/boppreh/keyboard#keyboard.wait)4.2. [add_hotkey()](https://github.com/boppreh/keyboard#keyboard.add_hotkey)4.3. [record()]...
  • react-native-keyboardevents 是 React Native 的键盘事件。基础示例:// require the module var KeyboardEvents = require('react-native-keyboardevents'); // Now get a handle on the event ...
  • 多引擎查毒 SHA256: 1358818ef3fa51d8bb6f938c68c6e03c437b557617cc682b718c99dfcb3b1657 ...Description Hot Virtual Keyboard 8.5.0.0 Setup Comments This installation was built with Inno Setup.
  • 1Keyboard for mac是一款非常实用的应用软件。如果你从未在Mac上尝试过1Keyboard ,那么现在就去试试吧,瞬间让mac键盘变成你的移动设备专属键盘!今天要给大家分享的是1Keyboard for mac使用教程,希望对大家有所...
  • WH_KEYBOARD和WH_KEYBOARD_LL的区别

    千次阅读 2010-06-11 12:06:00
     WH_KEYBOARD和WH_KEYBOARD_LL,这两个都是键盘钩子,他们有什么区别呢?MSDN上面说的是WH_KEYBOARD会在应用程序调用GetMessage 或者 PeekMessage函数并且有键盘消息(按下或者释放)的时候会调用相应的函数...
  • 我在github上找了很多开源项目,最后选择了Virtual Keyboard, 以下是我自己学习和使用Virtual Keyboard的经验和理解,可能不是很深入,嘿嘿。。。。。。 以下是正文 首先我们需要从github上把项目的代码拉下来,...
  • 软件名称:黑客键盘:Hacker's Keyboard 软件版本:v1.33 软件大小:1.74 M 支持系统:Android 2.2及更高版本 软件介绍 黑客键盘Hacker's Keyboard提供一切你需要的按键,方便地在Android上输入快捷键组合、特殊...
  • Keyboard与KeyboardView --- 自定义键盘

    千次阅读 2018-09-30 10:23:52
    1. 利用Keyboard实现布局 在res/xml目录下创建keyboard的布局xml文件,如下: &lt;!-- keyWidth每个按键占的宽百分比,keyHeight按键高度 --&gt; &lt;!-- verticalGap,horizontalGap 垂直/水平间...
  • keyboard:同样,是控制键盘的模块,可以完全控制键盘,本篇不打算介绍,源码很少,有兴趣可以看官网keyboard 一.介绍 pynput这个库让你可以控制和监控输入设备,它包含一个子模块来控制和监控该种输入设备: ...
  • GameKeyboard 6.1.1

    2020-07-25 23:30:55
    Game Keyboard 是一款强大的模拟游戏手柄的模拟器。 主要功能: - 支持用户自定义执行的连射,单击,组合键和动作序列 - 模拟Xperia Play和OnLive的控制器按钮 - 4/8连发,多达12个游戏按键 - 多点触摸(依赖于...
  • keyboard中key属性介绍

    千次阅读 2012-06-08 14:28:32
    keyboard的定义中,通过Keyboard说明是一个软键盘定义文件,Row元素说明这是一行按键的定义,Key元素说明这是一个按键的定义。Key元素通过一些属性来定义每个按键,下面是一些常用的属性介绍:  Codes:代表...
  • keyboard maestro教程:剪贴板首选项如何使用?此窗口窗格允许您添加,删除和重命名命名剪贴板,并查看和更改其值。 剪贴板首选项如何使用? 在“ 剪贴板”首选项窗格中,您可以添加,删除和重命名“命名剪贴板...
  • Keyboard Controller 简介主板的键盘有一块专用的接口芯片,一般是采用一块单片微处理器8042(现在大多已集成在南桥或SIO里)。它控制整个键盘的工作,包括加电自检、键盘扫描码的缓冲以及与主板的通讯。 INT 09H是...
  • 本来想在js.coach 库里面找一找第三方的插件,看到最好的一个就是react-native-keyboard-spacer了,然而我们还差一个东西,那就是获取键盘的高度。 这个我也查了半天并没有提供,获取没找到吧。于是只好自己写原生...
1 2 3 4 5 ... 20
收藏数 103,570
精华内容 41,428
关键字:

keyboard