首发于:http://blog.csdn.net/Likianta/article/details/78690286
对前四章的学习进行一次回顾和总结,本章集中解决之前的代码中产生的各种bug,尝试翻新结构以及使用更好的开源插件。
1. 先讲一下如何在真机上调试app
这里以红米Note2手机(MIUI9 开发版)为例:
- 准备一条可以传输数据的数据线
- 手机在开发者选项中启用“USB调试”和“允许USB安装”
- 手机连接PC
- 在Android Studio中运行AVD,选择“Xiaomi Redmi Note 2”,app将会安装到手机中
- 在初次安装中需要自己在手机上点击接受。安装完成后的调试会自动启动app
注意事项:
- 一定要选择可以传输数据的数据线
- 不同的手机开启开发者选项的方式不同,小米手机(MIUI9 开发版)的开启方式为连续点击MIUI版本号6次进入开发者模式
- 如果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. 登录界面在输入错误时软键盘不能自动弹出
- 首先修改Enter键的监听,将返回值改为“true”。其他代码保持不变
- 然后在“进入”按钮的点击监听事件中,判断登录成功,则强制关闭软键盘。其他代码保持不变
修改代码如下:
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
:
2.6.2. 修改activity_main.xml
文件
在activity_main.xml
中重新修改标题栏的两个文字属性(宽度改为0,weight改为1:1,margin各距100dp)。
然后删除原indicator,新增一个CircleIndicator。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.likianta.anykey.MainActivity">
<!--LinearLayout代替原标题栏的位置-->
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#ffffff">
<!--?attr/actionBarSize表示匹配原actionBar高度-->
<!--显示两个标题-->
<TextView
android:id="@+id/title_all"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="100dp"
android:layout_weight="1.0"
android:gravity="center_vertical|end"
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_marginEnd="100dp"
android:layout_weight="1.0"
android:gravity="center_vertical|start"
android:padding="15dp"
android:text="新增"
android:textColor="@color/mycolorText2"
android:textSize="20sp" />
<!--这里设置的两个文本的初始状态是文字1是深色,文字2是浅色。
之后会在函数中实现点击变色的功能-->
</LinearLayout>
<!--制作线条,line1是标题栏下的阴影-->
<TextView
android:id="@+id/shadow_line1"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignBottom="@id/linearLayout"
android:background="@color/mycolorLineShadow" />
<!--制作主体部分viewpager-->
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/shadow_line1">
</android.support.v4.view.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_indicator"
app:ci_margin="22dp"
app:ci_width="25dp" />
</RelativeLayout>
在CircleIndicator中用到了app:ci_drawable="@drawable/shape_indicator"
,这个shape只是一个简单的黑色背景,代码如下(在drawable目录下新建shape_indicator.xml
):
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/mycolorText1" />
<corners android:radius="8dp" />
</shape>
实际效果图如下:
image2.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. 布局地图
该流程图用于梳理整体的布局逻辑以及命名规范:
image相关参考
- Android 手动显示和隐藏软键盘 - 一点点征服 - 博客园 https://www.cnblogs.com/ldq2016/p/6861128.html
- http://m.blog.csdn.net/wenxin2011/article/details/50845563
- 安卓开发-Activity中finish() onDestroy() 和System.exit()的区别 - CSDN博客 http://blog.csdn.net/imzoer/article/details/9380807
- Android避免进入页面EditText自动弹出软键盘 - CSDN博客 http://blog.csdn.net/Vivian8725118/article/details/23184501
- 第三方框架ViewPagerIndicator引入到Android Studio的方法总结 - chironmy - 博客园 https://www.cnblogs.com/baipengzhan/p/6286619.html
- GitHub - ongakuer/CircleIndicator: A lightweight viewpager indicator like in nexus 5 launcher https://github.com/ongakuer/CircleIndicator
- android开发之GridLayout详解 - CSDN博客 http://blog.csdn.net/huangxiaominglipeng/article/details/17448045
- scrollview底部加入不滑动的button - CSDN博客 http://blog.csdn.net/lzq520210/article/details/49333321
- **【Android】EditText 遇到软键盘遮挡底部一点的问题 - CSDN博客 http://blog.csdn.net/xiaoguda1/article/details/52084248 **
- android selector 和 layer-list复合使用 - CSDN博客 http://blog.csdn.net/qq_20976303/article/details/51162649
- Android 显示和隐藏软键盘 - 简书 http://www.jianshu.com/p/dc9387417914
日志
2017年11月26日
- 【修改】解决登录界面密码输入错误键盘无法自动回弹的问题
- 【更新】登录界面的欢迎语的判断逻辑统一放在changeLoginWelcome()中
- 【更新】当登录密码输入错误时,欢迎语变为红色并闪烁一下(利用AlphaAnimation属性)
2017年11月27日
- 【修改】解决登录界面按返回键无法退出的问题
- 【修改】解决一进入主界面键盘就自动弹出的问题
- 【更新】解决指示器位置不准确的问题,换用开源库CircleIndicator实现指示器功能
- 【修改】解决EditText的背景的下半边被软键盘遮挡的问题
- 【新增】制作布局地图,梳理逻辑
2017年11月28日
- 【创建】Github Project
网友评论