第三天,就是做一些界面布局,Fragment和Activity的跳转,数据传递来实现分组的创建和添加联系人。
不多说,下面是我完成后的app的截图。
主界面(已经创建了一个test分组):
分组的操作:
给分组追加联系人:
编辑短信:
给分组test发送短信:
发送成功:
发送的短信(在短信内容的最前面加上了联系人名字):
第三天,就是做一些界面布局,Fragment和Activity的跳转,数据传递来实现分组的创建和添加联系人。
不多说,下面是我完成后的app的截图。
主界面(已经创建了一个test分组):
分组的操作:
给分组追加联系人:
编辑短信:
给分组test发送短信:
发送成功:
发送的短信(在短信内容的最前面加上了联系人名字):
1. Linear Layout中的weight和gravity的作用。
先看看下面的例子:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="vertical" >
<EditText
android:layout_width="100dp"
android:gravity="right"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/to" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/subject" />
<EditText
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="10"
android:gravity="bottom"
android:hint="@string/message" />
<Button
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="@string/send" />
</LinearLayout>
效果是:
从上图可以知道,weight的计算方法是:
1+1+2=4,所有第一个EditText会占总空间(除过最后一个EditText)的25%,第二个也是25%,第三个是50%。
gravity的作用是View的内容的显示方式是从哪里开始。
(Specifies how an object should position its content, on both the X and Y
axes, within its own bounds. )
http://developer.android.com/reference/android/widget/LinearLayout.html
2. Relative layout中的参数
Attribute Name | Related Method | Description
android:layout_above
| | Positions the bottom edge of this view above the given anchor view ID.
android:layout_alignBaseline
| | Positions the baseline of this view on the baseline of the given anchor
view ID.
android:layout_alignBottom
| | Makes the bottom edge of this view match the bottom edge of the given
anchor view ID.
android:layout_alignEnd
| | Makes the end edge of this view match the end edge of the given anchor
view ID.
android:layout_alignLeft
| | Makes the left edge of this view match the left edge of the given anchor
view ID.
android:layout_alignParentBottom
| | If true, makes the bottom edge of this view match the bottom edge of the
parent.
android:layout_alignParentEnd
| | If true, makes the end edge of this view match the end edge of the
parent.
android:layout_alignParentLeft
| | If true, makes the left edge of this view match the left edge of the
parent.
android:layout_alignParentRight
| | If true, makes the right edge of this view match the right edge of the
parent.
android:layout_alignParentStart
| | If true, makes the start edge of this view match the start edge of the
parent.
android:layout_alignParentTop
| | If true, makes the top edge of this view match the top edge of the
parent.
android:layout_alignRight
| | Makes the right edge of this view match the right edge of the given
anchor view ID.
android:layout_alignStart
| | Makes the start edge of this view match the start edge of the given
anchor view ID.
android:layout_alignTop
| | Makes the top edge of this view match the top edge of the given anchor
view ID.
android:layout_alignWithParentIfMissing
| | If set to true, the parent will be used as the anchor when the anchor
cannot be be found for layout_toLeftOf, layout_toRightOf, etc.
android:layout_below
| | Positions the top edge of this view below the given anchor view ID.
android:layout_centerHorizontal
| | If true, centers this child horizontally within its parent.
android:layout_centerInParent
| | If true, centers this child horizontally and vertically within its
parent.
android:layout_centerVertical
| | If true, centers this child vertically within its parent.
android:layout_toEndOf
| | Positions the start edge of this view to the end of the given anchor
view ID.
android:layout_toLeftOf
| | Positions the right edge of this view to the left of the given anchor
view ID.
android:layout_toRightOf
| | Positions the left edge of this view to the right of the given anchor
view ID.
android:layout_toStartOf
| | Positions the end edge of this view to the start of the given anchor
view ID.
http://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams.html
http://developer.android.com/guide/topics/ui/declaring-layout.html
有时你使用Eclipse创建完成Android工程后,会需要更改support,你可以参见这里:
libs/
directory in the root of your application project. <sdk>/extras/android/support/v4/android-support-v4.jar
) into your application’s project libs/
directory. https://developer.android.com/tools/support-library/setup.html
简单的说,Fragment就是Activity中的小“Activity”,它可以使你在一个Activity中实现多个panel的布局。
以下是Fragment的以下topic:
Add a Fragment to an Activity using XML
Add a Fragment to an Activity at Runtime
Replace One Fragment with Another
Deliver a Message to a Fragment
http://developer.android.com/guide/components/fragments.html
PS:但是我现在对Activity vs Fragment的关系还是不太理解。
PPS:如果你要替换Fragment的话,你可以参加:
一句话来说,R.java就是你的资源的别名,这个别名可以在java中直接使用,你不必理会它是图片,文件。它就是一个int值。
Once you provide a resource in your application (discussed in Providing
Resources),
you can apply it by referencing its resource ID. All resource IDs are defined
in your project’s R class, which the aapt tool automatically generates.
http://developer.android.com/guide/topics/resources/accessing-resources.html
http://www.satyakomatineni.com/akc/display?url=displaynoteimpurl&ownerUserId=satya&reportId=2883
http://www.yugandroid.in/android-tutorials/r-java-file.html
第二天就是你要做的app的实现了。
我想做的app是短信群发,这个app要有功能:
1. 分组功能,组可以增加,删除,重命名,给组中追加联系人/删除联系人;
2. 短信可以发给某一个分组或者所有的联系人,在发送短信之前要加上联系人的名字;
3. 分组信息要持久化
从需求来看这里比较重要的就是获得联系人信息和发送短信;
然后google android get all contact 和 android send message就可以找到相应的代码段来实现这两个功能。
以下是我现在的代码中使用的code:
获得所有的联系人:
public static List<Contact> getAllContact(ContentResolver cr) {
List<Contact> contacts = new ArrayList<Contact>();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if(cur.getCount() <= 0) {
return contacts;
}
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Contact contact = new Contact();
contact.name = name;
if (Integer.parseInt(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?", new String[] { id }, null);
while (pCur.moveToNext()) {
String phoneNo = pCur.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contact.telNumbers.add(phoneNo);
}
pCur.close();
}
contacts.add(contact);
}
return contacts;
}
发送短信:
private void sendMessage(Contact contact, String text) {
if (contact.telNumbers.size() <= 0) {
return;
}
String sms = "Hi, " + contact.name + ". " + text;
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(contact.telNumbers.get(0), null, sms, null, null);
contact.isSend = true;
} catch (Exception e) {
contact.isSend = false;
}
}
下面是我第一天完成后的界面:
发送的结果:
上次朋友推荐我去西安华为终端,然后HR打电话和我聊,问我有没有Android的开发经验,我说没有,然后就没有给我面试机会。
这里我很是不忿,为什么没有相关的经验,就不能做相关的事情呢?当然我承认没有经验的别有经验的人在刚开始干活的时候,
会有差别,但是难道经验是万能的,难道跨界这么难?
我在这里说三天开发一个app,不是想说明Android开发很简单,也没有黑华为的意思。只是想说明相关开发经验有没有都可以,
只要你这个人的学习能力比较强就好。
分割线————————————————————————————————————————————————–
第一天
从Android的官网下载带ADT的Eclipse,如果你的网络不给力的话,会花费一段时间;
http://developer.android.com/sdk/index.html
然后就是按照官网的教材,熟悉一下什么是模拟器,什么是Android SDK管理器,什么是Android工程,然模拟器运行起来;
然后根据官网的教材,作出自己的第一个app;
http://developer.android.com/training/basics/firstapp/index.html
因为我一直使用Eclipse进行开发,所以花费的时间比较短,加上下载ADT的时间4+小时。
PS:Android用Eclipse做开发已经不错了,为什么官方还在做IntelliJ IDEA?
PPS:刚开始不要管各种概念,先将第一个app完成后,然后再开一下整体的开发流程就差不多了。
见下图:
昨天不小心将管理短信的进程强制停止后,出现短信界面打不开,一直提示通”讯录已停止运行“。
在网上搜索了一下,有很多人遇到了同样的问题,但是最后都没有给出明确的答案。
这里给处我的解决方法(其他的清除通讯录的缓存,重启机器等都不行): 恢复出厂设置/Reset factory。
The argument list should be exactly the same as that of the overridden method.
参数列表必须一致
The return type should be the same or a subtype of the return type declared in the original overridden method in the superclass.
return的类型可以一样,或者子类returen的类型是父类的子类
The access level cannot be more restrictive than the overridden method’s access level. For example: if the superclass method is declared public then the overridding method in the sub class cannot be either private or protected.
访问级别只能比父类的更宽松;Java中的访问级别从高到低依次是:public, package level(具体使用时什么都不写),protected, private
Instance methods can be overridden only if they are inherited by the subclass.
实例方法只能覆盖从父类继承的方法
A method declared final cannot be overridden.
final方法不能被覆盖
A method declared static cannot be overridden but can be re-declared.
static方法不能被覆盖,但是可以被重新声明
If a method cannot be inherited, then it cannot be overridden.
如果方法不能继承,方法野不能覆盖
A subclass within the same package as the instance’s superclass can override any superclass method that is not declared private or final.
如果子类扶父类在同一个包下,子类可以覆盖父类的所以非private或final的方法
A subclass in a different package can only override the non-final methods declared public or protected.
如果子类扶父类在不同的包下,子类可以覆盖父类的所以非final同时public/protected的方法
An overriding method can throw any uncheck exceptions, regardless of whether the overridden method throws exceptions or not. However the overriding method should not throw checked exceptions that are new or broader than the ones declared by the overridden method. The overriding method can throw narrower or fewer exceptions than the overridden method.
不管父类有没有抛出异常,子类覆盖的方法可以抛出不检查的异常;如果父类抛出了异常,那么子类覆盖的方法只能抛出比父类范围更小的异常
Constructors cannot be overridden.
构造函数不能覆盖
如果对上面的说明还是不理解,可以参加下面的例子:
1. 父类
public class TestA {
protected void test1(int a, int b) {
System.out.println("supper");
return;
}
protected long test2(int a, int b) {
System.out.println("supper");
return 0;
}
protected TestB test3(int a, int b) {
System.out.println("supper");
return null;
}
protected TestA test4(int a, int b) {
System.out.println("supper");
return null;
}
protected TestA test5(int a, int b) {
System.out.println("supper");
return null;
}
protected TestA test6(int a, TestA b) {
System.out.println("supper");
return null;
}
protected TestA test6(int a, int b) {
System.out.println("supper");
return null;
}
protected static TestA test7(int a, int b) {
System.out.println("supper");
return null;
}
protected TestA test8(int a, int b) {
System.out.println("supper");
return null;
}
protected TestA test9(int a, int b) throws Exception{
System.out.println("supper");
return null;
}
protected TestA test10(int a, int b) throws NullPointerException{
System.out.println("supper");
return null;
}
protected static TestA test11(int a, int b) {
System.out.println("supper");
return null;
}
}
2. 子类
public class TestB extends TestA{
@Override
public void test1(int a, int b) {
System.out.println("sub");
return;
}
@Override
public long test2(int a, int b) {
System.out.println("sub");
return 0;
}
// fail
// @Override
// protected TestA test3(int a, int b) {
// System.out.println("sub");
// return null;
// }
@Override
protected TestB test3(int a, int b) {
System.out.println("sub");
return null;
}
@Override
protected TestB test4(int a, int b) {
System.out.println("sub");
return null;
}
@Override
public TestB test5(int a, int b) {
System.out.println("sub");
return null;
}
// fail
// @Override
// protected TestA test6(int a, TestB b) {
// System.out.println("sub");
// return null;
// }
@Override
protected TestA test6(int a, TestA b) {
System.out.println("sub");
return null;
}
@Override
protected TestA test6(int a, int b) {
System.out.println("sub");
return null;
}
// fail: This instance method cannot override the static method
// protected TestA test7(int a, int b) {
// System.out.println("sub");
// return null;
// }
// fail: can not throw checked exception
// @Override
// protected TestA test8(int a, int b) throws Exception {
// System.out.println("sub");
// return null;
// }
@Override
protected TestA test8(int a, int b) throws NullPointerException {
System.out.println("sub");
return null;
}
// fail:Exception Throwable is not compatible with throws
// clause in TestA.test8(int, int)
// @Override
// protected TestA test8(int a, int b) throws Throwable {
// System.out.println("sub");
// return null;
// }
// OK
// @Override
// protected TestA test9(int a, int b) throws Exception{
// System.out.println("sub");
// return null;
// }
// OK
// @Override
// protected TestA test9(int a, int b) throws Error{
// System.out.println("sub");
// return null;
// }
@Override
protected TestA test9(int a, int b) throws NullPointerException{
System.out.println("sub");
return null;
}
// fail
// @Override
// protected TestA test9(int a, int b) throws Throwable{
// System.out.println("sub");
// return null;
// }
@Override
protected TestA test10(int a, int b) throws NullPointerException{
System.out.println("sub");
return null;
}
// fail
// @Override
// protected TestA test10(int a, int b) throws Exception{
// System.out.println("sub");
// return null;
// }
protected static TestA test11(int a, int b) {
System.out.println("supper");
return null;
}
}
http://www.tutorialspoint.com/java/java_overriding.htm
http://docs.oracle.com/javase/tutorial/java/IandI/override.html