Android面试题-软键盘适配

Android程序员面试宝典

自定义控件

  • 一分钟实现贴纸功能
  • 一分钟实现TextView高亮
  • 一分钟实现新手引导页
  • 一分钟实现ViewPager卡片
  • 一分钟实现轮播图
  • 一分钟实现GridView拖拽
  • 一分钟实现底部导航栏
  • 一分钟实现底部FragmentTabhost
  • 一分钟实现多张图片选择
  • 一分钟实现仿美拍直播的点赞动画
  • 一分钟实现高仿今日头条视频列表
  • 一分钟实现购物车加减控件
  • 一分钟实现省市县三级联动
  • 一分钟实现二维码生成和扫描
  • 一分钟实现沉浸式状态栏
  • 一分钟实现图片裁剪
  • 一分钟实现视频弹幕
  • 一分钟实现图片缩放
  • 一分钟实现旋转选择器
  • 一分钟实现ofo小黄车的引导界面
  • 一分钟实现自定义ImageView外貌
  • 一分钟实现向左拖拽跳转详情页
  • 一分钟实现QQ首页动画特效
  • 一分钟实现ViewPager上下滑动

联网

  • 一分钟学会Retrofit并且进行实战
  • 一分钟实现OkHttp3

工具

  • 一分钟实现RecyclerView
  • 一分钟实现H5和Android通信
  • 一分钟实现pinyin4j
  • 一分钟实现分析内存泄漏

数据库

  • 一分钟实现LitePal数据库
  • 一分钟实现ormlite数据库
  • 一分钟实现GreenDao数据库

源码分析相关面试题

  • Volley源码分析
  • 注解框架实现原理
  • okhttp3.0源码分析
  • onSaveInstanceState源码分析
  • 静默安装和源码编译

Activity相关面试题

  • 保存Activity的状态
  • 深刻剖析activity启动模式(一)
  • 深刻剖析activity启动模式(二)
  • 深刻剖析activity启动模式(三)
  • Activity Task和Process之间的关系
  • 源码分析service开启Activity抛异常?activity不会抛异常
  • Activity优雅退出
  • onCreate源码分析

Service相关面试题

  • IntentService源码分析
  • Service是否在main thread中执行, service里面是否能执行耗时的操作?
  • Service不死之身

与XMPP相关面试题

  • XMPP协议优缺点
  • 极光消息推送原理

与性能优化相关面试题

  • 内存泄漏和内存溢出区别
  • UI优化和线程池实现原理
  • 代码优化
  • 内存性能分析
  • 内存泄漏检测
  • App启动优化
  • 与IPC机制相关面试题

与登录相关面试题

  • oauth认证协议原理
  • token产生的意义
  • 微信扫一扫实现原理

与开发相关面试题

  • 迭代开发的时候如何向前兼容新旧接口
  • 手把手教你如何解决as jar包冲突
  • context的原理分析
  • 解决ViewPager.setCurrentItem中间很多页面切换方案
  • 字体适配
  • 软键盘适配
  • 机型适配,例如三星、小米、华为、魅族等
  • CardView 设置水波纹效果

与人事相关面试题

  • 人事面试宝典

错误的打开方式


错误的打开姿势.gif

Android面试题-软键盘适配_第1张图片

Android面试题-软键盘适配_第2张图片


    
   
    

    
    
    

解决方法一:

最外层套ScrollView,控件多的时候可以自由滚动。




    

    

    
    
    

效果如下图:


Android面试题-软键盘适配_第3张图片

套了ScrollView之后,虽然可以滚动了,马马虎虎也算解决了问题。

解决方法二:优雅解决



    
        

            

            

            

            

在activity当中调用setScroll();

//键盘不遮挡按钮
    private void setScroll() {
        KeyboardUtil.assistActivity(this, R.id.scroll_view);       //这个是别人给我的工具类,只用这个会有

        parent.setOnTouchListener(new View.OnTouchListener() {                 //parent为Editext外面那层布局
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                parent.setFocusable(true);
                parent.setFocusableInTouchMode(true);
                parent.requestFocus();
                InputMethodManager imm = (InputMethodManager) MainActivity.this
                        .getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(account.getWindowToken(), 0);  //隐藏键盘,account为Editext,随便一个就好
                return false;
            }
        });

        scroll.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {         //scroll为parent外面那层布局()最好用NestedScrollView,ScrollView会有版本问题
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                v.scrollTo(0,450);     //这个是滑动距离,随便大一点就好
            }
        });
    }

键盘工具类:

public class KeyboardUtil {
    private static final String TAG = "KeyboardUtil";


    public static void assistActivity(Activity activity, int viewId) {
        new KeyboardUtil(activity, viewId);
    }

    private View mChildOfContent;
    private NestedScrollView mScrollView;
    private RelativeLayout.LayoutParams relativeLayoutParams;

    private KeyboardUtil(Activity activity, int viewId) {
        FrameLayout content = (FrameLayout) activity
                .findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mScrollView = (NestedScrollView) content.findViewById(viewId);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        possiblyResizeChildOfContent();
                    }
                });
    }

    private void possiblyResizeChildOfContent() {
        int contentHeight = mChildOfContent.getRootView().getHeight();
        int curDisplayHeight = computeUsableHeight();
        if (contentHeight - curDisplayHeight > contentHeight / 4) {
            Log.e(TAG, "possiblyResizeChildOfContent: 1" );
            mScrollView.scrollTo(0,600);
//                mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
        } else {
            Log.e(TAG, "possiblyResizeChildOfContent: 2" );
        }
    }

    /**
     * 获取屏幕可显示区域高度
     *
     * @return
     */
    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return r.height();
    }
}

自定义布局:

public class KeyboardLayout extends FrameLayout {

    private KeyboardLayoutListener mListener;
    private boolean mIsKeyboardActive = false; //输入法是否激活
    private int mKeyboardHeight = 0; // 输入法高度

    public KeyboardLayout(Context context) {
        this(context, null, 0);
    }

    public KeyboardLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public KeyboardLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 监听布局变化
        getViewTreeObserver().addOnGlobalLayoutListener(new KeyboardOnGlobalChangeListener());
    }

    public void setKeyboardListener(KeyboardLayoutListener listener) {
        mListener = listener;
    }

    public KeyboardLayoutListener getKeyboardListener() {
        return mListener;
    }

    public boolean isKeyboardActive() {
        return mIsKeyboardActive;
    }

    /**
     * 获取输入法高度
     *
     * @return
     */
    public int getKeyboardHeight() {
        return mKeyboardHeight;
    }

    public interface KeyboardLayoutListener {
        /**
         * @param isActive       输入法是否激活
         * @param keyboardHeight 输入法面板高度
         */
        void onKeyboardStateChanged(boolean isActive, int keyboardHeight);
    }

    private class KeyboardOnGlobalChangeListener implements ViewTreeObserver.OnGlobalLayoutListener {

        int mScreenHeight = 0;

        private int getScreenHeight() {
            if (mScreenHeight > 0) {
                return mScreenHeight;
            }
            mScreenHeight = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE))
                    .getDefaultDisplay().getHeight();
            return mScreenHeight;
        }

        @Override
        public void onGlobalLayout() {
            Rect rect = new Rect();
            // 获取当前页面窗口的显示范围
            ((Activity) getContext()).getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
            int screenHeight = getScreenHeight();
            int keyboardHeight = screenHeight - rect.bottom; // 输入法的高度
            boolean isActive = false;
            if (Math.abs(keyboardHeight) > screenHeight / 4) {
                isActive = true; // 超过屏幕五分之一则表示弹出了输入法
                mKeyboardHeight = keyboardHeight;
            }
            mIsKeyboardActive = isActive;
            if (mListener != null) {
                mListener.onKeyboardStateChanged(isActive, keyboardHeight);
            }
        }
    }

}

当前Activity清单文件配置:

android:windowSoftInputMode="stateAlwaysHidden|adjustResize"
  • 欢迎关注微信公众号,长期推荐技术文章和技术视频

  • 微信公众号名称:Android干货程序员

Android面试题-软键盘适配_第4张图片

你可能感兴趣的:(Android面试题-软键盘适配)