当前位置:  编程技术>移动开发
本页文章导读:
    ▪ListView用法小结        ListView用法总结 一:Adapter优化什么是Adapter,可以先看看我的上一篇文章,Android开发——说说Adapter那点事 Adapter与View的连接主要依靠getView这个方法返回我们需要的自定义view。ListView是Andro.........
    ▪ 【通译】(27)应用程序资源        【翻译】(27)应用程序资源 【翻译】(27)应用程序资源   see http://developer.android.com/guide/topics/resources/index.html   原文见 http://developer.android.com/guide/topics/resources/index.html   ------------------------------.........
    ▪ 挥动特效       晃动特效 头文件:   #import <UIKit/UIKit.h> @interface AccelerometerViewController : UIViewController <UIAccelerometerDelegate> { UILabel *label; } @property (nonatomic, retain) IBOutlet UILabel *label; @end   实现文件.........

[1]ListView用法小结
    来源: 互联网  发布时间: 2014-02-18
ListView用法总结
一:Adapter优化
什么是Adapter,可以先看看我的上一篇文章,Android开发——说说Adapter那点事 Adapter与View的连接主要依靠getView这个方法返回我们需要的自定义view。ListView是Android app中一个最最最常用的控件了,所以如何让ListView流畅运行,获取良好的用户体验是非常重要的。对ListView优化就是对Adapter中的getView方法进行优化。09年的Google IO大会给出的优化建议如下:
@Override
 public View getView(int position, View convertView, ViewGroup parent) {
     Log.d("MyAdapter", "Position:" + position + "---"
             + String.valueOf(System.currentTimeMillis()));
     ViewHolder holder;
     if (convertView == null) {
         final LayoutInflater inflater = (LayoutInflater) mContext
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         convertView = inflater.inflate(R.layout.list_item_icon_text, null);
         holder = new ViewHolder();
         holder.icon = (ImageView) convertView.findViewById(R.id.icon);
         holder.text = (TextView) convertView.findViewById(R.id.text);
         convertView.setTag(holder);
     } else {
         holder = (ViewHolder) convertView.getTag();
     }
     holder.icon.setImageResource(R.drawable.icon);
     holder.text.setText(mData[position]);
     return convertView;
 }
  
 static class ViewHolder {
     ImageView icon;
  
     TextView text;
 }

以上是Google io大会上给出的优化建议,经过尝试ListView确实流畅了许多。

不建议的做法:
   1: @Override
     public View getView(int position, View convertView, ViewGroup parent) {
         Log.d("MyAdapter", "Position:" + position + "---"
                 + String.valueOf(System.currentTimeMillis()));
             final LayoutInflater inflater = (LayoutInflater) mContext
                     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
             View v = inflater.inflate(R.layout.list_item_icon_text, null);
             ((ImageView) v.findViewById(R.id.icon)).setImageResource(R.drawable.icon);
             ((TextView) v.findViewById(R.id.text)).setText(mData[position]);
           return v;
    }




二:美化你的android程序:自定义ListView背景:
在Android中,ListView是最常用的一个控件,在做UI设计的时候,很多人希望能够改变一下它的背景,使他能够符合整体的UI设计,改变背景背很简单只需要准备一张图片然后指定属性 android:background="@drawable/bg",不过不要高兴地太早,当你这么做以后,发现背景是变了,但是当你拖动,或者点击list空白位置的时候发现ListItem都变成黑色的了,破坏了整体效果。
这是为什么呢?
这个要从Listview的效果说起,默认的ListItem背景是透明的,而ListView的背景是固定不变的,所以在滚动条滚动的过程中如果实时地去将当前每个Item的显示内容跟背景进行混合运算,所以android系统为了优化这个过程用,就使用了一个叫做android:cacheColorHint的属性,在黑色主题下默认的颜色值是#191919,所以就出现了刚才的画面,有一半是黑色的

那怎么办呢?
如果你只是换背景的颜色的话,可以直接指定android:cacheColorHint为你所要的颜色,如果你是用图片做背景的话,那也只要将android:cacheColorHint指定为透明(#00000000)就可以了,当然为了美化是要牺牲一些效率的。



三:ListView页眉页脚效果VS android背景渐变:
大家都知道,在我们调用ListView的addFooterView()方法给List增加一个页脚时,如果列表内容很多,超过了屏幕大小,那么页脚就看不到了,可我们一般想要的效果是如下图所示的,在ListView的内容超过屏幕时,页脚还在屏幕的底部。
[img]

[/img]
本文将介绍上图所示的ListView效果,同时介绍一下在android中如何实现渐变效果,就像上图中的页眉页脚的背景色一样。

实现上面的效果主要使用几个RelativeLayout标签和ListView组合即可,代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<RelativeLayout
		android:id="@+id/listHeader"
		android:background="@drawable/jbshape"
		android:layout_alignParentTop="true"
		android:gravity="center_horizontal"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content">
		<TextView
			android:text="IdeasAndroid 列表演示"
			android:textColor="#000000"
			android:textSize="18dip"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content" />
	</RelativeLayout>
	<RelativeLayout
		android:id="@+id/listFooter"
		android:background="@drawable/jbshape"
		android:gravity="center_horizontal"
		android:layout_alignParentBottom="true"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content">
		<Button
			android:id="@+id/prePage"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:text="上一页" 
			android:layout_alignParentLeft="true" />
		<Button
			android:layout_width="wrap_content"
			android:layout_gravity="right"
			android:layout_height="wrap_content"
			android:text="下一页"
			android:layout_toRightOf="@id/prePage" />
	</RelativeLayout>
	<ListView
		android:id="@+id/myListView"
		android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		android:layout_below="@id/listHeader"
		android:layout_above="@id/listFooter" />
</RelativeLayout>

几个关键点:
1、在页眉(id为listHeader)使用属性android:layout_alignParentTop=”true”
声明页眉部分与父视图的顶部对齐。
2、在页脚(id为listFooter)使用属性android:layout_alignParentBottom=”true” 声明其与父视图的底部对齐。
3、在 ListView中使用属性android:layout_below=”@id/listHeader” android:layout_above=”@id/listFooter” 声明ListView位于listHeader的下方,位于listFooter的上方。

这样我们的页眉页脚效果就实现了。

再来看看是怎么实现渐变的?

我们在res/drawable目录下新建一个叫jbshape.xml的文件,内容如下所示:
<?xml version="1.0" encoding="utf-8"?>
<shape
	xmlns:android="http://schemas.android.com/apk/res/android" 
	android:shape="rectangle">
	<gradient
		android:startColor="#509245"
		android:centerColor="#3e8532" 
		android:endColor="#509245"
		android:type="linear"
		android:angle="90" 
		android:centerX="0.5"
		android:centerY="0.5" />
	<padding
		android:left="7dp"
		android:top="7dp"
		android:right="7dp" 
		android:bottom="7dp" />
	<corners
		android:radius="4dp" />
</shape> 

这里就不多讲了,相信你一看就能看懂,android:shape 配置的是图形的形式,主要包括方形、圆形等,本例中为方形。gradient节点主要配置起点颜色、终点颜色、中间点的坐标、中间点的颜色、渐变角度(90度为上下渐变,0为左右渐变),padding节点主要配置上下左右边距,corners节点配置四周园角的半径。更详细的配置参见http://www.ideasandroid.com/android/sdk/docs/guide/topics/resources/drawable-resource.html 。

使用渐变就更简单了,如第一部分代码中所示的,直接用android:background=”@drawable/jbshape” 配置背景为刚才配置的渐变图形即可。



四:让ListView显示在Button上面
[img]

[/img]
通常情况下ListView的android:layout_height属性我们都设置成"fill_parent",但是这样一来,它就会占据整个屏幕,如果它下面还有控件的话,就会被它“挤到”外面去。如何解决这种情况呢?表面上使用LinearLayout是最简单的,但就会出现上面的情形。那就使用RelativeLayout吧。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<Button
		android:id="@+id/btn_1"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="click_1"
		android:layout_alignParentLeft="true"
		android:layout_alignParentBottom="true" />
	<Button
		android:id="@+id/btn_0"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="click_0"
		android:layout_above="@id/btn_1"
		android:layout_alignParentLeft="true" />
	<ListView
		android:id="@+id/listview"
		android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		android:layout_above="@id/btn_0"
		android:layout_alignParentLeft="true"
		android:layout_alignParentTop="true" />
</RelativeLayout>  

上面的布局仅作参考!
当然如果将ListView换成ScrollView也是一样的,这里只起到抛砖引玉的目的。

另外,你也可以在ListView中使用android:layout_weight="1",这样就可以将它放在LinearLayout,这样是最简单的




五:ListView列表分组的实现,效果图:
[img]

[/img]
布局文件:
group_list_item_tag.xml
<?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="wrap_content"
	android:background="#555555"
	android:paddingLeft="10dip">
	<TextView
		android:id="@+id/group_list_item_text"
		android:layout_width="wrap_content"
		android:layout_height="20dip"
		android:textColor="#ffffff"
		android:gravity="center_vertical" />
</LinearLayout> 


group_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:padding="5dip">     
	<!-- 图片和文字 -->    <!-- 随便放了一张图片,稍微美化一下 -->
	<ImageView
		android:src="/blog_article/@drawable/icon/index.html"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content" />
	<TextView
		android:id="@+id/group_list_item_text"
		android:layout_width="wrap_content"
		android:layout_height="fill_parent"
		android:paddingLeft="5dip"
		android:gravity="center_vertical" />
</LinearLayout>


group_list_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">    
	 <!--简单的列表显示-->
	<ListView
		android:id="@+id/group_list"
		android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		android:cacheColorHint="#00000000" />
</LinearLayout> 


Activity代码:
package com.magus.list;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {
	private GroupListAdapter adapter = null;
	private ListView listView = null;
	private List<String> list = new ArrayList<String>();
	private List<String> listTag = new ArrayList<String>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.group_list_activity);
		setData();
		adapter = new GroupListAdapter(this, list, listTag);
		listView = (ListView) findViewById(R.id.group_list);
		listView.setAdapter(adapter);
	}

	public void setData() {
		list.add("A");
		listTag.add("A");
		for (int i = 0; i < 2; i++) {
			list.add("阿凡达" + i);
		}
		list.add("B");
		listTag.add("B");
		for (int i = 0; i < 2; i++) {
			list.add("比特风暴" + i);
		}
		list.add("C");
		listTag.add("C");
		for (int i = 0; i < 30; i++) {
			list.add("查理风云" + i);
		}
	}

	private static class GroupListAdapter extends ArrayAdapter<String> {
		private List<String> listTag = null;

		public GroupListAdapter(Context context, List<String> objects,
				List<String> tags) {
			super(context, 0, objects);
			this.listTag = tags;
		}

		@Override
		public boolean isEnabled(int position) {
			if (listTag.contains(getItem(position))) {
				return false;
			}
			return super.isEnabled(position);
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			View view = convertView;
			if (listTag.contains(getItem(position))) {
				
				view = LayoutInflater.from(getContext()).inflate(
						R.layout.group_list_item_tag, null);
			} else {
				view = LayoutInflater.from(getContext()).inflate(
						R.layout.group_list_item, null);
			}
			//getItem(position) 得到的是list里面String,
			String str = getItem(position);
			System.out.println("getItem(position)="+str);
			
			TextView textView = (TextView) view
					.findViewById(R.id.group_list_item_text);
			textView.setText(getItem(position));
			return view;
		}
	}
}




六:ListView自适应实现表格
GridView比ListView更容易实现自适应的表格,但是GridView每个格单元的大小固定,而ListView实现的表格可以自定义每个格单元的大小,但因此实现自适应表格也会复杂些(格单元大小不一)。另外,GridView实现的表格可以定位在具体某个格单元,而ListView实现的表格则只能定位在表格行。因此还是那句老话:根据具体的使用环境而选择GridView 或者 ListView实现表格。

先贴出本文程序运行的效果图:
[img]

[/img]

布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<HorizontalScrollView
		android:id="@+id/HorizontalScrollView01"
		android:layout_height="fill_parent"
		android:layout_width="fill_parent">
		<ListView
			android:id="@+id/ListView01"
			android:layout_height="wrap_content"
			android:layout_width="wrap_content" />
	</HorizontalScrollView>
</LinearLayout>  


package com.magus.listview;  
import java.util.List;  
import android.content.Context;  
import android.graphics.Color;  
import android.view.Gravity;  
import android.view.View;  
import android.view.ViewGroup;  
import android.widget.BaseAdapter;  
import android.widget.ImageView;  
import android.widget.LinearLayout;  
import android.widget.TextView;  
public class TableAdapter extends BaseAdapter {  
    private Context context;  
    private List<TableRow> table;  
    public TableAdapter(Context context, List<TableRow> table) {  
        this.context = context;  
        this.table = table;  
    }  
    @Override  
    public int getCount() {  
        return table.size();  
    }  
    @Override  
    public long getItemId(int position) {  
        return position;  
    }  
    public TableRow getItem(int position) {  
        return table.get(position);  
    }  
    public View getView(int position, View convertView, ViewGroup parent) {  
        TableRow tableRow = table.get(position);  
        return new TableRowView(this.context, tableRow);  
    }  
    /** 
     * TableRowView 实现表格行的样式 
     * @author hellogv 
     */  
    class TableRowView extends LinearLayout {  
        public TableRowView(Context context, TableRow tableRow) {  
            super(context);  
              
            this.setOrientation(LinearLayout.HORIZONTAL);  
            for (int i = 0; i < tableRow.getSize(); i++) {//逐个格单元添加到行  
                TableCell tableCell = tableRow.getCellValue(i);  
                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(  
                        tableCell.width, tableCell.height);//按照格单元指定的大小设置空间  
                layoutParams.setMargins(0, 0, 1, 1);//预留空隙制造边框  
                if (tableCell.type == TableCell.STRING) {//如果格单元是文本内容  
                    TextView textCell = new TextView(context);  
                    textCell.setLines(1);  
                    textCell.setGravity(Gravity.CENTER);  
                    textCell.setBackgroundColor(Color.BLACK);//背景黑色  
                    textCell.setText(String.valueOf(tableCell.value));  
                    addView(textCell, layoutParams);  
                } else if (tableCell.type == TableCell.IMAGE) {//如果格单元是图像内容  
                    ImageView imgCell = new ImageView(context);  
                    imgCell.setBackgroundColor(Color.BLACK);//背景黑色  
                    imgCell.setImageResource((Integer) tableCell.value);  
                    addView(imgCell, layoutParams);  
                }  
            }  
            this.setBackgroundColor(Color.WHITE);//背景白色,利用空隙来实现边框  
        }  
    }  
    /** 
     * TableRow 实现表格的行 
     * @author hellogv 
     */  
    static public class TableRow {  
        private TableCell[] cell;  
        public TableRow(TableCell[] cell) {  
            this.cell = cell;  
        }  
        public int getSize() {  
            return cell.length;  
        }  
        public TableCell getCellValue(int index) {  
            if (index >= cell.length)  
                return null;  
            return cell[index];  
        }  
    }  
    /** 
     * TableCell 实现表格的格单元 
     * @author hellogv 
     */  
    static public class TableCell {  
        static public final int STRING = 0;  
        static public final int IMAGE = 1;  
        public Object value;  
        public int width;  
        public int height;  
        private int type;  
        public TableCell(Object value, int width, int height, int type) {  
            this.value = value;  
            this.width = width;  
            this.height = height;  
            this.type = type;  
        }  
    }  
}  


package com.magus.listview;  
import java.util.ArrayList;  

import com.magus.listview.TableAdapter.TableCell;
import com.magus.listview.TableAdapter.TableRow;

import android.app.Activity;  
import android.os.Bundle;  
import android.view.View;  
import android.widget.AdapterView;  
import android.widget.ListView;  
import android.widget.LinearLayout.LayoutParams;  
import android.widget.Toast;  
/** 
 * @author hellogv 
 */  
public class testMyListView extends Activity {  
    /** Called when the activity is first created. */  
    ListView lv;  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        this.setTitle("ListView自适应实现表格---hellogv");  
        lv = (ListView) this.findViewById(R.id.ListView01);  
        ArrayList<TableRow> table = new ArrayList<TableRow>();  
        TableCell[] titles = new TableCell[5];// 每行5个单元  
        int width = this.getWindowManager().getDefaultDisplay().getWidth()/titles.length;  
        // 定义标题  
        for (int i = 0; i < titles.length; i++) {  
            titles[i] = new TableCell("标题" + String.valueOf(i),   
                                    width + 8 * i,  
                                    LayoutParams.FILL_PARENT,   
                                    TableCell.STRING);  
        }  
        table.add(new TableRow(titles));  
        // 每行的数据  
        TableCell[] cells = new TableCell[5];// 每行5个单元  
        for (int i = 0; i < cells.length - 1; i++) {  
            cells[i] = new TableCell("No." + String.valueOf(i),  
                                    titles[i].width,   
                                    LayoutParams.FILL_PARENT,   
                                    TableCell.STRING);  
        }  
        cells[cells.length - 1] = new TableCell(R.drawable.icon,  
                                                titles[cells.length - 1].width,   
                                                LayoutParams.WRAP_CONTENT,  
                                                TableCell.IMAGE);  
        // 把表格的行添加到表格  
        for (int i = 0; i < 12; i++)  
            table.add(new TableRow(cells));  
        TableAdapter tableAdapter = new TableAdapter(this, table);  
        lv.setAdapter(tableAdapter);  
        lv.setOnItemClickListener(new ItemClickEvent());  
    }  
    class ItemClickEvent implements AdapterView.OnItemClickListener {  
        @Override  
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,  
                long arg3) {  
            Toast.makeText(testMyListView.this, "选中第"+String.valueOf(arg2)+"行", 500).show();  
        }  
    }  
}  




七:延时加载的ListView
效果图:

[img]

[/img]

项目结构图:

[img]

[/img]

布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<ProgressBar
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:indeterminateOnly="true"
   />
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Loading please wait..."
    />
</LinearLayout>


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <ListView 
    android:id="@+id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
  />
</LinearLayout>


package com.ql.app;

/*
 * Copyright (C) 2010 Makas Tzavellas
 *
 * 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.
 */

import com.ql.service.AbstractPageableAdapter;
import com.ql.service.DataLoaderHandler;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;

/**
 * Sample Activity that contains the Pageable list view.
 * @author Makas Tzavellas (makas dot tzavellas at gmail dot com)
 *
 */
public class SampleActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ListView listView = (ListView)findViewById(R.id.list);
        SampleDataLoaderHandler handler = new SampleDataLoaderHandler();
        PageableAdapter adapter = new PageableAdapter(listView, this, R.layout.loading, handler);
        listView.setAdapter(adapter);
        // Set the adapter as the on scroll listener.
        // It is done here just incase the activity or other class needs to listen to onScroll event too.
        listView.setOnScrollListener(adapter);
    }
    
    /**
     * Sample Pageable adapter that extends {@link AbstractPageableAdapter}
     * @author Makas Tzavellas (makas dot tzavellas at gmail dot com)
     *
     */
    private class PageableAdapter extends AbstractPageableAdapter<String> {

        public PageableAdapter(ListView listView, Context context, int loadingViewResourceId, DataLoaderHandler<String> handler) {
            super(listView, context, loadingViewResourceId, handler);
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, parent, false);
            }
            //((TextView)convertView).setText(getItem(position).toString());
            ((TextView)convertView).setText(getItem(position).toString()+"哈哈无敌小胖胖");
            return convertView;
        }
        
    }
}


package com.ql.app;

/*
 * Copyright (C) 2010 Makas Tzavellas
 *
 * 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.
 */
import android.os.AsyncTask;

import java.util.ArrayList;

import com.ql.service.DataLoaderHandler;
import com.ql.service.DataResponseHandler;

/**
 * Sample implementation of the {@link DataLoaderHandler}
 * @author Makas Tzavellas (makas dot tzavellas at gmail dot com)
 *
 */
public class SampleDataLoaderHandler implements DataLoaderHandler<String>, DataResponseHandler<SampleDataResult<String>> {
    private static final int MAX_SIZE_PER_PAGE = 10;
    private static final int MAX_ITEMS = 51;

    private boolean mLoading;
    private ArrayList<String> mValues = new ArrayList<String>();
    private DataLoadedCallback<String> mCallback;
    private int mMaxItems;
    
    public int getMaxItems() {
        return mMaxItems;
    }

    public void getNext(DataLoadedCallback<String> callback) {
        mLoading = true;
        mCallback = callback;
        new SampleBackgroundTask(this).execute(mValues.size());
    }

    public void getValues(DataLoadedCallback<String> callback) {
        if (mValues.isEmpty()) {
            // No data has been loaded before.
            // Load the initial data which includes the max size.
            mLoading = true;
            mCallback = callback;
            new SampleFirstBackgroundTask(this).execute();
        } else {
            callback.dataLoaded(mValues);
        }
    }

    public boolean isLoading() {
        return mLoading;
    }

    public void resultAvailable(int status, SampleDataResult<String> result) {
        mLoading = false;
        if (mMaxItems == 0)
            mMaxItems = result.maxItems;
        
        mValues.addAll(result.values);
        
        mCallback.dataLoaded(result.values);
    }
    
    /**
     * Sample implementation when loading the data the first time.
     * @author Makas Tzavellas (makas dot tzavellas at gmail dot com)
     *
     */
    private static class SampleFirstBackgroundTask extends AsyncTask<Void, Void, SampleDataResult<String>> {
        private DataResponseHandler<SampleDataResult<String>> mResponseHandler;
        
        private SampleFirstBackgroundTask(DataResponseHandler<SampleDataResult<String>> responseHandler) {
            mResponseHandler = responseHandler;
        }
        
        @Override
        protected SampleDataResult<String> doInBackground(Void... params) {
            // Put whatever info
            ArrayList<String> values = new ArrayList<String>(MAX_SIZE_PER_PAGE);
            for (int i = 0; i < MAX_SIZE_PER_PAGE; i++) {
                values.add("" + i);
            }
            SampleDataResult<String> result = new SampleDataResult<String>();
            // Since this is loaded the first time, the max item should be made available.
            result.maxItems = MAX_ITEMS;
            result.values = values;
            try {
                // Pause for 5 seconds to simulate "busy" state.
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return result;
        }

        @Override
        protected void onPostExecute(SampleDataResult<String> result) {
            mResponseHandler.resultAvailable(0, result);
        }
        
    }

    /**
     * Sample implementation that "downloads" more data.
     * @author Makas Tzavellas (makas dot tzavellas at gmail dot com)
     *
     */
    private class SampleBackgroundTask extends AsyncTask<Integer, Void, SampleDataResult<String>> {
        private DataResponseHandler<SampleDataResult<String>> mResponseHandler;
        
        private SampleBackgroundTask(DataResponseHandler<SampleDataResult<String>> responseHandler) {
            mResponseHandler = responseHandler;
        }

        @Override
        protected SampleDataResult<String> doInBackground(Integer... params) {
            int currentSize = params[0];
            ArrayList<String> values = new ArrayList<String>(MAX_SIZE_PER_PAGE);
            
            int maxSize = currentSize + MAX_SIZE_PER_PAGE;
            if (maxSize > MAX_ITEMS)
                maxSize = MAX_ITEMS;
            
            for (int i = currentSize; i < maxSize; i++) {
                values.add("" + i);
            }
            SampleDataResult<String> result = new SampleDataResult<String>();
            result.values = values;
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return result;
        }
        
        @Override
        protected void onPostExecute(SampleDataResult<String> result) {
            mResponseHandler.resultAvailable(0, result);
        }
    }

}


package com.ql.app;

/*
 * Copyright (C) 2010 Makas Tzavellas
 *
 * 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.
 */
import java.util.ArrayList;

/**
 * Sample class that contains the download info.
 * @author Makas Tzavellas (makas dot tzavellas at gmail dot com)
 *
 * @param <T>
 */
public class SampleDataResult<T> {
    public int maxItems;

    public ArrayList<T> values;
}



package com.ql.service;

/*
 * Copyright (C) 2010 Makas Tzavellas
 *
 * 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.
 */

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ListView;

import java.util.ArrayList;

import com.ql.service.DataLoaderHandler.DataLoadedCallback;

/**
 * Abstract adapter which will display the "busy" view as footer when a background download occurs.
 * Also calls the {@link DataLoaderHandler} for its initial values as well as subsequent items as 
 * the user scrolls to the end.
 * 
 * @author Makas Tzavellas (makas dot tzavellas at gmail dot com)
 *
 * @param <T>
 */
public abstract class AbstractPageableAdapter<T> extends BaseAdapter implements AbsListView.OnScrollListener, DataLoadedCallback<T> {

    private DataLoaderHandler<T> mDataLoaderHandler;
    private ListView mListView;
    private View mLoadingView;
    private Context mContext;
    private ArrayList<T> mList = new ArrayList<T>();

    /**
     * 
     * @param listView The list view that this adapter will be added to.
     * @param context The activity context.
     * @param loadingViewResourceId The layout to use when displaying the "busy" status
     * @param handler The handler to use when loading more data to the list view.
     */
    public AbstractPageableAdapter(ListView listView, Context context, int loadingViewResourceId, DataLoaderHandler<T> handler) {
        mContext = context;
        mDataLoaderHandler = handler;
        mListView = listView;
        mLoadingView = LayoutInflater.from(context).inflate(loadingViewResourceId, null);
        showLoading(true);
        mDataLoaderHandler.getValues(this);
    }
    
    /**
     * The {@link Context} passed in the constructor.
     * @return
     */
    public final Context getContext() {
        return mContext;
    }
    
    public final int getCount() {
        return mList.size();
    }

    public Object getItem(int position) {
        return mList.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
            int totalItemCount) {
        // Nothing to do I suppose...
        
    }

    public void onScrollStateChanged(final AbsListView view, final int scrollState) {
        switch (scrollState) {
            case SCROLL_STATE_IDLE: {
                final int maxItems = mDataLoaderHandler.getMaxItems();
                final int first = mListView.getFirstVisiblePosition();
                final int count = mListView.getChildCount();
                final int total = getCount();
                
                if (first + count < total || mDataLoaderHandler.isLoading())
                    return;
                
                if (total < maxItems) {
                    showLoading(true);
                    mDataLoaderHandler.getNext(this);
                }
                break;
            }
        }
    }
    
    private void showLoading(boolean show) {
        if (show)
            mListView.addFooterView(mLoadingView);
        else
            mListView.removeFooterView(mLoadingView);
    }
    
    public void dataLoaded(ArrayList<T> values) {
        ArrayList<T> list = mList;
        for (T value : values) {
            list.add(value);
        }
        showLoading(false);
        notifyDataSetChanged();
    }
    
}


package com.ql.service;

/*
 * Copyright (C) 2010 Makas Tzavellas
 *
 * 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.
 */

import java.util.ArrayList;

/**
 * 
 * The implementation of the interface is responsible to load data in the background.
 * 
 * @author Makas Tzavellas (makas dot tzavellas at gmail dot com)
 * 
 * @param <T>
 */
public interface DataLoaderHandler<T> {
    /**
     * The maximum item that can be loaded.
     * This method should probably only be called after the initial download has occured.
     * @return The max item available.
     */
    int getMaxItems();
    
    /**
     * Returns values that has been loaded or may trigger the download of the first batch.
     * @param callback The callback to notify when data is available.
     */
    void getValues(DataLoadedCallback<T> callback);
    /**
     * Returns the next batch of data.
     * @param callback The callback to notify when data is available.
     */
    void getNext(DataLoadedCallback<T> callback);

    /**
     * True if the implementation is busy loading data in the background.
     * @return
     */
    boolean isLoading();
    
    /**
     * The implementation of this interface will be called when the data has been downloaded.
     * 
     * @author Makas Tzavellas (makas dot tzavellas at gmail dot com)
     * 
     * @param <T>
     */
    interface DataLoadedCallback<T> {
        /**
         * Notifies the implementation that the download has completed with a list of values.
         * @param values The new values downloaded.
         */
        void dataLoaded(ArrayList<T> values);
    }
}


package com.ql.service;

/*
 * Copyright (C) 2010 Makas Tzavellas
 *
 * 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.
 */
/**
 * Default interface to use when receiving a response from server.
 * 
 * @author Makas Tzavellas (makas dot tzavellas at gmail dot com)
 *
 * @param <T>
 */
public interface DataResponseHandler<T> {
    /**
     * Notify the implementation that response is available.
     * @param status The status of the download. Whether it was successful or failed.
     * @param result The result of the download if any.
     */
    void resultAvailable(int status, T result);
}




八:自定义ListView圆角
String[] mStrings = { "aaaa", "bbbb", "cccc" };
ListView listView = (ListView) findViewById(R.id.list);
		listView.setAdapter(new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1, mStrings));


<ListView android:id="@+id/list" android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:background="@layout/list_corner_1"
		android:layout_weight="1.0" />


<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
	android:shape="rectangle">
	<gradient android:startColor="#CCCCFF" android:endColor="#99CCFF"
		android:angle="90" />
	<corners android:bottomRightRadius="10dp"
		android:bottomLeftRadius="10dp" android:topLeftRadius="10dp"
		android:topRightRadius="10dp" />
</shape>




九:ListView分组查询
请看效果图:
[img]

[/img]
工程结构图:
[img]

[/img]

布局文件:
city_list_item_city_index.xml:
<?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="wrap_content">

	<TextView
		xmlns:android="http://schemas.android.com/apk/res/android"
		android:id="@+id/city_list_item_city_index"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:paddingLeft="14dip"
		android:paddingRight="14dip"
		android:gravity="center_vertical"
		android:background="#FFc0c0c0"
		android:textColor="#FF545454"
		android:textSize="18dip" />

</LinearLayout>



city_list_item_city.xml:
<?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="wrap_content">

	<TextView
		xmlns:android="http://schemas.android.com/apk/res/android"
		android:id="@+id/city_list_item_city"
		android:layout_width="fill_parent"
		android:layout_height="44dip"
		android:paddingLeft="14dip"
		android:paddingRight="14dip"
		android:gravity="center_vertical"
		android:checkMark="?android:attr/listChoiceIndicatorSingle"
		android:textColor="#FF333333"
		android:textSize="18dip" />


</LinearLayout>




city_list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/city_list_item"
	android:layout_width="fill_parent"
	android:layout_height="44dip"
	android:paddingLeft="14dip"
	android:paddingRight="14dip"
	android:gravity="center_vertical"
	android:checkMark="?android:attr/listChoiceIndicatorSingle"
	android:textColor="#FF333333"
	android:textSize="18dip" />



city_select.xml:
<?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="@color/white"
    android:orientation="vertical"
    android:padding="5dip" >

    <EditText
        android:id="@+id/edit_filter"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/input"
        android:hint="@string/str_region_filter" />

    <ListView
        android:id="@+id/list_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="#00000000"
        android:dividerHeight="1dip" />

</LinearLayout>



list_position.xml
<?xml version="1.0" encoding="utf-8"?>
	<!--
		Copyright (C) 2006 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.
	-->

<TextView
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:textSize="50sp"
	android:textColor="#5B5B5B5B"
	android:background="@drawable/bg_city_select_list_index"
	android:minWidth="70dip"
	android:maxWidth="70dip"
	android:padding="10dip"
	android:gravity="center" />



values/colors.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<color name="white">#FFFFFF</color><!--白色 -->
<color name="twhite">#7FFFFFFF</color><!--白色 -->
<color name="ivory">#FFFFF0</color><!--象牙色 -->
<color name="lightyellow">#FFFFE0</color><!--亮黄色 -->
<color name="yellow">#FFFF00</color><!--黄色 -->
<color name="snow">#FFFAFA</color><!--雪白色 -->
<color name="floralwhite">#FFFAF0</color><!--花白色 -->
<color name="lemonchiffon">#FFFACD</color><!--柠檬绸色 -->
<color name="cornsilk">#FFF8DC</color><!--米绸色 -->
<color name="seashell">#FFF5EE</color><!--海贝色 -->
<color name="lavenderblush">#FFF0F5</color><!--淡紫红 -->
<color name="papayawhip">#FFEFD5</color><!--番木色 -->
<color name="blanchedalmond">#FFEBCD</color><!--白杏色 -->
<color name="mistyrose">#FFE4E1</color><!--浅玫瑰色 -->
<color name="bisque">#FFE4C4</color><!--桔黄色 -->
<color name="moccasin">#FFE4B5</color><!--鹿皮色 -->
<color name="navajowhite">#FFDEAD</color><!--纳瓦白 -->
<color name="peachpuff">#FFDAB9</color><!--桃色 -->
<color name="gold">#FFD700</color><!--金色 -->
<color name="pink">#FFC0CB</color><!--粉红色 -->
<color name="lightpink">#FFB6C1</color><!--亮粉红色 -->
<color name="orange">#FFA500</color><!--橙色 -->
<color name="lightsalmon">#FFA07A</color><!--亮肉色 -->
<color name="darkorange">#FF8C00</color><!--暗桔黄色 -->
<color name="coral">#FF7F50</color><!--珊瑚色 -->
<color name="hotpink">#FF69B4</color><!--热粉红色 -->
<color name="tomato">#FF6347</color><!--西红柿色 -->
<color name="orangered">#FF4500</color><!--红橙色 -->
<color name="deeppink">#FF1493</color><!--深粉红色 -->
<color name="fuchsia">#FF00FF</color><!--紫红色 -->
<color name="magenta">#FF00FF</color><!--红紫色 -->
<color name="red">#FF0000</color><!--红色 -->
<color name="oldlace">#FDF5E6</color><!--老花色 -->
<color name="lightgoldenrodyellow">#FAFAD2</color><!--亮金黄色 -->
<color name="linen">#FAF0E6</color><!--亚麻色 -->
<color name="antiquewhite">#FAEBD7</color><!--古董白 -->
<color name="salmon">#FA8072</color><!--鲜肉色 -->
<color name="ghostwhite">#F8F8FF</color><!--幽灵白 -->
<color name="mintcream">#F5FFFA</color><!--薄荷色 -->
<color name="whitesmoke">#F5F5F5</color><!--烟白色 -->
<color name="beige">#F5F5DC</color><!--米色 -->
<color name="wheat">#F5DEB3</color><!--浅黄色 -->
<color name="sandybrown">#F4A460</color><!--沙褐色 -->
<color name="azure">#F0FFFF</color><!--天蓝色 -->
<color name="honeydew">#F0FFF0</color><!--蜜色 -->
<color name="aliceblue">#F0F8FF</color><!--艾利斯兰 -->
<color name="khaki">#F0E68C</color><!--黄褐色 -->
<color name="lightcoral">#F08080</color><!--亮珊瑚色 -->
<color name="palegoldenrod">#EEE8AA</color><!--苍麒麟色 -->
<color name="violet">#EE82EE</color><!--紫罗兰色 -->
<color name="darksalmon">#E9967A</color><!--暗肉色 -->
<color name="lavender">#E6E6FA</color><!--淡紫色 -->
<color name="lightcyan">#E0FFFF</color><!--亮青色 -->
<color name="burlywood">#DEB887</color><!--实木色 -->
<color name="plum">#DDA0DD</color><!--洋李色 -->
<color name="gainsboro">#DCDCDC</color><!--淡灰色 -->
<color name="crimson">#DC143C</color><!--暗深红色 -->
<color name="palevioletred">#DB7093</color><!--苍紫罗兰色 -->
<color name="goldenrod">#DAA520</color><!--金麒麟色 -->
<color name="orchid">#DA70D6</color><!--淡紫色 -->
<color name="thistle">#D8BFD8</color><!--蓟色 -->
<color name="lightgray">#D3D3D3</color><!--亮灰色 -->
<color name="lightgrey">#D3D3D3</color><!--亮灰色 -->
<color name="tan">#D2B48C</color><!--茶色 -->
<color name="chocolate">#D2691E</color><!--巧可力色 -->
<color name="peru">#CD853F</color><!--秘鲁色 -->
<color name="indianred">#CD5C5C</color><!--印第安红 -->
<color name="mediumvioletred">#C71585</color><!--中紫罗兰色 -->
<color name="silver">#C0C0C0</color><!--银色 -->
<color name="darkkhaki">#BDB76B</color><!--暗黄褐色 -->
<color name="rosybrown">#BC8F8F</color><!--褐玫瑰红 -->
<color name="mediumorchid">#BA55D3</color><!--中粉紫色 -->
<color name="darkgoldenrod">#B8860B</color><!--暗金黄色 -->
<color name="firebrick">#B22222</color><!--火砖色 -->
<color name="powderblue">#B0E0E6</color><!--粉蓝色 -->
<color name="lightsteelblue">#B0C4DE</color><!--亮钢兰色 -->
<color name="paleturquoise">#AFEEEE</color><!--苍宝石绿 -->
<color name="greenyellow">#ADFF2F</color><!--黄绿色 -->
<color name="lightblue">#ADD8E6</color><!--亮蓝色 -->
<color name="darkgray">#A9A9A9</color><!--暗灰色 -->
<color name="darkgrey">#A9A9A9</color><!--暗灰色 -->
<color name="brown">#A52A2A</color><!--褐色 -->
<color name="sienna">#A0522D</color><!--赭色 -->
<color name="darkorchid">#9932CC</color><!--暗紫色 -->
<color name="palegreen">#98FB98</color><!--苍绿色 -->
<color name="darkviolet">#9400D3</color><!--暗紫罗兰色 -->
<color name="mediumpurple">#9370DB</color><!--中紫色 -->
<color name="lightgreen">#90EE90</color><!--亮绿色 -->
<color name="darkseagreen">#8FBC8F</color><!--暗海兰色 -->
<color name="saddlebrown">#8B4513</color><!--重褐色 -->
<color name="darkmagenta">#8B008B</color><!--暗洋红 -->
<color name="darkred">#8B0000</color><!--暗红色 -->
<color name="blueviolet">#8A2BE2</color><!--紫罗兰蓝色 -->
<color name="lightskyblue">#87CEFA</color><!--亮天蓝色 -->
<color name="skyblue">#87CEEB</color><!--天蓝色 -->
<color name="gray">#808080</color><!--灰色 -->
<color name="olive">#808000</color><!--橄榄色 -->
<color name="purple">#800080</color><!--紫色 -->
<color name="maroon">#800000</color><!--粟色 -->
<color name="aquamarine">#7FFFD4</color><!--碧绿色 -->
<color name="chartreuse">#7FFF00</color><!--黄绿色 -->
<color name="lawngreen">#7CFC00</color><!--草绿色 -->
<color name="mediumslateblue">#7B68EE</color><!--中暗蓝色 -->
<color name="lightslategray">#778899</color><!--亮蓝灰 -->
<color name="lightslategrey">#778899</color><!--亮蓝灰 -->
<color name="slategray">#708090</color><!--灰石色 -->
<color name="slategrey">#708090</color><!--灰石色 -->
<color name="olivedrab">#6B8E23</color><!--深绿褐色 -->
<color name="slateblue">#6A5ACD</color><!--石蓝色 -->
<color name="dimgray">#696969</color><!--暗灰色 -->
<color name="dimgrey">#696969</color><!--暗灰色 -->
<color name="mediumaquamarine">#66CDAA</color><!--中绿色 -->
<color name="cornflowerblue">#6495ED</color><!--菊兰色 -->
<color name="cadetblue">#5F9EA0</color><!--军兰色 -->
<color name="darkolivegreen">#556B2F</color><!--暗橄榄绿 -->
<color name="indigo">#4B0082</color><!--靛青色 -->
<color name="mediumturquoise">#48D1CC</color><!--中绿宝石 -->
<color name="darkslateblue">#483D8B</color><!--暗灰蓝色 -->
<color name="steelblue">#4682B4</color><!--钢兰色 -->
<color name="royalblue">#4169E1</color><!--皇家蓝 -->
<color name="turquoise">#40E0D0</color><!--青绿色 -->
<color name="mediumseagreen">#3CB371</color><!--中海蓝 -->
<color name="limegreen">#32CD32</color><!--橙绿色 -->
<color name="darkslategray">#2F4F4F</color><!--暗瓦灰色 -->
<color name="darkslategrey">#2F4F4F</color><!--暗瓦灰色 -->
<color name="seagreen">#2E8B57</color><!--海绿色 -->
<color name="forestgreen">#228B22</color><!--森林绿 -->
<color name="lightseagreen">#20B2AA</color><!--亮海蓝色 -->
<color name="dodgerblue">#1E90FF</color><!--闪兰色 -->
<color name="midnightblue">#191970</color><!--中灰兰色 -->
<color name="aqua">#00FFFF</color><!--浅绿色 -->
<color name="cyan">#00FFFF</color><!--青色 -->
<color name="springgreen">#00FF7F</color><!--春绿色 -->
<color name="lime">#00FF00</color><!--酸橙色 -->
<color name="mediumspringgreen">#00FA9A</color><!--中春绿色 -->
<color name="darkturquoise">#00CED1</color><!--暗宝石绿 -->
<color name="deepskyblue">#00BFFF</color><!--深天蓝色 -->
<color name="darkcyan">#008B8B</color><!--暗青色 -->
<color name="teal">#008080</color><!--水鸭色 -->
<color name="green">#008000</color><!--绿色 -->
<color name="darkgreen">#006400</color><!--暗绿色 -->
<color name="blue">#0099FF</color><!--蓝色 -->
<color name="mediumblue">#0000CD</color><!--中兰色 -->
<color name="darkblue">#00008B</color><!--暗蓝色 -->
<color name="navy">#000080</color><!--海军色 -->
<color name="black">#000000</color><!--黑色 -->
<color name="downloadbar">#525552</color>
</resources>


valus/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, EX02_ListviewAlphabeticalIndexActivity!</string>
    <string name="app_name">EX02_ListviewAlphabeticalIndex</string>
    <string name="str_region_filter">请输入城市首字母</string>
</resources>



AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest
	xmlns:android="http://schemas.android.com/apk/res/android"
	package="com.magus.listview"
	android:versionCode="1"
	android:versionName="1.0">
	<uses-sdk
		android:minSdkVersion="8" />

	<application
		android:icon="@drawable/icon"
		android:label="@string/app_name">
		<activity
			android:configChanges="orientation|keyboardHidden"
			android:label="@string/app_name"
			android:name="CitySelectActivity"
			android:screenOrientation="portrait"
			android:windowSoftInputMode="stateHidden|adjustUnspecified">
			<intent-filter>
				<action
					android:name="android.intent.action.MAIN" />
				<category
					android:name="android.intent.category.LAUNCHER" />
			</intent-filter>
		</activity>

	</application>
</manifest>



City:
package com.magus.listview;

import java.util.ArrayList;

public class City {

	private String cityId;
	private String cityName;
	private String cityPinyin;
	private int cityType;
	public static final int TYPE_CITY_HOT = 0; // 热门城市
	public static final int TYPE_CITY_NORMAL = 1;// 普通城市

	City() {

	}

	City(String cityid, String ciryname, String citypinyin, int citytype) {

		cityId = cityid;
		cityName = ciryname;
		cityPinyin = citypinyin;
		cityType = citytype;
	}

	City(String ciryname, String citypinyin, int citytype) {

		cityId = "";
		cityName = ciryname;
		cityPinyin = citypinyin;
		cityType = citytype;
	}

	public String getCityId() {
		return cityId;
	}

	public void setCityId(String cityId) {
		this.cityId = cityId;
	}

	public String getCityName() {
		return cityName;
	}

	public void setCityName(String cityName) {
		this.cityName = cityName;
	}

	public String getCityPinyin() {
		return cityPinyin;
	}

	public void setCityPinyin(String cityPinyin) {
		this.cityPinyin = cityPinyin;
	}

	public int getCityType() {
		return cityType;
	}

	public void setCityType(int cityType) {
		this.cityType = cityType;
	}

	public static ArrayList<City> getCityList() {

		ArrayList<City> cityList = new ArrayList<City>();

		// 热门城市
		City mCity;

		// A
		mCity = new City("安顺", "AS", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		mCity = new City("安徽", "AH", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		// B
		mCity = new City("包头", "BT", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		mCity = new City("滨州", "BZ", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		// C
		mCity = new City("长春", "CC", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		mCity = new City("常德", "CD", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		mCity = new City("从化", "CH", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		mCity = new City("重庆", "CQ", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		mCity = new City("常熟", "CS", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		mCity = new City("常州", "CZ", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		mCity = new City("郴州", "CZ", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		// D
		mCity = new City("丹东", "DD", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		mCity = new City("大连", "DL", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		mCity = new City("大庆", "DQ", TYPE_CITY_NORMAL);
		cityList.add(mCity);
		mCity = new City("德州", "DZ", TYPE_CITY_NORMAL);
		cityList.add(mCity);

		return cityList;

	}

}


Utils:
package com.magus.listview;

import java.util.ArrayList;
import java.util.List;

public class Utils {

	/**
	 * 处理城市列表,加入开头字幕索引
	 * 
	 * @author johnson 安顺 北京 ==加工==> A 安顺 B 北京
	 * **/

	public static ArrayList<City> rebuildList(List<City> mList) {

		String cityPinyin = "";
		String indexPinyin = "0";

		final ArrayList<City> buildList = new ArrayList<City>();
		for (City city : mList) {
			cityPinyin = city.getCityPinyin().substring(0, 1);
			if (!cityPinyin.equals(indexPinyin)) {
				indexPinyin = cityPinyin;
				buildList.add(addCityIndex(indexPinyin));
				buildList.add(city);
			} else {
				buildList.add(city);
			}

		}
		return buildList;

	}

	/**
	 * 开头字幕索引
	 * 
	 * @author johnson
	 */
	public static City addCityIndex(String str) {

		return new City("-"+ str, str, City.TYPE_CITY_NORMAL);

	}

}



CitySelectActivity:
package com.magus.listview;

import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * 
 * 城市选择 activity
 * 
 * @author Johnson
 * 
 */
public class CitySelectActivity extends Activity implements
		ListView.OnScrollListener {

	// 城市选择

	private ListView listView;
	private ArrayList<City> listBasicData = new ArrayList<City>();// 存放原始数据;
	private ArrayList<City> list = new ArrayList<City>();// 存放临时数据
	private LayoutInflater mInflater;
	private RemoveWindow mRemoveWindow = new RemoveWindow();
	private WindowManager mWindowManager;
	private TextView mDialogText;
	private boolean mShowing;
	private boolean mReady;
	private String mPrevLetter = "";
	private EditText filterEdit;
	Handler mHandler = new Handler();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
        //原始数据
		listBasicData = City.getCityList();
		
		//初始化显示数据加入字幕索引item
		initShowData();
		this.setContentView(R.layout.city_select);
		mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		listView = (ListView) findViewById(R.id.list_view);
		final myAdapter adapter = new myAdapter();
		listView.setAdapter(adapter);
		listView.setItemsCanFocus(false);
		listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);// 设置单选模型
		listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				
			Toast.makeText(getApplicationContext(), list.get(position).getCityName(), Toast.LENGTH_SHORT).show();
				
			}
		});

		filterEdit = (EditText) findViewById(R.id.edit_filter);
		filterEdit.addTextChangedListener(new TextWatcher() {
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
			}

			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}

			public void afterTextChanged(Editable s) {
	
				final String txt = s.toString().toLowerCase();
				if (list != null) {
					list.clear();

					if (listBasicData != null && listBasicData.size() > 0) {
						for (City mCity : listBasicData) {

							String pinyin = mCity.getCityPinyin();
							String name = mCity.getCityName();
							if (pinyin.startsWith(txt)
									|| pinyin.startsWith(txt.toLowerCase())
									|| pinyin.startsWith(txt.toUpperCase())
									|| (name.indexOf(txt) != -1)) {
								list.add(mCity);
							}
						}
						if ("".equals(txt)) {
							//当字母过滤框内容为空重新初始化数据
							initShowData();
						}

						if ("".equals(txt)) {

							mReady = true;
						} else {
					
							mReady = false;
						}

						// List数据变化时, 刷新Dialog
						// dialog.notifyDataSetChanged();
						adapter.notifyDataSetChanged();
					}
				}
			}
		});

		initIndexTextView();
	}



	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		int visibleItemIndex = firstVisibleItem;
		
		
		
		// int visibleItemIndex = firstVisibleItem + (visibleItemCount / 2 - 1);
		
		
		if (mReady) {

			City city = (City) list.get(visibleItemIndex);

			String firstLetter = city.getCityPinyin();
			System.out.println("@" + firstLetter);

			if (firstLetter.equals("-")) {
				firstLetter = firstLetter.substring(1, 2);
			} else {
				firstLetter = firstLetter.substring(0, 1);
			}

			if (!mShowing && firstLetter.equals(mPrevLetter)) {

				mShowing = true;
				mDialogText.setVisibility(View.VISIBLE);
			}

			mDialogText.setTextSize(40);
			mDialogText.setText(firstLetter);
			mHandler.removeCallbacks(mRemoveWindow);
			mHandler.postDelayed(mRemoveWindow, 1000);
			mPrevLetter = firstLetter;
		}
	}

	@Override
	public void onScrollStateChanged(AbsListView arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	private void removeWindow() {

		if (mShowing) {
			mShowing = false;
			mDialogText.setVisibility(View.INVISIBLE);
		}
	}

	private final class RemoveWindow implements Runnable {
		public void run() {
			removeWindow();
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		mReady = true;
	}

	@Override
	protected void onPause() {
		super.onPause();
		removeWindow();
		mReady = false;
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (mWindowManager != null) {
			mWindowManager.removeView(mDialogText);
		}

		mReady = false;
	}

	class myAdapter extends BaseAdapter {

		View convertView;

		City city;

		@Override
		public boolean isEnabled(int position) {

			if (city != null) {
				return !city.getCityName().startsWith("-");
			} else {
				return true;
			}

		}

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return list.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return list.get(position);
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public View getView(int position, View convertVie, ViewGroup arg2) {
			// TODO Auto-generated method stub
			convertView = convertVie;
			TextView tv;

			city = (City) list.get(position);

			if (city.getCityName().startsWith("-")) {

				convertView = mInflater.inflate(
						R.layout.city_list_item_city_index, null);
				tv = (TextView) convertView
						.findViewById(R.id.city_list_item_city_index);
				tv.setText(city.getCityName().substring(1,
						city.getCityName().length()));

			} else {

				convertView = mInflater.inflate(R.layout.city_list_item_city,
						null);
				tv = (TextView) convertView
						.findViewById(R.id.city_list_item_city);
				tv.setText(city.getCityName());
			}

			return convertView;
		}
	}

	/**
	 * 初始化用于显示的数据
	 *  
	 * @author johnson
	 * 
	 * */
	
	public void initShowData() {

		list.clear();
		list = Utils.rebuildList(listBasicData);

	}
	
	/**
	 * 初始化程序列表索引IndexTextView
	 * 
	 * @author johnson
	 * */ 
	
	
	public void initIndexTextView() {
		mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		listView.setOnScrollListener(this);
		mDialogText = (TextView) mInflater
				.inflate(R.layout.list_position, null);
		mDialogText.setVisibility(View.INVISIBLE);
		mHandler.post(new Runnable() {

			public void run() {
				mReady = true;
				WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
						LayoutParams.WRAP_CONTENT,
						LayoutParams.WRAP_CONTENT,
						WindowManager.LayoutParams.TYPE_APPLICATION_STARTING,
						WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
								| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
						PixelFormat.TRANSLUCENT);

				mWindowManager.addView(mDialogText, lp);
			}
		});

	}

}




十:ListView去掉橙黄底色
在ListView中,系统默认选中时会出现橙黄底色。有时候我们不需要这样的效果,如何去掉?可在ListView中增加 android:listSelector="@android:color/transparent"


十一、List可扩展的列表:
请看效果图:
[img]

[/img]
package com.zhou.activity;

import android.app.ExpandableListActivity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;

public class ExpandableList extends ExpandableListActivity {
	//声明adapter
	private ExpandableListAdapter mAdapter;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//设这标题
		setTitle("可扩展的列表");
		//实例化adapter
		mAdapter = new MyExpandableListAdapter();
		//为列表设置adapter
		setListAdapter(mAdapter);
		//为list注册context菜单
		registerForContextMenu(this.getExpandableListView());
	}
	
	
	@Override
	public boolean onChildClick(ExpandableListView parent, View v,
			int groupPosition, int childPosition, long id) {
		Toast.makeText(this, " 组元素索引: " + groupPosition + " 子元素索引: " + childPosition, Toast.LENGTH_SHORT).show();
		return super.onChildClick(parent, v, groupPosition, childPosition, id);
	}


	@Override
	public void onGroupExpand(int groupPosition) {
		Toast.makeText(this, " 组元素索引: " + groupPosition, Toast.LENGTH_SHORT).show();
		super.onGroupExpand(groupPosition);
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		menu.setHeaderTitle("上下文菜单");
		menu.add(0, 0, 0, "单击我");
	}

	// 单击上下文菜单后的逻辑
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo();
		String title = ((TextView) info.targetView).getText().toString();

		int type = ExpandableListView.getPackedPositionType(info.packedPosition);
		if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
			int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
			int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition);
			Toast.makeText(this, title + " 组元素索引: " + groupPos + " 子元素索引: " + childPos, Toast.LENGTH_SHORT).show();
			return true;
		} else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
			int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
			Toast.makeText(this, title + " 组元素索引: " + groupPos, Toast.LENGTH_SHORT).show();
			return true;
		}
		return false;
	}
	//自定义Adapter
	public class MyExpandableListAdapter extends BaseExpandableListAdapter {
		// 父列表数据
		private String[] groups = 
		{ 
			"吉林省", 
			"辽宁省", 
			"黑龙江省",
			"山东省" 
		};
		// 子列表数据
		private String[][] children = 
		{
			{ "长春市" },
			{ "沈阳市", "铁岭市" },
			{ "哈尔滨市", "齐齐哈尔市", "牡丹江市" },
			{ "济南市", "青岛市", "淄博市", "潍坊市" }
		};
		@Override
		public Object getChild(int groupPosition, int childPosition) {
			return children[groupPosition][childPosition];
		}
		@Override
		public long getChildId(int groupPosition, int childPosition) {
			return childPosition;
		}
		@Override
		public int getChildrenCount(int groupPosition) {
			return children[groupPosition].length;
		}
		// 取子列表中的某一项的 View
		@Override
		public View getChildView(int groupPosition, int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			TextView textView = getGenericView();
			textView.setText(getChild(groupPosition, childPosition).toString());
			return textView;
		}
		@Override
		public Object getGroup(int groupPosition) {
			return groups[groupPosition];
		}
		@Override
		public int getGroupCount() {
			return groups.length;
		}
		@Override
		public long getGroupId(int groupPosition) {
			return groupPosition;
		}
		// 取父列表中的某一项的 View
		@Override
		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			TextView textView = getGenericView();
			textView.setText(getGroup(groupPosition).toString());
			return textView;
		}
		@Override
		public boolean hasStableIds() {
			return true;
		}
		@Override
		public boolean isChildSelectable(int groupPosition, int childPosition) {
			return true;
		}
		// 获取某一项的 View 的逻辑
		private TextView getGenericView() {
			AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
					ViewGroup.LayoutParams.FILL_PARENT, 48);
			TextView textView = new TextView(ExpandableList.this);
			textView.setLayoutParams(lp);
			textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
			textView.setPadding(32, 0, 0, 0);
			return textView;
		}
	}
}
1 楼 yahier 2012-02-23  
感谢分享

    
[2] 【通译】(27)应用程序资源
    来源: 互联网  发布时间: 2014-02-18
【翻译】(27)应用程序资源

【翻译】(27)应用程序资源

 

see

http://developer.android.com/guide/topics/resources/index.html

 

原文见

http://developer.android.com/guide/topics/resources/index.html

 

-------------------------------

 

Application Resources

 

应用程序资源

 

Topics

 

主题

 

* Providing Resources 提供资源

* Accessing Resources 访问资源

* Handling Runtime Changes 处理运行时改变

* Localization 本地化

 

Reference 

 

参考

 

Resource Types 资源类型

 

You should always externalize resources such as images and strings from your application code, so that you can maintain them independently. Externalizing your resources also allows you to provide alternative resources that support specific device configurations such as different languages or screen sizes, which becomes increasingly important as more Android-powered devices become available with different configurations. In order to provide compatibility with different configurations, you must organize resources in your project's res/ directory, using various sub-directories that group resources by type and configuration.

 

你应该总是从你的应用程序中外部化资源诸如图片和字符串,使你可以独立地维护它们。外部化你的资源还允许你提供支持特定设备配置的可选资源诸如不同的语言或屏幕大小,这随着带有不同配置的更多基于Android的设备变得可用而变得日益重要。为了提供不同配置的兼容性,你必须在你的工程的res/目录下组织资源,使用不同的子目录根据类型和配置分组资源。

 

(图1略:

Android设备A

Android应用 默认资源

Android设备B

 

Figure 1. Two different devices, both using default resources.

 

图1. 两个不同的设备,都使用默认资源。

 

 

(图2略:

Android设备A

Android应用 默认资源 可选资源B

Android设备B

 

Figure 2. Two different devices, one using alternative resources.

 

图2. 两个不同的设备,其中有一个使用候选资源。

 

For any type of resource, you can specify default and multiple alternative resources for your application:

 

对于任意类型的资源,你可以为你的应用程序指定默认的和多个候选的资源:

 

* Default resources are those that should be used regardless of the device configuration or when there are no alternative resources that match the current configuration.

 

* 默认资源是那些应该在无需考虑设备配置或者在没有候选的资源匹配当前配置的时候使用的资源。

 

* Alternative resources are those that you've designed for use with a specific configuration. To specify that a group of resources are for a specific configuration, append an appropriate configuration qualifier to the directory name.

 

* 候选资源是那些你已经设计好用于特定配置的资源。为了指定一组资源用于一个特定的配置,请尾加一个合适的配置修饰符到目录名。

 

For example, while your default UI layout is saved in the res/layout/ directory, you might specify a different UI layout to be used when the screen is in landscape orientation, by saving it in the res/layout-land/ directory. Android automatically applies the appropriate resources by matching the device's current configuration to your resource directory names.

 

例如,当你的默认用户界面布局保存在res/layout/目录,你可以指定一个不同的用户界面布局在屏幕处于宽屏方向时使用,通过保存它在res/layout-land/目录下。Android通过匹配设备的当前配置到你的资源目录名,自动地应用合适的资源。

 

Figure 1 demonstrates how a collection of default resources from an application are applied to two different devices when there are no alternative resources available. Figure 2 shows the same application with a set of alternative resources that qualify for one of the device configurations, thus, the two devices uses different resources.

 

图1演示当没有可用的可选资源时,来自一个应用程序的一组默认资源如何被应用到两个不同的设备。图2展示带有一组分别修饰一种设备配置的可选资源的相同应用程序,这种情况下,两个设备使用不同的资源。

 

The information above is just an introduction to how application resources work on Android. The following documents provide a complete guide to how you can organize your application resources, specify alternative resources, access them in your application, and more:

 

上面的信息只是介绍应用程序资源是如何工作在Android上。以下文档提供一个完整的指引,关于你如何可以组织你的应用程序资源,指定候选资源,在你的应用程序中访问它们,以及更多:

 

* Providing Resources

 

* 提供资源

 

What kinds of resources you can provide in your app, where to save them, and how to create alternative resources for specific device configurations.

 

你可以在你的应用中提供哪些类型的资源,在哪里保存它们,以及如何为特定的设备配置创建候选资源。

 

* Accessing Resources

 

* 访问资源

 

How to use the resources you've provided, either by referencing them from your application code or from other XML resources.

 

如何使用你已经提供的资源,通过从你的应用程序代码中或者从其它XML资源中引用它们来做到。

 

* Handling Runtime Changes

 

* 处理运行时改变

 

How to manage configuration changes that occur while your Activity is running.

 

如何管理在你的Activity正在运行时发生的配置改变。

 

* Localization

 

* 本地化

 

A bottom-up guide to localizing your application using alternative resources. While this is just one specific use of alternative resources, it is very important in order to reach more users.

 

一个关于使用可选资源本地化你的应用程序的自下而上的指引。虽然这只是可选资源的一个特定用途,然而这对于接触更多用户来说非常重要。

 

* Resource Types

 

* 资源类型

 

A reference of various resource types you can provide, describing their XML elements, attributes, and syntax. For example, this reference shows you how to create a resource for application menus, drawables, animations, and more.

 

你可以提供的不同资源类型的参考文档,描述它们的XML元素、属性,以及语法。例如,这个参考文档向你展示如何为应用程序的菜单、可绘画对象、动画,以及更多东西创建一个资源。

 

Except as noted, this content is licensed under Apache 2.0. For details and restrictions, see the Content License.

 

除特别说明外,本文在Apache 2.0下许可。细节和限制请参考内容许可证。

 

Android 4.0 r1 - 21 Dec 2011 3:15

 

-------------------------------

 

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

 

(此页部分内容基于Android开源项目,以及使用根据创作公共2.5来源许可证描述的条款进行修改)

 

(本人翻译质量欠佳,请以官方最新内容为准,或者参考其它翻译版本:

* ソフトウェア技術ドキュメントを勝手に翻訳

http://www.techdoctranslator.com/android

* Ley's Blog

http://leybreeze.com/blog/

* 农民伯伯

http://www.cnblogs.com/over140/

* Android中文翻译组

http://androidbox.sinaapp.com/

 


    
[3] 挥动特效
    来源: 互联网  发布时间: 2014-02-18
晃动特效

头文件:

 

#import <UIKit/UIKit.h>

@interface AccelerometerViewController : UIViewController <UIAccelerometerDelegate> {
	UILabel *label;
}

@property (nonatomic, retain) IBOutlet UILabel *label;

@end

 

实现文件:

 

#import "AccelerometerViewController.h"

@implementation AccelerometerViewController

@synthesize label;

- (void)viewDidLoad {
	[super viewDidLoad];
	UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
	accelerometer.delegate = self;
	accelerometer.updateInterval = 1.0f/60.0f;
}

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
	static NSInteger shakeCount = 0;
	static NSDate *shakeStart;
	NSDate *now = [[NSDate alloc] init];
	NSDate *checkDate = [[NSDate alloc] initWithTimeInterval:2.0f sinceDate:shakeStart];
	
	if ([now compare:checkDate] == NSOrderedDescending || shakeStart == nil) {
		shakeCount = 0;
		shakeStart = [[NSDate alloc] init];                                
	}
	
	[now release];
	[checkDate release];
	
	if (fabsf(acceleration.x) > 2.0 || fabsf(acceleration.y) > 2.0|| fabsf(acceleration.z) > 2.0) {
		shakeCount++;
		if (shakeCount > 4){
			shakeCount = 0;
			shakeStart = [[NSDate alloc] init];
			label.text = @"地震了";              
			[NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(cleartext) userInfo:nil repeats:NO];
		}
	}
}                

-(void)cleartext{
	label.text = @"没地震";
}

- (void)dealloc {
	[label release];
	label = nil;
	[super dealloc];
}

@end
 

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3