event.getAction()&MotionEvent.ACTION_MASK的原因

看到下面代码中用了AND位运算是为了什么呢?

	public boolean onTouchEvent(MotionEvent event) {
		int action = event.getAction();
		switch (action & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:
			showMsg("ACTION_DOWN" + action);
			break;
		case MotionEvent.ACTION_UP:
			showMsg("ACTION_UP" + action);
			break;
		case MotionEvent.ACTION_POINTER_UP:
			showMsg("ACTION_POINTER_UP" + action);
			break;
		case MotionEvent.ACTION_POINTER_DOWN:
			showMsg("ACTION_POINTER_DOWN" + action);
			break;
		}
		return super.onTouchEvent(event);
	}

首先来看看这些常量的值

ACTION_MASK     0x000000ff
ACTION_DOWN     0x00000000         ACTION_UP      0x00000001        ACTION_MOVE      0x00000002
ACTION_POINTER_DOWN       0x00000005            ACTION_POINTER_UP        0x00000006
ACTION_POINTER_1_DOWN     0x00000005            ACTION_POINTER_1_UP      0x00000006
ACTION_POINTER_2_DOWN     0x00000105            ACTION_POINTER_2_UP      0x00000106
ACTION_POINTER_3_DOWN     0x00000205            ACTION_POINTER_3_UP      0x00000206

看到这么多16进制有没有怕呢。。。我数学不太好,看着有点怕呢~
先做做十六进制AND运算
来看看ACTION_MASK & ACTION_POINTER_2_DOWN 即 0x000000ff & 0×00000105
换成二进制 1111 1111(2) & 1 0000 0110(2) = 0110(2) = 0×00000006
如果不会换算,试试用计算器啦。。(掩面,我也是用计算器,快速计算的方法是把16进制的每一位扩展为4位的二进制)
可以看到,and运算的结果总是小于等于0x000000ff,那就是说and之后,无论你多少根手指加进来,都是会ACTION_POINTER_DOWN或者ACTION_POINTER_UP

补充一下,当第二个手指触摸屏幕时,event.getAction()的值是0×00000105,第三个手指触摸是0×00000205,放开相应的手指数量会返回相应的值。


Android ViewHolder模式

这个ViewHolder到底是什么呢?我们可以在官方sample看到这段代码
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/List14.html

        static class ViewHolder {
            TextView text;
            ImageView icon;
        }

可以看到它只是一个静态类,它的作用就在于减少不必要的调用findViewById
完整的官方例子,官方例子中convertView 也是避免inflating View。
然后把对底下的控件引用存在ViewHolder里面,再在View.setTag(holder)把它放在view里,下次就可以直接取了。

效率相差多少?看这篇文章:Android开发之ListView 适配器(Adapter)优化

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package com.example.android.apis.view;
 
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.ImageView;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import com.example.android.apis.R;
 
/**
 * Demonstrates how to write an efficient list adapter. The adapter used in this example binds
 * to an ImageView and to a TextView for each row in the list.
 *
 * To work efficiently the adapter implemented here uses two techniques:
 * - It reuses the convertView passed to getView() to avoid inflating View when it is not necessary
 * - It uses the ViewHolder pattern to avoid calling findViewById() when it is not necessary
 *
 * The ViewHolder pattern consists in storing a data structure in the tag of the view returned by
 * getView(). This data structures contains references to the views we want to bind data to, thus
 * avoiding calls to findViewById() every time getView() is invoked.
 */
public class List14 extends ListActivity {
 
    private static class EfficientAdapter extends BaseAdapter {
        private LayoutInflater mInflater;
        private Bitmap mIcon1;
        private Bitmap mIcon2;
 
        public EfficientAdapter(Context context) {
            // Cache the LayoutInflate to avoid asking for a new one each time.
            mInflater = LayoutInflater.from(context);
 
            // Icons bound to the rows.
            mIcon1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_1);
            mIcon2 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_2);
        }
 
        /**
         * The number of items in the list is determined by the number of speeches
         * in our array.
         *
         * @see android.widget.ListAdapter#getCount()
         */
        public int getCount() {
            return DATA.length;
        }
 
        /**
         * Since the data comes from an array, just returning the index is
         * sufficent to get at the data. If we were using a more complex data
         * structure, we would return whatever object represents one row in the
         * list.
         *
         * @see android.widget.ListAdapter#getItem(int)
         */
        public Object getItem(int position) {
            return position;
        }
 
        /**
         * Use the array index as a unique id.
         *
         * @see android.widget.ListAdapter#getItemId(int)
         */
        public long getItemId(int position) {
            return position;
        }
 
        /**
         * Make a view to hold each row.
         *
         * @see android.widget.ListAdapter#getView(int, android.view.View,
         *      android.view.ViewGroup)
         */
        public View getView(int position, View convertView, ViewGroup parent) {
            // A ViewHolder keeps references to children views to avoid unneccessary calls
            // to findViewById() on each row.
            ViewHolder holder;
 
            // When convertView is not null, we can reuse it directly, there is no need
            // to reinflate it. We only inflate a new View when the convertView supplied
            // by ListView is null.
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
 
                // Creates a ViewHolder and store references to the two children views
                // we want to bind data to.
                holder = new ViewHolder();
                holder.text = (TextView) convertView.findViewById(R.id.text);
                holder.icon = (ImageView) convertView.findViewById(R.id.icon);
 
                convertView.setTag(holder);
            } else {
                // Get the ViewHolder back to get fast access to the TextView
                // and the ImageView.
                holder = (ViewHolder) convertView.getTag();
            }
 
            // Bind the data efficiently with the holder.
            holder.text.setText(DATA[position]);
            holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
 
            return convertView;
        }
 
        static class ViewHolder {
            TextView text;
            ImageView icon;
        }
    }
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setListAdapter(new EfficientAdapter(this));
    }
 
    private static final String[] DATA = Cheeses.sCheeseStrings;
}

找不到管理网页和文件夹对处理方法

Tags:

把下面内容保存为aa.reg文件,双击运行导入
(未测试是否成功,注册表从我电脑导出的,WIN7和XP应该是一样可以用的)

Windows Registry Editor Version 5.00
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Folder\Thickets]
"Text"="管理网页和文件夹对"
"HelpID"="TBD"
"Type"="group"
"Bitmap"="C:\\Windows\\system32\\\\SHELL32.DLL,4"
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Folder\Thickets\AUTO]
"CheckedValue"=dword:00000000
"Type"="radio"
"ValueName"="NoFileFolderConnection"
"HelpID"="TBD"
"Text"="作为单一文件显示和管理对"
"DefaultValue"=dword:00000000
"RegPath"="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"
"HKeyRoot"=dword:80000001
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Folder\Thickets\NOHIDE]
"ValueName"="NoFileFolderConnection"
"DefaultValue"=dword:00000000
"Text"="显示两部分但是作为单一文件进行管理"
"RegPath"="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"
"HelpID"="TBD"
"Type"="radio"
"CheckedValue"=dword:00000002
"HKeyRoot"=dword:80000001
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Folder\Thickets\NONE]
"CheckedValue"=dword:00000001
"Type"="radio"
"HKeyRoot"=dword:80000001
"RegPath"="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"
"HelpID"="TBD"
"ValueName"="NoFileFolderConnection"
"DefaultValue"=dword:00000000
"Text"="显示两部分并分别进行管理"
 
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
“NoFileFolderConnection”=dword:00000001

Activity startActivityForResult

public void startActivityForResult (Intent intent, int requestCode)
从一个Activity启动另一个activity,得到结果返回给前一个activity。

简单说

OneActivity实现onActivityResult (int requestCode, int resultCode, Intent data)方法,然后使用startActivityForResult启动另一个Activity
另一个Activity取得结果后通过setResult (…)把结果传回。

代码如下

界面代码不提供了,两个都是一个简单的button
注意要在AndroidManifest.xml定义你新增的Activity

<activity android:name=".OtherActivity"></activity>

第一个Activity

package com.fatkun;
 
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
 
public class OneActivity extends Activity {
	private final int myRequestCode = 1; //请求码
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button btn = (Button)findViewById(R.id.button1);
        btn.setOnClickListener(new OnClickListener() {
 
			public void onClick(View v) {
				Intent intent = new Intent(OneActivity.this, OtherActivity.class);
				//第二个参数是请求码,会在onActivityResult返回
				startActivityForResult(intent, myRequestCode);
			}
		});
    }
 
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		switch (requestCode) {
		case myRequestCode:
			if (resultCode == Activity.RESULT_OK) {
				//如果resultCode是RESULT_OK的话,就把内容显示出来。
				Toast.makeText(this, data.getExtras().getString("info"), Toast.LENGTH_SHORT).show();
			}
			break;
		}
	}
}

第二个Activity

package com.fatkun;
 
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
 
public class OtherActivity extends Activity {
 
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.other);
		Button btn = (Button) findViewById(R.id.button1);
		btn.setOnClickListener(new OnClickListener() {
 
			public void onClick(View v) {
				Intent intent = new Intent(OtherActivity.this, OneActivity.class);
				intent.putExtra("info", "我是从OtherActivity返回的数据");
				OnClickListener a = this;
				// 这里的OtherActivity.this是为了得到OtherActivity类的对象,因为现在在button的内部类里面,this指向的是OnClickListener
				OtherActivity.this.setResult(Activity.RESULT_OK, intent);
				OtherActivity.this.finish(); // 结束自己
			}
		});
	}
 
}

Android BroadcastReceiver 广播

总结如下:
广播可用于Service与Activity的之间的通信,也可用于接收一些系统的事件,例如收到短信,电量等信息。

有两种方法注册,静态注册和动态注册

静态注册

创建一个类继承BroadcastReceiver,然后在AndroidManifest.xml 添加

<receiver android:name="clsReceiver2">  
    <intent-filter>  
        <action android:name="com.testBroadcastReceiver.Internal_2"/>  
    </intent-filter>  
</receiver>

动态注册

继承BroadcastReceiver类,实现onReceive方法。然后registerReceiver它。同一个Receiver还可以“听多个广播”,可以在IntentFilter加多个action。
主要通过IntentFilter,别人用sendBroadcast(intent)发广播,如果频率一样(IntentFilter里的Action一样)就可以听到广播。

//动态注册广播消息  
        registerReceiver(bcrIntenal1, new IntentFilter(INTENAL_ACTION_1));
//取消广播接收器
        unregisterReceiver(rhelper);

两篇参考文章:

http://blog.csdn.net/hellogv/article/details/5999170
http://www.cnblogs.com/jico/articles/1838293.html


WP-Syntax代码编辑器插件

升级到WP3.3后,之前的那些插入代码按钮都没有用啦。。上去找插件没找到,自己改了一个syntanx-highlighter的。
感谢原作者leo108,http://leo108.com/

把下面的代码保存下来,放在一个文件夹里,打包成zip文件,然后就可以在插件处上传安装了。
或者下载这个文件:http://fatkun.googlecode.com/files/wp-syntax-editor.zip

<?php
/*
Plugin Name: WP-Syntax Code Editor
Plugin URI: http://fatkun.com/2012/01/wp-syntax-code-editor.html
Description: 在编辑框加入一个插入wp-syntax代码的按钮,修改自syntax-highlighter-with-add-button-in-editor(原作者leo108)
Version: 1.0.0
Original Author: leo108
Author URI: http://fatkun.com/
*/
function codebox_init(){
?>
<div id="codebox" class="meta-box-sortables ui-sortable" style="position: relative;"><div class="postbox">
<div class="handlediv" title="Click to toggle"></div>
<h3 class="hndle"><span>WP-Syntax</span></h3>
<div class="inside">
Language:
<select id="language">
	<option value="other">Other</option>
	<option value="bash">Bash</option>
	<option value="c">C</option>
	<option value="cpp">C++</option>
	<option value="csharp">C#</option>
	<option value="css">CSS</option>
	<option value="delphi">Delphi</option>
	<option value="diff">Diff</option>
	<option value="erl">Erlang</option>
	<option value="groovy">Groovy</option>
	<option value="html">HTML</option>
	<option value="java">Java</option>
	<option value="js">Javascript</option>
	<option value="perl">Perl</option>
	<option value="php">PHP</option>
    <option value="ps">PowerShell</option>
	<option value="python">Python</option>
	<option value="ruby">Ruby</option>
	<option value="sql">SQL</option>
	<option value="vb">VisualBasic</option>
	<option value="vb">VB.NET</option>
	<option value="xml">XML</option>
</select>
<br>
Code:<br><textarea id="code" rows="8" cols="70" style="width:97%;"></textarea><br>
<input type="button" value="INSERT" onclick="javascript:settext();">
 
<script>
function settext()
{ 
	var str='<pre escaped="true" lang="';
	var lang=document.getElementById("language").value;
	var code=document.getElementById("code").value;
	str=str+lang;
	str=str+'">';
	str=str+filter(code)+"</pre>";
	var win = window.dialogArguments ¦¦ opener ¦¦ parent ¦¦ top;
	win.send_to_editor(str);
	document.getElementById("code").value="";
}
function filter (str) {
	str = str.replace(/&/g, '&amp;');
	str = str.replace(/</g, '&lt;');
	str = str.replace(/>/g, '&gt;');
	str = str.replace(/'/g, '&#39;');
	str = str.replace(/"/g, '&quot;');
	str = str.replace(/\¦/g, '&brvbar;');
	return str;
}
</script>
</div></div></div>
<script>document.getElementById("postdivrich").appendChild(document.getElementById("codebox"));</script>
<?php
}
add_action('dbx_post_sidebar','codebox_init');
?>