Android 学习笔记 – 第四天

ListView

Adapter 的概念。这里可以参考 Head First Design Patterns 的相关部分进行理解。

然后遇到了个蛋疼的监听器报错事件不存在的问题。。。返回去先看 java 好了。。。

 

Head First JAVA

布局。FlowLayout 从左到右,从上到下依次摆放组件,在空间不足时,自动换行到下一行,默认的代码测试没有效果,通过 setPreferredSize(new Dimension(int width, int height)) 来控制 Jpanel 的大小后,可以看到确实换行了。

Android 学习笔记 – 第三天

UI 界面

HelloWorld 中的 TextView ,使用 android:gravity 属性设置居中属性无效,设置后仍然是靠左显示(布局为 LinearLayout, orientation=”vertical” )。

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="Hello World!" />

这是由于在 android:layout_width 中设置的属性为 wrap_content,这样显示的时候,TextView 的宽度应该是正好包裹着 Text 的。所以导致了这时候不论是何种 gravity ,看起来都一样。将 layout_width 属性修改为 match_parent 后,则默认宽度匹配父级组件,这样就能看到效果了。

<TextView
    android:layout_width="<strong>match_parent</strong>"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="Hello World!" />

android:textSize=”24sp”. 这里涉及到几个单位的问题。官网文档链接。还可以参考 StackOverflow 的一个答案,里面给出了具体的转换表。一般推荐字体使用 sp 单位,像素使用 dp 单位,便于各种不同分辨率的屏幕的适配。

ImageView

按照 demo 做到 imageView.setImageResource(R.drawable.picname) 这一步时,编译报错 no marked region found along edge,这个是由于拷贝过去的外部图片文件夹中带有一张 more.9.png 图片,.9.png 是 android 平台中的一种特殊格式文件,具体可以参考这篇文章。这个报错是由于使用的这张 .9.png 图片中缺少了定位区域导致的。 Android Studio 中已经集成了 .9.png 图片编辑工具,在 AS 中双击打开目标图片文件,加黑边编辑后,重新编译,报错 can’t have more than one marked region along edge,这是由于在编辑时候侧边加了两段黑色标记区域,再次修改后,编译正常。

FrameLayout 后面加载的组件会覆盖在前面加载的组件上。

从头写 layout 的 xml 文件,layout 类型后面总是跟着

xmlns:android="http://schemas.android.com/apk/res/android

,查了一下,这个 URI 主要和 java 中的 package 的概念差不多,主要是为了标识 xml 文件,具体可以看下面的这一段说明(源地址):

In XML, xmlns declares a Namespace. In fact, when you do:

<LinearLayout android:id>
</LinearLayout>

Instead of calling android:id, the xml will use http://schemas.android.com/apk/res/android:id to be unique. Generally this page doesn’t exist (it’s a URI, not a URL), but sometimes it is a URL that explains the used namespace.

The namespace has pretty much the same uses as the package name in a Java application.

Here is an explanation.

Uniform Resource Identifier (URI)

A Uniform Resource Identifier (URI) is a string of characters which identifies an Internet Resource.

The most common URI is the Uniform Resource Locator (URL) which identifies an Internet domain address. Another, not so common type of URI is the Universal Resource Name (URN).

In our examples we will only use URLs.

layout_gravity 和 gravity 的区别:

gravity 这个英文单词是重心的意思,在这里就表示停靠位置的意思(参考文章)。

android:layout_gravity 和 android:gravity 的区别

从名字上可以看到,android:gravity是对元素本身说的,元素本身的文本显示在什么地方靠着换个属性设置,不过不设置默认是在左侧的。

android:layout_gravity是相对与它的父元素说的,说明元素显示在父元素的什么位置。

比如说button: android:layout_gravity 表示按钮在界面上的位置。 android:gravity表示button上的字在button上的位置。

XML 使用 include 标签引入另一个 xml 文件的布局。测试 include 要放在控件位置前,放控件后并不会起效果。通过引入自定义控件也是一样,放前面才有效。若要绑定响应事件等,更适合使用自定义控件的方式。

Android 对于 XML 文件采用 PULL 方式进行解析。具体分析可以参考这篇文章

自定义控件部分的核心内容主要是 LayoutInflater 的使用,郭林在博客写过一篇很好的分析文章,介绍得很详细(链接地址)。先通过

 LayoutInflater layoutInflater = LayoutInflater.from(Context)

来获取到 LayoutInflater 实例。然后调用它的 inflate() 方法来加载布局。

layoutInflater.inflate(resourceId, root)

第一个参数是要加载的布局 ID, 第二个是给该布局的外面再嵌套一层父布局。若不需要父布局,可以传 null。

Android 学习笔记 – 第二天

从 Intent 部分开始。

Intent 分为显式 Intent 和隐式 Intent。

显式 Intent 重载 new Intent(Context packageContext, Class<?> cls) 构造函数(例子中重写 onClick() 方法),new Intent 后通过 startActivity() 方法启动目标活动。

隐式 Intent 指明的是 action 和 category 等信息,由系统分析后找出匹配的 Activity 来调用。在 AndroidManifest.xml 中,配置 <Activity> 标签下的 <intent-filter>,指定对应 Activity 所相应的 action 和 category。然后 Intent intent = new Intent(“%ACTION%”) ,intent.addCategory() 方法添加 category。 这里 category 里面写的路径貌似并没有严格规定,测试了一下只要和之前在 intent-filter 中对应的 category 一致即可调用。注意 <action> 和 <category> 需要同时匹配。但是 android.intent.category.DEFAULT 是默认的 category,调用 activity 时会自动将该 category 添加到 Intent 中。每个 Intent 只能指定一个 action,但 category 可以有多个。添加多个时会去 AndroidManifest.xml 中去找对应匹配的 Activity,全部条件满足(包含于) Activity 中定义的 action 和 category 属性,就能够成功调用特定的 Activity。

隐式 Intent 既可启动程序内 Activity,亦可启动其他程序的 Activity,从而可以实现多个应用程序的功能共享。例如调用系统浏览器,调用系统拨号盘等。

除了启动 Activity 外,还可以在启动 Activity 时传递数据

通过重载 putExtra() 方法向下一个活动传递数据,intent.putExtra(“dataname”, data) ,然后在下一个 Activity 中Intent intent = getIntent() ,String data = intent.getStringExtra(“dataname”)。这里遇到个问题,在虚拟机中跑时,Log.d(String, data) 在 LogCat 中能正常打印,但是在实体机上跑时,LogCat 中一直看不到信息。查阅资料后,通过以下方式解决:在拨号盘输入 *#*#2846579#*#* ,进入工程菜单,选择后台设置并将里面日志相关的部分功能打开,即可显示(顺便吐槽下华为手机真是渣渣!)。

返回数据给上一个活动。

Android 学习笔记 – 第一天

使用 Android Studio 配合着 《第一行代码》开始学习 Android。

Activity 的标题栏问题:

在 FirstActivity处遇到几个问题:AS里面运行后默认的效果就是没有标题栏,查了一下貌似也有其他人遇到该问题,但是也没有找到解决方法。文章下有一条评论“Android Studio New 一个Blank Activity时,默认基类为ActionBarActivity,其子类不支持requestWindowFeature(Window.FEATURE_NO_TITLE);将基类改为Activity ,即可”试了一下,将 FirstActivity.java 中 FirstActivity 类继承的Activity 改为 ActionBarActivity,标题栏就能显示了。但是提示 ActionBarActivity 已经 deprecated 了,按照建议修改为 AppCompatActivity ,仍然能显示带标题栏的效果。

然后到隐藏标题栏部分。按照书中所述在 super.onCreate(savedInstanceState); 语句后添加 requestWindowFeature(Window.FEATURE_NO_TITLE) 语句后,运行 app 无法启动,后台报错 android.util.AndroidRuntimeException: requestFeature() must be called before adding content。查询资料后,将以上两语句交换位置后,可以正常运行,但是标题栏仍然正常显示,并没有达到隐藏的效果。使用同一个帖子中推荐的 getActionBar.hide() 也会由于 NULL Object 报错。最后继续查阅资料,通过使用 getSupportActionBar().hide(); 实现了隐藏标题栏效果。

toast 部分知识点:
  1. 传 Context 上下文参数时用到了 类名.this. 想了一下应该是由于匿名内部类的原因。具体可以参考这篇匿名内部类的文章以及这篇关于类名.this的文章。
  2. public static Toast makeText (Context context, CharSequence text, int duration)。其中最后一个参数 int duration,可以看到有 Toast.LENGTH_SHORT 和 Toast.LENGTH_LONG,进去发现值分别是 0 和 1,具体的时间长度是 2500 和 3500 (ms),具体如何定位可以参考这篇文章
Menu部分:

这里有个地方比较坑,因为一直是在 FirstActivity 的基础上不断添加组件来实现的,前面已经实现了隐藏标题栏的效果,这时候加了菜单,如果是较新版本的手机,都没有菜单键了,而菜单栏默认一般都是集成在标题栏最右侧,以三个点表示。也就是说,调不出菜单栏了。最后通过安装虚拟键盘模拟菜单按钮的方式唤起菜单栏,才看到效果。

IntelliJ IDEA相关

括号相关:
() parentheses
[] brackets
{} braces
Ctrl + [ :移动光标到当前所在代码的花括号开始位置
Ctrl + ] :移动光标到当前所在代码的花括号结束位置
Ctrl + Shift + M :切换到代码段的开始或结束位置。

alt + Insert :自动添加 getter, setter

sout: 自动补全 System.out.println();
psvm: 自动补全 public static void main(String[] args){}

(eclipse): alt + shift + R:自动替换变量
(idea):shift+F6

Ctrl + Q : 查看方法说明文档

Ctrl + D :复制行 (eclipse 中为删除光标所在行)
Ctrl + X :  删除行

Ctrl + Alt + L : 格式化
(eclipse) : Ctrl + Shift + F

Ctrl + O : 选择可重写的方法
(eclipse): Alt + /

Alt + Insert:代码自动生成,如生成对象的 set / get 方法,构造函数,toString() 等

新建了一个 package ,包名为 enum,结果没法在里面新建 class 文件了,修改名字才可以。猜测这是因为如果包名有保留字的话,那么 class 前面在声明 package 时,package 的路径中就会出现保留字,这样就导致报错了。小细节,mark 一下。

今天 commit 的时候提示有 warning,看了一下原来是类的内部接口前面加了 static,而作为内部接口,默认就是静态的,因此对内部接口而言 static 修饰符就是冗余了。另外一个冗余,应该是 1.7 中的新特性,泛型不需要重复定义。mark 一记。

alt + up/down : 光标移动到上一个/下一个方法
ctrl + shift + up/down : 向上/向下移动方法块
ctrl + up/down :向上/向下滚动
ctrl + 加号(等号)/减号(连接符) : 展开/折叠代码

chrome清除地址栏中的某个特定网址

之前输入bing.com的时候不小心输成了bing.com_(万恶的输入法切换>.<),从此以后每次访问bing.com,由于浏览器的自动匹配都会匹配成带下划线后缀的错误地址,清除所有地址确实可破,但是如果这样的话,很多不是很频繁访问但是偶尔需要,偏偏又没有放入收藏夹的网址,再次访问时就会很麻烦。google 后找到一个解决方案,在错误的网址上使用 Shift + Delete 组合键,即可删除该特定网址。

Java中Math.random()和Random().nextInt(int)的区别

Math.random() uses Random.nextDouble() internally.

Random.nextDouble() uses Random.next() twice to generate a double that has approximately uniformly distributed bits in its manitissa, so it is uniformly distributed in the range 0 to 1-(2^-52).

Random.nextInt(n) uses Random.next() less than twice on average- it uses it once, and if the value obtained is above the highest multiple of n below MAX_INT it tries again, otherwise is returns the value modulo n (this prevents the values above the highest multiple of n below MAX_INT squewing the distribution), so returning a value which is uniformly distributed in the range 0 to n-1.

Prior to scaling by 6, the output of Math.random() is one of 2^52 possible values drawn from a uniform distribution.

Scaling by 6 doesn’t alter the number of possible values, and casting to an int then forces these values into one of six ‘buckets’ (0, 1, 2, 3, 45), each bucket corresponding to ranges encompassing either 1501199875790165 or 1501199875790166 of the possible values (as 6 is not a disvisor of 2^52). This means that for a sufficient number of dice rolls (or a die with a sufficiently large number of sides), the die will show itself to be biased towards the larger buckets.

You will be waiting a very long time rolling dice for this effect to show up.

Math.random() also requires about twice the processing and is subject to synchronization.

更多可以参考:http://stackoverflow.com/questions/738629/math-random-versus-random-nextintint

Head First Java 学习笔记

Chapter 9 Life and Death of an Object

  1. Java 有两种类型的内存空间: 堆(Heap)和栈(Stack)
  2. 在类中但不在方法中声明的变量称为实例变量(instance variable)
  3. 在方法内声明的变量,或者是作为方法参数声明的变量成为局部变量(local variable)
  4. 所有的局部变量(local variables)存活于栈中,具体位置是声明该变量的方法所对应的栈帧(stack frame)
  5. 对象引用变量(object reference variables)和基本变量(primitive variables)一样,如果被声明为局部变量,就会在栈中。
  6. 所有的对象都在堆中,无论引用它们的变量是本地变量还是局部变量。

 

Chapter 10 Numbers Matter

    1. 静态方法(static method) 应当通过类名(class name)来调用,而不是通过对象引用变量(object reference variable)来调用:
      Math.random() vs. myFoo.go()
    2. 静态方法能够在堆(heap)上没有该方法所在类(method’s class)的任何实例(instance)时被调用(invoke)。
    3. 静态方法是很好的实用方法(utility method)(A static method is good for a utility method), 不需要(也绝不会需要)依赖于特定的实例变量值(instance variable value).
    4. 静态方法并不与某个特定的对象——只有类——相关联,因此它并不能调用它的类中的任何实例变量值。因为它无法知道到底要调用的是哪个实例的值(instance’s value)。
    5. 静态方法不能调用非静态方法(non-static method),因为非静态方法经常与实例变量状态相联系。
    6. 如果你有某个类只有静态的方法,并且你不希望这个类被实例化(instantiate),你可以把构造器(constructor)标记为私有(private)。
    7. 静态变量(static variable)所给类的所有成员共享的变量。某个静态变量在一个类中只有一个,而不是实例变量的每个单独实例都有一个(rather than one copy per each individal instance for instance variables)。
    8. 静态方法能够调用静态变量。
    9. 可以通过将一个变量同时标记为静态(static)和final,从而将它定义为 java 中的常数。
    10. final类型的静态变量(final static variable)必须被赋一个值,而且赋值必须在它被声明时进行,或者在一个静态初始化器(static initializer)中进行。
      static {
      DOG_CODE = 420;
      }
    11. 常数(final static variable)的命名惯例:将名称全部大写。
    12. final 类型(final variable)变量一旦被赋值就不能改变。
    13. 对 final 类型的实例变量(final instance variable),要么在它被声明时赋值,要么在构造器中赋值。
    14. final 方法不能被重写(override)。
    15. final 类不能被继承(不能有子类)。

utility method:(参考自:http://c2.com/cgi/wiki?UtilityMethod)

 A (usually) static method. Used when you need to do stuff that does not need an instance of a class.Example: A math class has an add function. That function needs no state to operate on, only two numbers to add. It doesn’t need to touch any of the member / instance variables of the math class, so it’s preferable to make it static, rather than member. – MikleI don’t see the reason for such things to exist. In this example, surely “add” is something that numbers do, not “math”? That would make it a method of whatever number implementation is being used (eg. the “+” method in Smalltalk). If there could ever be an entity for representing such a vague and imprecise thing as “math”, I would surely say it’s a module. In general, “static” methods are an artefact of languages where classes and methods are not objects (Java, C++, etc.) – Warbo