while(enough experience){
work();
experience++;
}
Success();
安卓小本本
0、各位写程序时请一定要写点注释,没有注释的代码只是一时节省了时间,不但别人不容易看懂,就是你自己过了一段时间对这段代码也未必能说的头头是道,尤其是在团队开发时,我最近接手的项目就是一个.java七八百行,竟然一条注释都没有,
实在是让人感觉头皮发麻,所以这条必须写在最上方,写个注释,不仅是为了自己,也是为了他人!!!
1、可以使用TextWatcher来监听editText的输入情况,比如登陆界面的实现过程中,如果登陆按钮需要在密码和账号的格式同时正确时才能点击,就可以使用TextWatcher来监听
2、获取验证码时的倒计时可以用CountDownTimer实现,自己写一个类继承CountDownTimer,在onTick和onFinish中实现逻辑
3、在获取控件的字符串时为了避免因为用户输入的空格引起的错误,可以使用editText.getText().toString().trim()来去除空格
4、使用butter Knife来注册view,可以一键注册布局下的所有id以及它们的点击事件,妈妈再也不用担心我的程序总是报空指针异常啦
5、editText去除下划线的方法是,加入android:background="@null"属性
6、所有的软件安装的时候最好都使用英文,而且不要有空格,今天(2017.12.4)就因为Androidstudio安装路径出现一个严重的bug,如果要改变软件默认安装位置,也最好就把其中的C:改为其他(D:、E:等),这样可以减少因为路径出现的bug
7、gravity和layout_gravity的区别,前者是针对元素本身,列如Textview使用gravity的话就是控制自己的文字显示位置,而layout_gravity则是子元素针对于父元素的位置,例如一个Linearlayout包含一个Textview,如果此时的Textview使用layout_gravity这个属性则表示控制Textview相对于Linearlayout的位置显示
8、写布局时遇到这样一个问题,一个LinearLayout包含多个子控件,最下方的是button,因为需要与上方的标题有一定的距离,所以在LinearLayout中加一个layout_marginTop="12dp",最后写button控件的时候发现这样一个问题,我们给button一个center的属性,但是button中间的文字一直在屏幕中显示的情况是偏下方的,并没有居中,在预览图中可以看到button有一部分是在屏幕外的(我使用scrollview来布局),在预览图中仔细看各个控件的位置,发现所有的控件其实都是向屏幕下方偏移了12dp,只不过因为button是最后一个控件,所以其显示被覆盖了12dp,为了解决显示的问题,我加入了layout_marginBottom="12dp",这样button的显示才正常,
<Button android:id="@+id/buttonOk" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginBottom="12dp" android:layout_marginTop="16dp" android:text="提交"/>
可以看到这个button有Margin Bottom和MarginTop两个属性,起初我以为这两个是相反的一对属性,实验才发现,并不是,原理和高中物理一样,这两个属性从字面理解确实是相反的,但实际使用时因参照的东西不一样,所以产生的效果也不同,就以这个button来说,marginTop是根据其上一个控件进行参照的,而marginButton却是以它的父控件,也就是开头说的linearLayout来进行参照的,参照物不同,实际的效果也就不一样,总结就是 marginTop=16dp+marginButton=12dp并!=marginTop=4dp
9、团队开发中有时候会遇到写业务的时候没有条件进行测试,例如后台接口没写完,程序流程并没有连上(你要做功能二,但是功能一是没有做完的,但是你必须要功能一有了之后你才能做功能二),这种情况的话只写逻辑不测试其实是比较容易出错的,所以需要模拟数据,就是本来数据来源应该是通过网络,但我们自己写数据,这样切断了与其他模块的联系,对我们写的功能进行单独测试,所以软件开发中,讲究的高内聚,低耦合就是这个理,一个程序往往由多人开发,如果程序耦合太高,就会造成测试一个函数需要涉及到多个模块,这样的情况下出现一个bug往往是毁灭性的;;扯远了 。。 说到自己写json文件,就要说如何去读取,读取的过程如下
//读取本地json文件 private String getJsonData() { AssetManager assetManager=getContext().getAssets(); try { InputStream is=assetManager.open("waitopen.txt"); BufferedReader reader=new BufferedReader(new InputStreamReader(is)); StringBuffer stringBuffer=new StringBuffer(); String str; while ((str=reader.readLine())!=null){ stringBuffer.append(str); } return stringBuffer.toString(); } catch (IOException e) { e.printStackTrace(); } return null; }
这样的话我们就可以继续完成json解析以及其他的一些逻辑操作,到时候只需要替换数据来源,测试的时候就方便很多了,而且这样做的话比直接写逻辑代码而不带入数据测试要可靠的多
-----------对第九条的补充(2017.12.8):我们可以把文件的名字作为参数传入,这样所有在这个assert的路径下的文件都可以通过这个方法进行读取,提高方法的复用性
10、当scrollView中包含一个listview时,listview中只会显示一行,原因是ScrollView中嵌套listview的时候,listview的大小是无法正确计算的。我刚开始是直接指定listview的大小,例如height=300dp,这样做是可以的,但是这样当用户屏幕手机长度比较长,而你的listview中的子项又很少的话,会造成屏幕中大量空白,这样显示效果肯定是不行的;另一个解决办法是去掉scrollview(简单 暴力 快捷),我看网络资料的另一个是在代码中确定子项高度,有兴趣的可以试试
11、当点击退出按钮时 弹出对话框的实现
public void onButtonFinishClicked() { AlertDialog.Builder dialog=new AlertDialog.Builder(this); //标题 dialog.setTitle("提示:"); //弹窗内容 dialog.setMessage("你确定要退出吗?"); //确定键的事件 dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { Intent intent=new Intent(); intent.setClass(PropertyPeopleInfoActivity.this, MainActivity.class); startActivity(intent); } }); //取消键的事件 dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); //创建并显示 dialog.create().show(); }
12、程序内部调用系统拨号实现方式
public void onImageCallClicked() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:" + phone)); //启动系统打电话功能。 startActivity(intent); }
最后要在配置清单里加上这个权限,否则程序会crash
<uses-permission android:name="android.permission.CALL_PHONE"/>
(2017.12.25补充:ACTION_CALL是直接拨打电话,而ACTION_DIAL是直接转到拨打电话的界面,要不要拨打由用户决定)
13、转换时间戳,第一个是需要显示的格式(比如:yyyy/MM/dd HH:mm 对应的就是2017/12/13 14:25),第二个是时间戳
//转换时间戳 public static String formatData(String dataFormat, long timeStamp) { timeStamp = timeStamp * 1000; SimpleDateFormat format = new SimpleDateFormat(dataFormat); String result = format.format(new Date(timeStamp)); return result; }
14、如果写程序时遇到需要从网络中获取数据完毕后才能确定布局的情况,需要把改变布局的代码写在确保网络数据是获取成功之后,可以把改变布局的代码封装成一个方法,在获取数据后的代码中调用,因为网络有延迟,所以改变布局的代码会比获取网络的代码先执行
15、安卓studio在fragment中使用butterKnife插件时,因为fragment与activity的生命周期不同,所以在前者的onCreatView中绑定视图时,需要在onDestroyView中进行解绑操作(插件自动完成),要使用butter knife为我们绑定的id时,需要在该语句之后
unbinder = ButterKnife.bind(this, view);
,否则会提示空对象引用;
16、获取当前时间
//当前月 private String currentMonth; //当前年 private String currentYear;
Calendar cal = Calendar.getInstance(); cal.setTimeZone(TimeZone.getTimeZone("GMT+8:00")); currentMonth = String.valueOf(cal.get(Calendar.MONTH) + 1); currentYear = String.valueOf(cal.get(Calendar.YEAR));
月份需要加一
17、NumberPicker在项目中也时有用到,但是如果是显示NumberPicker格式的日期,使用NumberPicker这个控件来实现逻辑就会很复杂(闰年 大小月之类的),这时可以使用DatePicker,虽然默认时是一个日历的形式,但是只要加一条
android:datePickerMode="spinner"
就可以让其变成NumberPicker的格式了 非常方便.
(2017.12.26补充:无论是NumberPicker还是DatePicker,其默认都是可以点击的,如何使其不可以点击呢,只需要在对应的xml文件中加入这条属性就可以了
android:descendantFocusability="blocksDescendants")
18、关于recycerView 内容错乱的原因,其实以前做网络图片的加载的时候就遇到过,在适配器中一个图片没有值时,一定要手动赋值(给个占位图什么的),否则会发生本来不应该有图片的地方却显示了其他子项的图片的情况,那次还好,很快就找到原因,这次却花了一个下午,原因还是一样的(一个萝卜本来有两个坑,我们只填了其中的一个,另一个没填就导致了后面的萝卜填了你没填的坑,于是所有的萝卜都gg了,大致就是这个意思),但这个是本不该隐藏的地方却隐藏了,大致情况如下:程序中有一个地方需要根据服务器返回的数据来判断隐藏与否,但是我在设置的时候只设置了隐藏的情况,没有设置显示的情况,刚进去时数据一切正常,可是刷新后却出现了数据错乱,在一个下午的调试与奔溃中,终于找到罪魁祸首是当初写的时候只是设置数据的一面,另一面没有设置,于是被后来的子项占用,于是数据就全乱了,这点其实很重要,有时间的话我也想专门开一篇博客操作一下
19、持续更新中~