Android 易忽略小知识

1.设置hint的字体大小 

在Android xml文件中并没有直接设置hint字体大小的属性。如果hint文字的大小不希望跟正常字体的大小一样,就只能通过代码的方式来进行处理。

提供两种方式:

//设置"用户名"提示文字的大小

EditText etUserName = (EditText)findViewById(R.id.et_usernanme);

SpannableString s = new SpannableString("请输入用户名");

AbsoluteSizeSpan textSize = new AbsoluteSizeSpan(14,true);

s.setSpan(textSize,0,s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

etUserName.setHint(s);

 

//设置"密码"提示文字的大小

EditText etPassword = (EditText)findViewById(R.id.et_password);

//用html的方式来设置这个属性,毕竟都是String

etPassword.setHint(Html.fromHtml("<font color=\"#cbccd1\"><small>请输入密码</small></font>"));

//etPassword.setHint(Html.fromHtml("<font color=\"#cbccd1\"><small><small>请输入密码</small></small></font>"));

 

2.定时器

①延迟处理

TimerTask task = new TimerTask() {

    @Override

    public void run() {

        //要执行的操作

    }

};

Timer timer = new Timer();

timer.schedule(task, 2000);//2秒后执行TimeTask的run方法

②指定日期运行一次

String sdate = "2018-02-14";

SimpleDateFormat sf = new SimpleDateFormat("yy-MM-dd");

Date date = sf.parse(sdate);

Timer timer = new Timer();

timer.schedule(new TimerTask() {

    @Override

    public void run() {

        System.out.println("系统正在运行……");

    }

}, date); //在指定的日期运行一次定时任务

注:如果date日期在今天之前,则启动定时器后,立即运行一次定时任务run方法;如果date日期在今天之后,则启动定时器后,会在指定的将来日期运行一次任务run方法

③在距当前时刻的一段指定距离后,每隔指定时间运行一次定时器任务

Timer timer = new Timer();

timer.schedule(new TimerTask() {

    @Override

    public void run() {

        System.out.println("系统正在运行……");

    }

}, 5000, 2000);

当启动定时器后,5s之后开始每隔2s执行一次定时器任务。

停止的方法:

timer.cancel();

 

3.ScrollView fillViewport属性

为了屏幕适配,包含多元素的布局一般都会使用ScrollView,以便小屏手机滑动查看,但是在大屏手机上内容全部加载,导致下方空白。

android:fillViewport="true" 是一个布局属性,它用于在ScrollView中填充视图的高度,以便在内容不足以填满屏幕时也能填充整个屏幕。这个属性只适用于ScrollView或其子类。当ScrollView中的内容小于屏幕高度时,如果不设置该属性,ScrollView不会填充整个屏幕,而是只显示其内容所占的部分。而当设置了该属性后,ScrollView会将其内容拉伸至填满整个屏幕,使得用户在浏览内容时不会出现界面空白的情况。

需要注意的是,android:fillViewport="true"只会在ScrollView的内容不足以填满整个屏幕时起作用,如果内容已经填满了整个屏幕,则该属性不会有任何作用。

比如下图,我们希望最后的Button是置底的,同时是可以跟随滑动的。

7809052ab9084a8a82118b4caec5a0df.png

由于子布局高度小于ScrollView的高度,定义子布局match_parent或者fill_parent不起作用,因此设置layout_gravity也不起作用。此时只需要在scrollview里添加属性android:fillViewport=”true” 就可以了,使得子布局高度和scrollview一样,而当子布局高度超过scrollview的高度时,这个属性就没有意义了。

 

4.按钮模拟点击performClick()无效

原因:开发过程中遇到button.performClick()无效,原因是View.performClick()需要在UI线程中调用才会有效执行。

响应系统调用的方法(比如报告用户动作的onKeyDown()或一个生命周期回调方法)永远在界面线程中进程,所以onCreate里面调用button的performClick没问题, 而通过code直接调用相当于是代码执行,并不会触发android的UI线程。

两个解决方法:

①View.post(Runnable)方法

View.postDelayed(new Runnable(){

    @Override

    public void run() {

        button.performClick();

    }

}, 1000);

在post(Runnable action)方法里,View获得当前线程(即UI线程)的Handler,然后将action对象post到Handler里。在Handler里,它将传递过来的action对象包装成一个Message(Message的callback为action),然后将其投入UI线程的消息循环中。在Handler再次处理该Message时,有一条分支(未解释的那条)就是为它所设,直接调用runnable的run方法。而此时,已经路由到UI线程里,因此,我们可以毫无顾虑的来更新UI。

②Activity.runOnUiThread(Runnable)方法

Activity.runOnUiThread(new Runnable() {

    @Override

    public void run() {

        button.performClick();

    }

});

把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThread(Runnable)。 这样Runnable对像就能在ui程序中被调用。如果当前线程是UI线程,那么行动是立即执行;如果当前线程不是UI线程,操作是发布到事件队列的UI线程。

 

5.adb命令启动Activity 

①不带参数启动Activity

adb shell am start -n com.app.test/.MainActivity

②带参数的启动Activity

adb shell am start -n com.app.test/.MainActivity --ei start_index 1  --es str "hello"

表示启动Activity并传递两个参数:

第一个参数是start_index,整型,值为1;第二个参数是str,字符串,值为"hello"

等同于Java代码:

  Intent intent= new Intent();

  intent.setComponent(new ComponentName("com.app.test", "com.app.test.MainActivity"));

  intent.putExtra("start_index", 1); 

③指定Action

adb shell am start -a android.intent.action.MAIN -n com.app.test/.MainActivity --ei start_index 1

④指定category

adb shell am start -c android.intent.category.LAUNCHER -n com.app.test/.MainActivity --ei start_index 1

⑤同时指定action和category都可以

adb shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n com.app.test/.MainActivity --ei start_index 1

对应命令的介绍:

-a action;activity对应的action;

--es key stringValue; 传递 String 参数;

--ez key booleanValue; 传递 Boolean 参数;

--ei key intValue; 传递 int 参数;

--el key longValue; 传递 long 参数;

--ef key floatValue; 传递 float 参数;

 

6.compileSdkVersion、buildToolsVersion、minSdkVersion和targetSdkVersion的含义

①compileSdkVersion和minSdkVersion比较容易理解,compileSdkVersion表示当前项目的编译版本,即你想让AndroidStudio以什么SDK版本去编译你的项目,minSdkVersion表示当前项目支持的最低安卓系统版本。

②buildToolsVersion是指构建工具的SDK版本,也就是AndroidStudio中设置的AndroidSDK版本,buildToolsVersion要高于compileSdkVersion版本,这个很好理解,如果编译版本高于AndroidStudio的SDK版本,那AndroidStudio怎么给项目编译呢?

③targetSdkVersion是指当前app的目标sdk版本,可以理解为当前app在这个版本是比较稳定的,针对这个版本所开发的,是安卓提供的前向兼容的主要手段。当targetSdkVersion为20的app运行在系统版本号高于20的手机系统中,app所执行的旧版本api在高版本可能不一样了,但是安卓为了兼容,在系统层会读取当前应用的targetSdkVersion,当targetSdkVersion版本号低于当前版本就会执行旧版本的api,不会导致由于系统的原因而让app运行失常。

注意:compileSdkVersion和buildToolsVersion作用于项目的编译,minSdkVersion和targetSdkVersion控制项目的运行版本。

一般compileSdkVersion设置为最新的SDK版本比较好,compileSdkVersion的作用就是可以让我们在编码的过程中编译器以最新SDK的api去要求我们的编码,它会有最新的一些提醒和异常,compileSdkVersion版本调高还有一个好处就是当app中有其他第三方sdk或者supperLib时,compileSdkVersion低于这些库的编译版本时就无法编译打包。

同样,targetSdkVersion设置为最新的版本最好,因为不需要让系统对app进行前向兼容了,同时也可以使用高版本的一些新特性。在开发过程中如果需要用到高版本的api但是又不想去改动项目中的代码时可以把compileSdkVersion版本调到新版本,targetSdkVersion保持不变就可以,编译版本让你可以调用高版本的api,但是在高版本运行时旧的api由于targetSdkVersion的原因而正常运行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值