05 Anykey阶段性总结、bug汇总及解决

对前四章的学习进行一次回顾和总结,本章集中解决之前的代码中产生的各种bug,尝试翻新结构以及使用更好的开源插件。

1. 先讲一下如何在真机上调试app

这里以红米Note2手机(MIUI9 开发版)为例:

  1. 准备一条可以传输数据的数据线
  2. 手机在开发者选项中启用“USB调试”和“允许USB安装”
  3. 手机连接PC
  4. 在Android Studio中运行AVD,选择“Xiaomi Redmi Note 2”,app将会安装到手机中
  5. 在初次安装中需要自己在手机上点击接受。安装完成后的调试会自动启动app

注意事项:

  1. 一定要选择可以传输数据的数据线
  2. 不同的手机开启开发者选项的方式不同,小米手机(MIUI9 开发版)的开启方式为连续点击MIUI版本号6次进入开发者模式
  3. 如果Android Studio在运行时提示“error:前言中不允许有内容”,则点击菜单栏 - Build - Rebuild Project即可解决

参考:http://m.blog.csdn.net/wenxin2011/article/details/50845563


2. 实机测试问题汇总

2.1. 首次创建密码后无法进入主界面

这是因为第一章中忘了在LoginActivity中写intent的跳转代码了。

解决方法:在LoginActivity的“进入(loginOn)”按钮的监听事件中,创建密码成功则跳转至主界面

修改代码如下:

LoginActivity.java:

public class LoginActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {

        //触发点击事件,监听登录按钮
        loginOn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (saved_userPassword.equals("N/A")) {
                    //首次使用的业务逻辑

                    ...

                    Toast.makeText(LoginActivity.this, "创建成功", Toast.LENGTH_SHORT).show();
                    //跳转至主界面
                    Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                    LoginActivity.this.startActivity(intent);
                    finish();
                }
            }
        });
    }
}

2.2. 登录界面在输入错误时软键盘不能自动弹出

  1. 首先修改Enter键的监听,将返回值改为“true”。其他代码保持不变
  2. 然后在“进入”按钮的点击监听事件中,判断登录成功,则强制关闭软键盘。其他代码保持不变

修改代码如下:

LoginActivity.java:

public class LoginActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {

        //触发点击事件,监听登录按钮
        loginOn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (saved_userPassword.equals("N/A")) {
                    //首次使用的业务逻辑
                    ...

                } else {
                    //判断输入的密码是否正确
                    if (passwordValue.equals(saved_userPassword)) {

                        //通过调用输入管理器来隐藏软键盘
                        InputMethodManager inputMethodManager = (InputMethodManager) etPassword.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                        inputMethodManager.hideSoftInputFromWindow(etPassword.getWindowToken(), 0); //强制隐藏软键盘

                        ...

                    }

                }
            }
        });

        //另外再设置一个监听软键盘输入,当输入Enter的时候,也能触发上面的登录按钮
        etPassword.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View view, int i, KeyEvent keyEvent) {
                if (i == keyEvent.KEYCODE_ENTER) {
                    loginOn.callOnClick(); //callOnClick是performClick的简化版,适合简单触发点击监听事件
                    return true;
                }
                return false;
            }
        });
    }
}

参考:Android 手动显示和隐藏软键盘 - 一点点征服 - 博客园 https://www.cnblogs.com/ldq2016/p/6861128.html

2.3. 密码错误时的提示语不醒目

之前的效果是当密码多次输入错误时,欢迎语文字都不会变化,所以看起来不醒目;
下图是更改后的样式——每次密码错误,提示语都会变成红色并且闪烁一下:

实现思路为:当输入错误时,设置文本颜色为亮红色,然后利用透明度动画AlphaAnimation来完成颜色的由亮到浅的变化(动画持续时间在300-800ms之间)。代码如下所示:

LoginActivity.java:

public class LoginActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {

        //判断是否为首次使用
        changeLoginWelcome(saved_userPassword); //将原先的“LoginWelcome”更改为“changeLoginWelcome”,用于专门处理欢迎语的变化

        //触发点击事件,监听登录按钮
        loginOn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (saved_userPassword.equals("N/A")) {
                    //首次使用的业务逻辑
                    ...
                } else {
                    //非首次登录时的常规业务
                    if (passwordValue.equals(saved_userPassword)) {
                        ...
                    } else {
                        //密码错误时的业务
                        changeLoginWelcome("WRONG_CODE"); //欢迎语的变化放在changeLoginWelcome中处理

                        etPassword.setText(""); //重置密码框为空

                        //让输入框重新获取焦点
                        etPassword.setFocusable(true);
                        etPassword.setFocusableInTouchMode(true);
                        etPassword.requestFocus();
                        //通过调用输入管理器来自动弹出软键盘
                        InputMethodManager inputMethodManager = (InputMethodManager) etPassword.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                        inputMethodManager.showSoftInput(etPassword, 0);
                    }
                }
            }
        });
    }


    //判断是否为首次使用,不是的话什么都不做
    public void changeLoginWelcome(String userCode) {

        switch (userCode) {
            case "N/A":
                //首次使用时是欢迎语
                loginWelcome.setText("首次使用\n请创建你的主密码");
                break;
            case "WRONG_CODE":
                //密码输入错误时的欢迎语
                loginWelcome.setText("密码错误\n请重新登录");//在“欢迎词”中显示出错提示
                loginWelcome.setTextColor(0xFFF4297E);//显示为红色
                final AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.6f);//不透明度的参数取值是小数,范围在0-1之间,0表示完全透明,1表示完全显示
                alphaAnimation.setDuration(500);
                alphaAnimation.setFillAfter(true); //表示停留在最终状态上
                loginWelcome.setAnimation(alphaAnimation);
                alphaAnimation.startNow();
                break;
        }
    }
}

2.4. 在登录界面按返回键无法退出

解决方法:新增一个按键监听设置,当按返回键时,则finish掉当前Activity:

LoginActivity.java:

public class LoginActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
    }


    //监听按下的按键,如果按下了返回键,则退出登录界面
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {

        if (keyCode == KeyEvent.KEYCODE_BACK) {
            LoginActivity.this.finish();
            return true;
        }

        return super.onKeyDown(keyCode, keyEvent);
    }
}

PS:为什么要使用finish(),而不使用onDestroy()或者System.exit(0)

finish是把当前Activity关闭,而onDestroy会销毁当前Activity的实例,System.exit(0)则会将当前整个进程给终结掉。
在实际使用中会发现,后两者在退出时屏幕会闪一下,而使用finish退出,退出动画更加自然一些。

参考:安卓开发-Activity中finish() onDestroy() 和System.exit()的区别 - CSDN博客 http://blog.csdn.net/imzoer/article/details/9380807

2.5. 一进入主界面软键盘就自动弹出

这是因为MainActivity的子分页布局里面有EditText控件,这个EditText会率先获取焦点,导致软键盘检测并触发弹出。
解决方法也很简单,在MainActivity中设置键盘默认不许自动弹出即可(只需新增一行代码):

MainActivity.java:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        //开始绑定按钮
        ...

        //http://blog.csdn.net/Vivian8725118/article/details/23184501
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

    }
}

参考:Android避免进入页面EditText自动弹出软键盘 - CSDN博客 http://blog.csdn.net/Vivian8725118/article/details/23184501

2.6. 主界面顶部标签文字下的指示器的位置有问题

这是因为代码中用的是绝对位置,不是相对位置引起的。其实这个坑早就该填了,现在使用开源库CircleIndicator来重新实现指示器的功能。

CircleIndicator的Github地址:GitHub - ongakuer/CircleIndicator: A lightweight viewpager indicator like in nexus 5 launcher https://github.com/ongakuer/CircleIndicator

2.6.1. 首先添加库的依赖(app:build.gradle):

dependencies {
    compile 'me.relex:circleindicator:1.2.2'
}

添加完后注意点击页面右上角的Sync Now

Sync Now

2.6.2. 修改activity_main.xml文件

activity_main.xml中重新修改标题栏的两个文字属性(宽度改为0,weight改为1:1,margin各距100dp)。
然后删除原indicator,新增一个CircleIndicator。

<RelativeLayout>

    <LinearLayout>

        <TextView
            android:id="@+id/title_all"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:gravity="center_vertical|right"
            android:padding="15dp"
            android:text="全部"
            android:textColor="@color/mycolorText1"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/title_new"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:gravity="center_vertical|left"
            android:padding="15dp"
            android:text="新增"
            android:textColor="@color/mycolorText2"
            android:textSize="20sp" />

    </LinearLayout>

    <TextView
        android:id="@+id/shadow_line1"
        ... />

    <!--制作主体部分viewpager-->
    <android.support.v4.view.ViewPager ... />

    <!--CircleIndicator建议写作ViewPager的下方-->
    <me.relex.circleindicator.CircleIndicator
        android:id="@+id/indicator"
        android:layout_width="match_parent"
        android:layout_height="5dp"
        android:layout_above="@id/viewPager"
        android:layout_marginBottom="1dp"
        app:ci_drawable="@drawable/shape_oval3_indicator"
        app:ci_margin="22dp"
        app:ci_width="25dp" />

</RelativeLayout>

CircleIndicator中用到了app:ci_drawable="@drawable/shape_oval3_indicator",这个shape只是一个简单的黑色背景,代码如下(在drawable目录下新建shape_oval3_indicator.xml):

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/mycolorText1" />
    <corners android:radius="8dp" />
</shape>

实际效果图如下:

2.6.3. 在MainActivity中创建indicator并绑定

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private CircleIndicator indicator; //将原先的ImageView indicator改为CircleIndicator indicator滚动指示器

    /*这三行可以删掉了
    private int offset = 0; //滚动条初始偏移量
    private int currIndex = 0; //当前页编号
    private int bmpW; //滚动条宽度
    private int one; //一倍滚动量
    */

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        indicator = (CircleIndicator) findViewById(R.id.indicator);

        ...

        //初始化适配器数据
        PagerAdapter pagerAdapter = new PagerAdapter() {...};

        //绑定适配器
        viewPager.setAdapter(pagerAdapter);
        //装载indicator,只需短短一行代码就替代了之前的初始化、一倍位移量等各种操作
        indicator.setViewPager(viewPager);

        //设置viewPager的初始界面为第一个界面
        ...
    }

    //页面滚动监听器功能,实现标签页左右滑动切换效果
    public class MyOnPageChangeListener implements ViewPager.OnPageChangeListener {

        @Override
        public void onPageSelected(int index) {
            switch (index) {
                case 0:
                    titleAll.setTextColor(0xff000000);//0x表示整型,ff表示透明度为0,最后的6位数字表示颜色,必须这样写,不能省略
                    titleNew.setTextColor(0xff8e8e8e);
                    break;
                case 1:
                    titleNew.setTextColor(0xff000000);
                    titleAll.setTextColor(0xff8e8e8e);
                    break;
            }
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
        }
    }

    /*这里可以删除了
    public void InitScrollbar(int bmpW) {...}
    */

}

3. 布局地图

该流程图用于梳理整体的布局逻辑以及命名规范:


相关参考

  1. Android 手动显示和隐藏软键盘 - 一点点征服 - 博客园 https://www.cnblogs.com/ldq2016/p/6861128.html
  2. http://m.blog.csdn.net/wenxin2011/article/details/50845563
  3. 安卓开发-Activity中finish() onDestroy() 和System.exit()的区别 - CSDN博客 http://blog.csdn.net/imzoer/article/details/9380807
  4. Android避免进入页面EditText自动弹出软键盘 - CSDN博客 http://blog.csdn.net/Vivian8725118/article/details/23184501
  5. 第三方框架ViewPagerIndicator引入到Android Studio的方法总结 - chironmy - 博客园 https://www.cnblogs.com/baipengzhan/p/6286619.html
  6. GitHub - ongakuer/CircleIndicator: A lightweight viewpager indicator like in nexus 5 launcher https://github.com/ongakuer/CircleIndicator
  7. android开发之GridLayout详解 - CSDN博客 http://blog.csdn.net/huangxiaominglipeng/article/details/17448045
  8. scrollview底部加入不滑动的button - CSDN博客 http://blog.csdn.net/lzq520210/article/details/49333321
  9. 【Android】EditText 遇到软键盘遮挡底部一点的问题 - CSDN博客 http://blog.csdn.net/xiaoguda1/article/details/52084248
  10. android selector 和 layer-list复合使用 - CSDN博客 http://blog.csdn.net/qq_20976303/article/details/51162649
  11. Android 显示和隐藏软键盘 - 简书 http://www.jianshu.com/p/dc9387417914

日志

2017年11月26日

  1. 【修改】解决登录界面密码输入错误键盘无法自动回弹的问题
  2. 【更新】登录界面的欢迎语的判断逻辑统一放在changeLoginWelcome()中
  3. 【更新】当登录密码输入错误时,欢迎语变为红色并闪烁一下(利用AlphaAnimation属性)

2017年11月27日

  1. 【修改】解决登录界面按返回键无法退出的问题
  2. 【修改】解决一进入主界面键盘就自动弹出的问题
  3. 【更新】解决指示器位置不准确的问题,换用开源库CircleIndicator实现指示器功能
  4. 【修改】解决EditText的背景的下半边被软键盘遮挡的问题
  5. 【新增】制作布局地图,梳理逻辑

2017年11月28日

  1. 【创建】Github Project
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值