Android.Hacks读书笔记01
#1#权重布局之解析:
LinearLayout ’s android:weightSum LinearLayout ’s child android:layout_weight
兼容适配的时候,比较方便:
Defines the maximum weight sum. If unspecified, the sum is computed by adding the layout_weight of all of the children. This can be used for instance to give a single child 50% of the total available space by giving it a layout_weight of 0.5 and setting the weightSum to 1.0.
简单小Demo:
<?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:background="#FFFFFF" android:gravity="center" android:orientation="horizontal" android:weightSum="1"> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.5" android:text="Click me"/> </LinearLayout>
至于为什么要把Button的宽度设置为0dp,是因为,在绘制界面的时候,会根据权重算出宽度然后再加上Button的宽度,求出的和才是Button的实际宽度,计算公式如下:
Button's width + Button's weight * 200 / sum(weight)
Because the Button ’s width is 0dp , the Button ’s weight is 0.5 . With the sum(weight)
set to 1 , the result would be the following:(假设屏幕宽度为200)
0 + 0.5 * 200 / 1 = 100
参考链接:http://developer.android.com/reference/android/view/View.html
#2# 避免重复写一些共性布局,用<include>实现
比较简单,小Demo如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center_horizontal" android:text="@string/hello"/> <include layout="@layout/footer_with_layout_properties"/> </RelativeLayout/>
And the footer_with_layout_properties would look like the following:
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="30dp" android:gravity="center_horizontal" android:text="@string/footer_text"/>
注意:如果父布局是相对布局,而<include>里面是线性布局,那么有可能属性会冲突,那就把<include>的xml文件的layout_.. 属性,写在<include width.. height...>
即可实现预期的效果。
#3# ViewStub
用ViewStub类和在XML文件里面指定的布局资源文件关联起来,让布局资源文件在需要使用的时候再加载上去。主要作用是性能优化,什么时候用什么时候加载,不用在开始启动的时候一次加载,既可以加快程序的启动速度,又可以节省内存资源
小Demo:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:onClick="onShowMap" android:text="@string/show_map" /> <ViewStub android:id="@+id/map_stub" android:layout_width="fill_parent" android:layout_height="fill_parent" android:inflatedId="@+id/map_view" android:layout="@layout/map" /> <include android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="30dp" layout="@layout/footer" /> </RelativeLayout>
布局比较简单,看不出优化效果,如果布局很复杂的话,那么优化性能就会很明显。
#4# 自定义viewgroup,以及PreferenceCategory的使用
首先要熟悉viewgroup在屏幕显示,绘制的过程,首先执行pass.
通过2次view tree的遍历,把整个界面的绘制完成。
自定义控件参见源码即可。
--------------PreferenceCategory------Android配置界面的使用,比较简单实用。
TypedArray实例是个属性的容器,context.obtainStyledAttributes()方法返回得到。AttributeSet是节点的属性集合
android.content.res.TypedArray
包含函数 obtainStyledAttributes(AttributeSet, int[], int, int) 或者 obtainAttributes(AttributeSet, int[])检索的数组值。
在执行完之后,一定要确保调用 recycle()函数 。用于检索从这个结构对应于给定的属性位置到obtainStyledAttributes中的值。
涉及的函数介绍:
obtainStyledAttributes(AttributeSet, int[], int, int)或者
obtainAttributes(AttributeSet, int[])
定义:
public TypedArray obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
public TypedArray obtainAttributes (AttributeSet set, int[] attrs)(说明此函数)
说明:返回一个由AttributeSet获得的一系列的基本的属性值,不需要用用一个主题或者/和样式资源执行样式。
参数:
set:现在检索的属性值;
attrs:制定的检索的属性值
public void recycle()
返回先前检索的数组,稍后再用。
/*******************************************************************************
* Copyright (c) 2012 Manning
* See the file license.txt for copying permission.
******************************************************************************/
package com.manning.androidhacks.hack004;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.net.Uri;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
public class MainActivity extends PreferenceActivity implements
OnSharedPreferenceChangeListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
Preference sharePref = findPreference("pref_share");
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Check this app!");
shareIntent.putExtra(Intent.EXTRA_TEXT,
"Check this awesome app at: ...");
sharePref.setIntent(shareIntent);
Preference ratePref = findPreference("pref_rate");
Uri uri = Uri.parse("market://details?id=" + getPackageName());
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
ratePref.setIntent(goToMarket);
updateUserText();
}
@Override
protected void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
if (key.equals("pref_username")) {
updateUserText();
}
}
private void updateUserText() {
EditTextPreference pref;
pref = (EditTextPreference) findPreference("pref_username");
String user = pref.getText();
if (user == null) {
user = "?";
}
pref.setSummary(String.format("Username: %s", user));
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2012 Manning
See the file license.txt for copying permission.
-->
<PreferenceScreen
xmlns:andro
android:key="pref_first_preferencescreen_key"
android:title="Preferences">
<PreferenceCategory
android:title="User">
<EditTextPreference
android:key="pref_username"
android:summary="Username:"
android:title="Username"/>
</PreferenceCategory>
<PreferenceCategory
android:title="Application">
<Preference
android:key="pref_rate"
android:summary="Rate the app in the store!"
android:title="Rate the app"/>
<Preference
android:key="pref_share"
android:summary="Share the app with your friends"
android:title="Share it"/>
<com.manning.androidhacks.hack004.preference.EmailDialog
android:dialogIcon="@drawable/ic_launcher"
android:dialogTitle="Send Feedback"
android:dialogMessage="Do you want to send an email with feedback?"
android:key="pref_sendemail_key"
android:negativeButtonText="Cancel"
android:positiveButtonText="OK"
android:summary="Send your feedback by e-mail"
android:title="Send Feedback"/>
<com.manning.androidhacks.hack004.preference.AboutDialog
android:dialogIcon="@drawable/ic_launcher"
android:dialogTitle="About"
android:key="pref_about_key"
android:negativeButtonText="@null"
android:title="About"/>
</PreferenceCategory>
</PreferenceScreen>
详细参考代码见Android.Hack,系列源码==========================================================================