<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>阳春面的学习摘录 &#187; Android</title>
	<atom:link href="http://chenyc.info/tag/android/feed/" rel="self" type="application/rss+xml" />
	<link>http://chenyc.info</link>
	<description>人生是一个不断折腾的过程，生命不息，折腾不止</description>
	<lastBuildDate>Mon, 06 Feb 2012 12:48:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Android LinearLayout根据状态切换图片(模拟按钮的效果）</title>
		<link>http://chenyc.info/2011/12/android_linearlayout_as_button/</link>
		<comments>http://chenyc.info/2011/12/android_linearlayout_as_button/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 14:58:23 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[LinearLayout]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=731</guid>
		<description><![CDATA[在Android中Button可以根据选中，点击等状态切换图片，我想用LinearLayout实现类似的功能， 但是默认情况下pressed状态“容器类”（继承于ViewGroup的类）是接收不到的， 所以LinearLayout的按下就没有效果，后来分析代码，可以通过设置setAddStatesFromChildren 方法获得内部View的状态，就可以取得pressed状态。 linearLayout.setAddStatesFromChildren(true); 还有一个相反的方法setDuplicateParentStateEnabled，内部类获得外部容器类的状态， 这个方法和setAddStatesFromChildren不能同时设置，同时设置会产生异常。]]></description>
			<content:encoded><![CDATA[<p><font size="2" face="宋体">在Android中Button可以根据选中，点击等状态切换图片，我想用LinearLayout实现类似的功能，</font></p>
<p><font size="2" face="宋体">但是默认情况下pressed状态“容器类”（继承于ViewGroup的类）是接收不到的，</font></p>
<p><font size="2"><font face="宋体">所以LinearLayout的按下就没有效果，后来分析代码，可以通过设置<span style="color: #0000ff">setAddStatesFromChildren</span></font></font></p>
<p><span style="color: #0000ff"></span><font size="2" face="宋体">方法获得内部View的状态，就可以取得pressed状态。</font></p>
<blockquote><p><span style="color: #0000ff"><font size="2" face="宋体">linearLayout.setAddStatesFromChildren(true);</font></span></p>
</blockquote>
<p><font size="2" face="宋体"></font></p>
<p><font size="2" face="宋体">还有一个相反的方法<span style="color: #0000ff">setDuplicateParentStateEnabled</span>，内部类获得外部容器类的状态，</font></p>
<p><font size="2" face="宋体">这个方法和<span style="color: #0000ff">setAddStatesFromChildren</span>不能同时设置，同时设置会产生异常。</font></p>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2011/12/android_linearlayout_as_button/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android layout布局相关的注意点</title>
		<link>http://chenyc.info/2011/12/android-layout%e5%b8%83%e5%b1%80%e7%9b%b8%e5%85%b3%e7%9a%84%e6%b3%a8%e6%84%8f%e7%82%b9/</link>
		<comments>http://chenyc.info/2011/12/android-layout%e5%b8%83%e5%b1%80%e7%9b%b8%e5%85%b3%e7%9a%84%e6%b3%a8%e6%84%8f%e7%82%b9/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 14:19:20 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[layout]]></category>
		<category><![CDATA[性能]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=726</guid>
		<description><![CDATA[1.不要过多的嵌套布局，特别是在ListView中需要重复获取的情况下。嵌套布局的情况可以采用RelativeLayout替代LinearLayout,减少嵌套层数。 2.可以采用SDK工具里的hierarchyviewer，分析layout的执行效率。 3.利用新版的ADT(adt1.6)的提示功能，纠正布局文件中影响性能的部分。 4.在采用LinearLayout布局时，尽量不要嵌套中使用layout_weight属性，这会导致所有的内部VIew执行两次measure. 5.对于公用的layout编写,可以采用&#60;merge&#62;作为父标签，这样include到其他layout中后，merge标签不会作为容器，可以减少layout层次。 &#60;merge xmlns:android=&#34;http://schemas.android.com/apk/res/android&#34;&#62; &#60;Button android:layout_width=&#34;fill_parent&#34; android:layout_height=&#34;wrap_content&#34; android:text=&#34;@string/add&#34;/&#62; &#60;Button android:layout_width=&#34;fill_parent&#34; android:layout_height=&#34;wrap_content&#34; android:text=&#34;@string/delete&#34;/&#62; &#60;/merge&#62; 6.采用ViewStub按需加载View &#60;ViewStub     android:id=&#34;@+id/stub_import&#34;     android:inflatedId=&#34;@+id/panel_import&#34;     android:layout=&#34;@layout/progress_overlay&#34;     android:layout_width=&#34;fill_parent&#34;     android:layout_height=&#34;wrap_content&#34;     android:layout_gravity=&#34;bottom&#34; /&#62; 加载方法： View importPanel &#8230; <a href="http://chenyc.info/2011/12/android-layout%e5%b8%83%e5%b1%80%e7%9b%b8%e5%85%b3%e7%9a%84%e6%b3%a8%e6%84%8f%e7%82%b9/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>1.不要过多的嵌套布局，特别是在ListView中需要重复获取的情况下。嵌套布局的情况可以采用<code><a href="http://developer.android.com/reference/android/widget/RelativeLayout.html">RelativeLayout</a>替代<a href="http://developer.android.com/reference/android/widget/LinearLayout.html">LinearLayout</a>,减少嵌套层数。</code></p>
<p>2.可以采用SDK工具里的<code>hierarchyviewer，分析layout的执行效率。</code></p>
<p><img src="http://developer.android.com/images/training/hierarchy-linearlayout.png" alt="" /></p>
<p><img src="http://developer.android.com/images/training/hierarchy-layouttimes.png" alt="" /></p>
<p>3.利用新版的ADT(adt1.6)的提示功能，纠正布局文件中影响性能的部分。</p>
<p>4.在采用<a href="http://developer.android.com/reference/android/widget/LinearLayout.html">LinearLayout</a>布局时，尽量不要嵌套中使用layout_weight属性，这会导致所有的内部VIew执行两次measure.</p>
<p>5.对于公用的layout编写,可以采用&lt;merge&gt;作为父标签，这样include到其他layout中后，merge标签不会作为容器，可以减少layout层次。</p>
<pre>&lt;merge xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;

&lt;Button
android:layout_width=&quot;fill_parent&quot;
android:layout_height=&quot;wrap_content&quot;
android:text=&quot;@string/add&quot;/&gt;

&lt;Button
android:layout_width=&quot;fill_parent&quot;
android:layout_height=&quot;wrap_content&quot;
android:text=&quot;@string/delete&quot;/&gt;

&lt;/merge&gt;</pre>
<p>6.采用ViewStub按需加载View</p>
<pre>&lt;ViewStub
    android:id=&quot;@+id/stub_import&quot;
    android:inflatedId=&quot;@+id/panel_import&quot;
    android:layout=&quot;@layout/progress_overlay&quot;
    android:layout_width=&quot;fill_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:layout_gravity=&quot;bottom&quot; /&gt;</pre>
<p>加载方法：</p>
<pre>
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();
</pre>
<p>加载完成后，ViewStub的Id就不再有效了</p>
<p>7.在ListView中采用ViewHolder保存View的引用，不要重复使用findViewById方法，<br />
这样可加快执行的性能。</p>
<pre>
ViewHolder holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);
holder.text = (TextView) convertView.findViewById(R.id.listitem_text);
holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);
holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);
convertView.setTag(holder);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2011/12/android-layout%e5%b8%83%e5%b1%80%e7%9b%b8%e5%85%b3%e7%9a%84%e6%b3%a8%e6%84%8f%e7%82%b9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>不让ScrollView自动切换子View的焦点</title>
		<link>http://chenyc.info/2011/11/scrollview-dont-change-childview-foucs/</link>
		<comments>http://chenyc.info/2011/11/scrollview-dont-change-childview-foucs/#comments</comments>
		<pubDate>Wed, 02 Nov 2011 04:31:00 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[ScrollView]]></category>

		<guid isPermaLink="false">http://chenyc.info/2011/11/%e4%b8%8d%e8%ae%a9scrollview%e8%87%aa%e5%8a%a8%e5%88%87%e6%8d%a2%e5%ad%90view%e7%9a%84%e7%84%a6%e7%82%b9-2/</guid>
		<description><![CDATA[在开发中，在同一个Activity中有多个输入框，不想让ScrollView自动切换EditText的焦点， 需要继承ScrollView,重写onRequestFocusInDescendants方法,然后在layout中使用自定义的ScrollView即可。 public class NonFocusingScrollView extends ScrollView { public NonFocusingScrollView(Context context) { super(context); } public NonFocusingScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public NonFocusingScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected boolean onRequestFocusInDescendants(int direction, &#8230; <a href="http://chenyc.info/2011/11/scrollview-dont-change-childview-foucs/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>在开发中，在同一个Activity中有多个输入框，不想让ScrollView自动切换EditText的焦点，<br />
需要继承ScrollView,重写onRequestFocusInDescendants方法,然后在layout中使用自定义的ScrollView即可。</p>
<pre>
public class NonFocusingScrollView extends ScrollView {

    public NonFocusingScrollView(Context context) {
        super(context);
    }

    public NonFocusingScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NonFocusingScrollView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected boolean onRequestFocusInDescendants(int direction,
            Rect previouslyFocusedRect) {
        return true;
    }

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2011/11/scrollview-dont-change-childview-foucs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>我的豆瓣V1.0发布</title>
		<link>http://chenyc.info/2011/03/mydouban-v1-0/</link>
		<comments>http://chenyc.info/2011/03/mydouban-v1-0/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 16:19:00 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[dobuan]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=214</guid>
		<description><![CDATA[最近由于一些其他事情，没有空写“我的豆瓣”， 暂时移除掉我关注的人等功能，发布第一版先 详细请参考如下地址： http://chenyc.info/mydouban/]]></description>
			<content:encoded><![CDATA[<p>最近由于一些其他事情，没有空写“我的豆瓣”，</p>
<p>暂时移除掉我关注的人等功能，发布第一版先</p>
<p>详细请参考如下地址：</p>
<p><a href="http://chenyc.info/mydouban/">http://chenyc.info/mydouban/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2011/03/mydouban-v1-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>编写自己的ContentProvider</title>
		<link>http://chenyc.info/2010/03/create-contentprovider/</link>
		<comments>http://chenyc.info/2010/03/create-contentprovider/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 14:26:14 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[ContentProvider]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=108</guid>
		<description><![CDATA[刚开始看Android NotePad中的ContentProvider的实现时，看的云里雾里，但自己模仿写过一个后，才发现也就这么一回事，就是实现公用的增删改查。下面将需要实现的方法做一个简单的回顾： 1.一个ContentProvider可以实现对多个数据表的操作，但每一个数据表都需要有一个独立URI，也必须有一个独立的类型。URI是其他应用访问这个数据入口，比如： content://com.chenyc.timeaccount.provider/eventtypes/id 它包括4部分，content://就是固定的头部，com.chenyc.timeaccount.provider部分需要一个唯一的字符串，一般就用ContentProiver类所在的包名，eventtypes部分一般是指在这个ContentProvider下，你需要操作那种类型的数据，一般可以用表名来表示，id部分是指具体操作数据的_id，如果查询某一条数据，则id部分就是其在数据库中的_id字段的值。 每个数据表需要有一个独立的数据类型，需要在getType(Uri uri)中实现，返回一个唯一的字符串即可，比如：vnd.chenyc.cursor.dir/vnd.account.eventtype 2.query方法，查询作为最常用的方法，实现也很简单,projection参数代表要查那些列，selection是where条件部分，selectionArgs是where条件部分参数的值,sortOrder指排序，switch部分判断是查一条数据，还是查一个list,然后根据情况进行查询 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); switch (sUriMatcher.match(uri)) { case EVENT_TYPES: qb.setTables(EVENT_TYPE_TABLE_NAME); qb.setProjectionMap(sEventTypesProjectionMap); break; case EVENT_TYPE_ID: qb.setTables(EVENT_TYPE_TABLE_NAME); qb.setProjectionMap(sEventTypesProjectionMap); qb.appendWhere(EventTypeAdapter.KEY_ROWID + &#8230; <a href="http://chenyc.info/2010/03/create-contentprovider/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>刚开始看Android NotePad中的ContentProvider的实现时，看的云里雾里，但自己模仿写过一个后，才发现也就这么一回事，就是实现公用的增删改查。下面将需要实现的方法做一个简单的回顾：</p>
<p>1.一个ContentProvider可以实现对多个数据表的操作，但每一个数据表都需要有一个独立URI，也必须有一个独立的类型。URI是其他应用访问这个数据入口，比如：</p>
<p><a title="content://" href="content://">content://</a>com.chenyc.timeaccount.provider/eventtypes/id</p>
<p>它包括4部分，<a title="content://" href="content://">content://</a>就是固定的头部，com.chenyc.timeaccount.provider部分需要一个唯一的字符串，一般就用ContentProiver类所在的包名，eventtypes部分一般是指在这个ContentProvider下，你需要操作那种类型的数据，一般可以用表名来表示，id部分是指具体操作数据的_id，如果查询某一条数据，则id部分就是其在数据库中的_id字段的值。</p>
<p>每个数据表需要有一个独立的数据类型，需要在getType(Uri uri)中实现，返回一个唯一的字符串即可，比如：vnd.chenyc.cursor.dir/vnd.account.eventtype</p>
<p>2.query方法，查询作为最常用的方法，实现也很简单,projection参数代表要查那些列，selection是where条件部分，selectionArgs是where条件部分参数的值,sortOrder指排序，switch部分判断是查一条数据，还是查一个list,然后根据情况进行查询</p>
<pre>
public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {

		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		switch (sUriMatcher.match(uri)) {
		case EVENT_TYPES:
			qb.setTables(EVENT_TYPE_TABLE_NAME);
			qb.setProjectionMap(sEventTypesProjectionMap);
			break;
		case EVENT_TYPE_ID:
			qb.setTables(EVENT_TYPE_TABLE_NAME);
			qb.setProjectionMap(sEventTypesProjectionMap);
			qb.appendWhere(EventTypeAdapter.KEY_ROWID + "="
					+ uri.getPathSegments().get(1));
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		SQLiteDatabase db = mDbHelper.getReadableDatabase();
		Cursor c = qb.query(db, projection, selection, selectionArgs, null,
				null, sortOrder);
		c.setNotificationUri(getContext().getContentResolver(), uri);
		return c;
	}
</pre>
<p>3.delete方法，处理方式也跟查询差不多，也分删一个和删一批</p>
<pre>
public int delete(Uri uri, String where, String[] whereArgs) {
		SQLiteDatabase db = mDbHelper.getWritableDatabase();
		int count;
		switch (sUriMatcher.match(uri)) {
		case EVENT_TYPES:
			count = db.delete(EVENT_TYPE_TABLE_NAME, where, whereArgs);
			break;
		case EVENT_TYPE_ID:
			String id = uri.getPathSegments().get(1);
			count = db.delete(EVENT_TYPE_TABLE_NAME,
					EventTypeAdapter.KEY_ROWID
							+ "="
							+ id
							+ (!TextUtils.isEmpty(where) ? " AND (" + where
									+ ')' : ""), whereArgs);
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}
</pre>
<p>4.insert方法，插入成功后需要返回这条记录的URI</p>
<pre>
public Uri insert(Uri uri, ContentValues initialValues) {
		SQLiteDatabase db = mDbHelper.getWritableDatabase();
		long rowId = 0;
		Uri contentUri;
		switch (sUriMatcher.match(uri)) {
		case EVENT_TYPES:
			rowId = db.insert(EVENT_TYPE_TABLE_NAME, "null", initialValues);
			contentUri = TimeAccount.EVENT_TYPE_CONTENT_URI;
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		if (rowId > 0) {
			Uri returnUri = ContentUris.withAppendedId(contentUri, rowId);
			getContext().getContentResolver().notifyChange(returnUri, null);
			return returnUri;
		}
		throw new SQLException("Failed to insert row into " + uri);
	}
</pre>
<p>5.update方法，更新成功后需要返回修改的记录数</p>
<pre>
public int update(Uri uri, ContentValues values, String where,
			String[] whereArgs) {

		SQLiteDatabase db = mDbHelper.getWritableDatabase();
		String id;
		int count;
		switch (sUriMatcher.match(uri)) {
		case EVENT_TYPES:
			count = db.update(EVENT_TYPE_TABLE_NAME, values, where, whereArgs);
			break;
		case EVENT_TYPE_ID:
			id = uri.getPathSegments().get(1);
			count = db.update(EVENT_TYPE_TABLE_NAME, values,
					EventTypeAdapter.KEY_ROWID
							+ "="
							+ id
							+ (!TextUtils.isEmpty(where) ? " AND (" + where
									+ ')' : ""), whereArgs);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2010/03/create-contentprovider/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何处理SimpleCursorAdapter不能自动转换的数据</title>
		<link>http://chenyc.info/2010/03/simplecursoradapter-cant-bind/</link>
		<comments>http://chenyc.info/2010/03/simplecursoradapter-cant-bind/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 10:40:22 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[ListView]]></category>
		<category><![CDATA[SimpleCursorAdapter]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=104</guid>
		<description><![CDATA[SimpleCursorAdapter可以把我们从Array或数据库中取出的数据绑定的ListView或其他的组件，这个很好用，但有时候有些View，SimpleCursorAdapter并不能直接绑定，需要自己去实现它的setViewBinder方法，下面是我利用SimpleCursorAdapter绑定RatingBar的例子： SimpleCursorAdapter timeItems = new SimpleCursorAdapter(this, &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; R.layout.timeitem_row, timeItemsCursor, from, to); &#160;&#160;&#160;&#160;&#160;&#160;&#160; timeItems.setViewBinder(new SimpleCursorAdapter.ViewBinder(){ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; @Override &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; public boolean setViewValue(View view, Cursor cursor, int columnIndex) { &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int rateIndex = cursor.getColumnIndex(&#34;rate&#34;); &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(columnIndex == rateIndex) &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RatingBar ratingBar &#8230; <a href="http://chenyc.info/2010/03/simplecursoradapter-cant-bind/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>SimpleCursorAdapter可以把我们从Array或数据库中取出的数据绑定的ListView或其他的组件，这个很好用，但有时候有些View，SimpleCursorAdapter并不能直接绑定，需要自己去实现它的setViewBinder方法，下面是我利用SimpleCursorAdapter绑定RatingBar的例子：</p>
<p>SimpleCursorAdapter timeItems = new SimpleCursorAdapter(this,   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; R.layout.timeitem_row, timeItemsCursor, from, to);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; timeItems.setViewBinder(new SimpleCursorAdapter.ViewBinder(){ </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; @Override   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; public boolean setViewValue(View view, Cursor cursor, int columnIndex) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int rateIndex = cursor.getColumnIndex(&quot;rate&quot;);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(columnIndex == rateIndex)    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RatingBar ratingBar = (RatingBar)view;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ratingBar.setRating(cursor.getInt(rateIndex));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return true;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return false;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; });</p>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2010/03/simplecursoradapter-cant-bind/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android中编写Service相关的知识</title>
		<link>http://chenyc.info/2010/03/android-service/</link>
		<comments>http://chenyc.info/2010/03/android-service/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 10:34:09 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Service]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=101</guid>
		<description><![CDATA[1.在Android中编写Service，需要继承android.app.Service，覆盖其onCreate()和onStart(Intent intent, int startId)方法即可，onCreate方法只在service创建时调用，onStart方法每次都会调用。 2.在Service中不能直接访问数据库，只能通过ContentResolver访问，如果访问自己的数据，需要继承ContentProvider并实现其方法，才能被ContentResolver访问，以下使用ContentResolver的方法： mCursor = getContentResolver().query( &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Uri.withAppendedPath( &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TimeAccount.EVENT_TYPE_CONTENT_URI, &#34;/&#34; + pid), &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; new String[] { &#34;name&#34; }, null, null, null); 3.在Service中可以直接使用本应用的SharePreferences，我本来以为本来这个也用数据库一样，需要写成ContentProvider，没想到可以直接使用；例如： sharePreferences = PreferenceManager.getDefaultSharedPreferences(this); &#160;&#160;&#160;&#160;&#160;&#160;&#160; INTERVAL = Integer.valueOf(sharePreferences.getString( &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#34;sync_interval_list&#34;, &#34;60&#34;)); 4.Service有两种形式，一种是生命周期依赖于所启动的应用，就是BInd形式，通过bindService启动；另一种就是不依赖启动的应用，在应用已被操作系统干掉后，服务还会一直存在，通过startService启动。例如： Intent serviceIntent = new &#8230; <a href="http://chenyc.info/2010/03/android-service/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>1.在Android中编写Service，需要继承android.app.Service，覆盖其onCreate()和onStart(Intent intent, int startId)方法即可，onCreate方法只在service创建时调用，onStart方法每次都会调用。</p>
<p>2.在Service中不能直接访问数据库，只能通过ContentResolver访问，如果访问自己的数据，需要继承ContentProvider并实现其方法，才能被ContentResolver访问，以下使用ContentResolver的方法：</p>
<blockquote><p>mCursor = getContentResolver().query(      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Uri.withAppendedPath(       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TimeAccount.EVENT_TYPE_CONTENT_URI, &quot;/&quot; + pid),       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; new String[] { &quot;name&quot; }, null, null, null);</p>
</blockquote>
<p>3.在Service中可以直接使用本应用的SharePreferences，我本来以为本来这个也用数据库一样，需要写成ContentProvider，没想到可以直接使用；例如：</p>
<p>sharePreferences = PreferenceManager.getDefaultSharedPreferences(this);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; INTERVAL = Integer.valueOf(sharePreferences.getString(     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;sync_interval_list&quot;, &quot;60&quot;));</p>
<p>4.Service有两种形式，一种是生命周期依赖于所启动的应用，就是BInd形式，通过bindService启动；另一种就是不依赖启动的应用，在应用已被操作系统干掉后，服务还会一直存在，通过startService启动。例如：</p>
<p>Intent serviceIntent = new Intent();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; serviceIntent.setAction(&quot;com.chenyc.timeaccount.sync.SYNC_SERVICE&quot;);     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; context.startService(serviceIntent);</p>
<p>5.自己编写的Service，需要在AndroidManifest.xml中注册，例如：</p>
<p>&lt;service android:name=&quot;com.chenyc.timeaccount.sync.SyncService&quot;&gt;    <br />&#160;&#160;&#160; &lt;intent-filter&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;action android:name=&quot;com.chenyc.timeaccount.sync.SYNC_SERVICE&quot; /&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;     <br />&#160;&#160;&#160; &lt;/intent-filter&gt;     <br />&lt;/service&gt;</p>
<p>6.如果想在开机时就启动Service，需要写一个BroadcastReceiver接收BOOT_COMPLETED消息，系统启动完成后会发出这个消息；编写的BroadcastReceiver也需要在AndroidManifest.xml中注册。</p>
<p>IntentReceiver类接收消息，并启动服务：</p>
<blockquote><p>public class IntentReceiver extends BroadcastReceiver {      <br />&#160;&#160;&#160; public void onReceive(Context context, Intent intent) {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Intent serviceIntent = new Intent();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; serviceIntent.setAction(&quot;com.chenyc.timeaccount.sync.SYNC_SERVICE&quot;);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; context.startService(serviceIntent);       <br />&#160;&#160;&#160; } </p>
<p>}</p>
<p>在AndroidManifest.xml中注册：</p>
<p>&lt;receiver android:name=&quot;com.chenyc.timeaccount.sync.IntentReceiver&quot;&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;intent-filter&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;action android:name=&quot;android.intent.action.BOOT_COMPLETED&quot; /&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;category android:name=&quot;android.intent.category.HOME&quot; /&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/intent-filter&gt;      <br /> &lt;/receiver&gt;</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2010/03/android-service/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何在Android中创建自己的View</title>
		<link>http://chenyc.info/2010/03/create-android-view/</link>
		<comments>http://chenyc.info/2010/03/create-android-view/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 10:03:14 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[view]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=92</guid>
		<description><![CDATA[在Android中创建自己的VIEW只要继承android.view.View类，然后在onDraw方法中使用canvas画自己所需要的东东就可以了。当然你还需要做一些实际处理，比如对用户点击的处理，向前或向后滚动的处理等。 以下是我创建的CalendarView中，部分显示日历的代码： public CalendarView(Context context) { super(context); calendarBrowse = (CalendarBrowse) context; setFocusable(true); setFocusableInTouchMode(true); cPaint = new Paint(Paint.ANTI_ALIAS_FLAG); cPaint.setStyle(Paint.Style.FILL_AND_STROKE); cPaint.setColor(Color.RED); cPaint.setTextSize(20f); tPaint = new Paint(Paint.ANTI_ALIAS_FLAG); tPaint.setStyle(Paint.Style.FILL_AND_STROKE); tPaint.setColor(Color.WHITE); tPaint.setTextSize(20f); setBackgroundColor(getResources().getColor(R.color.background)); mGestureDetector = new GestureDetector( new GestureDetector.SimpleOnGestureListener() { @Override public boolean onFling(MotionEvent e1, &#8230; <a href="http://chenyc.info/2010/03/create-android-view/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>在Android中创建自己的VIEW只要继承android.view.View类，然后在onDraw方法中使用canvas画自己所需要的东东就可以了。当然你还需要做一些实际处理，比如对用户点击的处理，向前或向后滚动的处理等。</p>
<p>以下是我创建的CalendarView中，部分显示日历的代码：</p>
<pre>
public CalendarView(Context context) {
		super(context);

		calendarBrowse = (CalendarBrowse) context;

		setFocusable(true);
		setFocusableInTouchMode(true);

		cPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		cPaint.setStyle(Paint.Style.FILL_AND_STROKE);
		cPaint.setColor(Color.RED);
		cPaint.setTextSize(20f);

		tPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		tPaint.setStyle(Paint.Style.FILL_AND_STROKE);
		tPaint.setColor(Color.WHITE);
		tPaint.setTextSize(20f);

		setBackgroundColor(getResources().getColor(R.color.background));

		mGestureDetector = new GestureDetector(
				new GestureDetector.SimpleOnGestureListener() {

					@Override
					public boolean onFling(MotionEvent e1, MotionEvent e2,
							float velocityX, float velocityY) {

						if (e1.getX() > e2.getX()) {
							cal.add(Calendar.MONTH, 1);
							CalendarView.this.invalidate();
						}

						if (e1.getX() < e2.getX()) {
							cal.add(Calendar.MONTH, -1);
							CalendarView.this.invalidate();
						}

						return true;

					}

					@Override
					public boolean onSingleTapUp(MotionEvent e) {
						day = getDay(e.getX(), e.getY());
						if (day != INVALID_POSITION) {
							calendarBrowse.showTimeItemList(year, month, day);
						}
						return true;
					}

				});
	}
 </pre>
<p>GestureDetector类是用于对手势操作的处理，它可以截取你对屏幕的单击，长按，<br />
向前向后滚动等操作，这个功能在Android的框架中封装的很好，使用起来很舒服。</p>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2010/03/create-android-view/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>时间账本开发总结</title>
		<link>http://chenyc.info/2010/03/timeaccount-sum-up/</link>
		<comments>http://chenyc.info/2010/03/timeaccount-sum-up/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 09:48:00 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[时间管理]]></category>
		<category><![CDATA[时间账本]]></category>

		<guid isPermaLink="false">http://chenyc.info/2010/03/%e6%97%b6%e9%97%b4%e8%b4%a6%e6%9c%ac%e5%bc%80%e5%8f%91%e6%80%bb%e7%bb%93/</guid>
		<description><![CDATA[时间账本是我写的第一个Android应用，想法来自于《把时间当作朋友》和《奇特的一生》这两本书，功能很简单，就是登记自己每天做了什么，后来我又引入了反思想法，可以对每一天写一些反思，其实我觉得登记账本本身就是一种反思；现在主要完成了手机端的，下一步准备利用GAE开发WEB端，与手机端同步，然后再WEB端再做一些分析和生成报告等工作，例如可以做一些不同时期的时间执行效率比较，年末对这一年所做过的事出一份报告：比如在这一年中你读过什么书，看过什么电影，学习到什么技术等等；这还只是有一个初步的概念，具体怎么做还在一步的探索中；Android手机端也一样，会根据需要，进行改变，目的就是打造一个符合自己需要的时间管理软件。 时间账本的代码我已经放到google code上了，希望与大家一起交流Android开发知识，有兴趣的朋友也可以和我一起来完善这个时间账本。]]></description>
			<content:encoded><![CDATA[<p><strong>时间账本</strong>是我写的第一个Android应用，想法来自于<a href="http://book.douban.com/subject/3609132/" target="_blank">《把时间当作朋友》</a>和<a href="http://book.douban.com/subject/1115353/" target="_blank">《奇特的一生》</a>这两本书，功能很简单，就是登记自己每天做了什么，后来我又引入了反思想法，可以对每一天写一些反思，其实我觉得登记账本本身就是一种反思；现在主要完成了手机端的，下一步准备利用GAE开发WEB端，与手机端同步，然后再WEB端再做一些分析和生成报告等工作，例如可以做一些不同时期的时间执行效率比较，年末对这一年所做过的事出一份报告：比如在这一年中你读过什么书，看过什么电影，学习到什么技术等等；这还只是有一个初步的概念，具体怎么做还在一步的探索中；Android手机端也一样，会根据需要，进行改变，目的就是打造一个符合自己需要的时间管理软件。</p>
<p>时间账本的代码我已经放到<a href="http://code.google.com/p/timeaccount/" target="_blank">google code</a>上了，希望与大家一起交流Android开发知识，有兴趣的朋友也可以和我一起来完善这个<strong>时间账本。</strong></p>
<p><img src="http://pic.yupoo.com/chenyangcun/3769890b154c/saxxri9a.png" alt="" /> <img src="http://pic.yupoo.com/chenyangcun/1827790b154c/ypsvxbbp.png" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2010/03/timeaccount-sum-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android Notepad Tutorial 学习笔记</title>
		<link>http://chenyc.info/2010/03/android_notepad_learn/</link>
		<comments>http://chenyc.info/2010/03/android_notepad_learn/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 13:37:17 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=59</guid>
		<description><![CDATA[1. DbAdapter，作为content provider,通过继承SQLiteOpenHelper辅助实现 private static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(DATABASE_CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w(TAG, "Upgrading database from &#8230; <a href="http://chenyc.info/2010/03/android_notepad_learn/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>1.	DbAdapter，作为content provider,通过继承SQLiteOpenHelper辅助实现</p>
<pre>
    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {

            db.execSQL(DATABASE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS notes");
            onCreate(db);
        }
  }
</pre>
<p>2. SimpleCursorAdapter的用法</p>
<pre>
Cursor NotesCursor = mDbHelper.fetchAllNotes();
        startManagingCursor(NotesCursor);

        // Create an array to specify the fields we want to display in the list (only TITLE)
        String[] from = new String[]{NotesDbAdapter.KEY_TITLE};

        // and an array of the fields we want to bind those fields to (in this case just text1)
        int[] to = new int[]{R.id.text1};

        // Now create a simple cursor adapter and set it to display
        SimpleCursorAdapter notes =
        	    new SimpleCursorAdapter(this, R.layout.notes_row, NotesCursor, from, to);
        setListAdapter(notes);
</pre>
<p>2.	获取上下文菜单项</p>
<pre>
	public boolean onContextItemSelected(MenuItem item) {
		switch(item.getItemId()) {
    	case DELETE_ID:
    		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
	        mDbHelper.deleteNote(info.id);
	        fillData();
	        return true;
		}
		return super.onContextItemSelected(item);
	}
</pre>
<p>3.	通过Intent向下一个Activity传递参数</p>
<pre>
   Intent i = new Intent(this, NoteEdit.class);
   i.putExtra(NotesDbAdapter.KEY_ROWID, id);
   startActivityForResult(i, ACTIVITY_EDIT);
</pre>
<p>4.	onActivityResult的调用<br />
通过startActivityForResult打开的Activity，完成后返回时调用onActivityResult方法</p>
<p>5.	onSaveInstanceState的调用时点，及用处</p>
<pre>
  protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
}
   </pre>
<p>onSaveInstanceState在程序退出或暂停时调用，通过Bundle保存的值，在下次程序重新打开或恢复运行时会重新载入，这样我们就能在程序下一次打开时还原用户的最后状态。</p>
<p>6.	layout中的android:layout_weight的意义<br />
设置android:layout_weight，比同组没有设的对象占用的面积多，android:layout_weight数值大的比android:layout_weight数值小占用面积多。</p>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2010/03/android_notepad_learn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

