# Build UI
Layout object can contain any type of view - even other layouts.
但是如果是纯XML或者纯Code模式,setContentView()就必须放在后面,除非需要先对views进行引用:
Android 2.2 之后 FILL_PARENT 已弃用,转而使用 MATCH_PARENT , 这只是严格意义上的名称变更,他们的值不变,还是 -1 .
所以,可以直接用-1 避免版本上的差异。
# Text Controls
\ TextView use the setText() method to set value, The TextView display text but not allow to editing.
set autoLink in code:
# AutoCompleteTextView
# Button Control
可设置pressed. Pressed means that the button’s appearance changes when it has been pressed but before the user has let go.
第二,default状态要放在最后,因为会按照顺序测试状态,而default测试总是成功的
android:state_selected是选中
android:state_focused是获得焦点
android:state_pressed是点击
android:state_enabled是设置是否响应事件,指所有事件
根据这些状态同样可以设置button的selector效果。也可以设置selector改变button中的文字状态
然后在layout中设置 selector
# ToggleButton Control
# Check Boxes
设置check状态函数: setChecked() or toggle(), 获取当前状态 isChecked();
如果在XML中加入了android:onClick="myClickerHandler", 可以像BUTTON一样统一设定一个处理click的函数:
# Radio Button 单选按钮
一样可以使用onCheckedChangeListener(),但和前面不同,这里要使用RadioGroup.onCheckedChangeListener()
RadioGroup只能影响group内的RadioButton, group外的RadioButton和group内的非RadioButton都无法影响。
不用逐个检查RadioButton是否checked,可以直接调用getCheckedRadioButtonId();
# ImageView
# Adapter
# SimpleCursorAdapter
Android不会为每一行数据建立adapter,而只会根据view可显示的数量,在以childLayout形式建立adapter,并且会比同屏可显示的多一些(类似缓冲,提高浏览速度)。
# ArrayAdapter
ArrayAdapter is simpler than SimpleCursorAdapter
不同的是只pass了一组array as the actual data,没有pass a cursor or a "to array".
当childLayout对象不是TextView时,可以传递资源ID和TextView资源ID来接收数据。如果没有现成的string array, 可以用createFromResource()函数。
另外:sort()可以重新排序array,当然这样会失去data array和ListView之间的同步,因此还要call notifyDataSetChanged() 来resync the ListView with the adapter.
# Adapters that Android provides:
# Using Adapter with AdapterView
# ListView: set data by calling setListAdapter() method.
# Creating Custom Adapters
Layout object can contain any type of view - even other layouts.
setContentView(R.layout.main);
TextView nameValue = (TextView)findViewById(R.id.nameValue);
nameValue.setText("John Doe");
TextView addrValue = (TextView)findViewById(R.id.addrValue);
addrValue.setText("911 Hollywood Blvd.")
Load the resource by calling setContentView(R.layout.main) before calling findViewById()—we cannot get references to views if they have not been loaded yet.
TextView nameValue = (TextView)findViewById(R.id.nameValue);
nameValue.setText("John Doe");
TextView addrValue = (TextView)findViewById(R.id.addrValue);
addrValue.setText("911 Hollywood Blvd.")
但是如果是纯XML或者纯Code模式,setContentView()就必须放在后面,除非需要先对views进行引用:
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
createNameContainer();
createAddressContainer();
createParentContainer();
setContentView(parentContainer);
}
# FILL_PARENT vs. MATCH_PARENT
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
createNameContainer();
createAddressContainer();
createParentContainer();
setContentView(parentContainer);
}
Android 2.2 之后 FILL_PARENT 已弃用,转而使用 MATCH_PARENT , 这只是严格意义上的名称变更,他们的值不变,还是 -1 .
所以,可以直接用-1 避免版本上的差异。
# Text Controls
\ TextView use the setText() method to set value, The TextView display text but not allow to editing.
<
TextView
android:autoLink
="email|web"
/>
如果用户点击到这个highlight items, 系统会使用邮件程序打开邮件 | 或者用浏览器打开指定的网页。
set autoLink in code:
TextView tv =(TextView)
this.findViewById(R.id.tv)
tv.setAutoLinkMask(Linkify.ALL);
tv.setText("Please visit my website, http://www.androidbook.com or email me at davemac327@gmail.com.");
set the link before set text, because setAutoLinkMask won't affect the existing text.
tv.setAutoLinkMask(Linkify.ALL);
tv.setText("Please visit my website, http://www.androidbook.com or email me at davemac327@gmail.com.");
# AutoCompleteTextView
<AutoCompleteTextView android:id="@+id/actv"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
AutoCompleteTextView actv = (AutoCompleteTextView) this.findViewById(R.id.actv);
ArrayAdapter<String> aa = new ArrayAdapter<String>( this,
android.R.layout.simple_dropdown_item_1line,
new String[] {"English", "Hebrew", "Hindi","Spanish", "German", "Greek" });
actv.setAdapter(aa);
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
AutoCompleteTextView actv = (AutoCompleteTextView) this.findViewById(R.id.actv);
ArrayAdapter<String> aa = new ArrayAdapter<String>( this,
android.R.layout.simple_dropdown_item_1line,
new String[] {"English", "Hebrew", "Hindi","Spanish", "German", "Greek" });
actv.setAdapter(aa);
# Button Control
<Button android:id="@+id/button1"
android:text="@string/basicBtnLabel"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
Button button1 = (Button) this.findViewById(R.id.button1);
button1.setOnClickListener( new OnClickListener()
{
public void onClick(View v)
{
Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.androidbook.com"));
startActivity(intent);
}
});
# Android1.6之后可以更简便的设置handler
android:text="@string/basicBtnLabel"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
Button button1 = (Button) this.findViewById(R.id.button1);
button1.setOnClickListener( new OnClickListener()
{
public void onClick(View v)
{
Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.androidbook.com"));
startActivity(intent);
}
});
<Button
android:onClick="myClickHandler"
/>
public void myClickHandler(View target) {
switch(target.getId()) {
case R.id.button1:
# Image Button 2种方法设置Image:
public void myClickHandler(View target) {
switch(target.getId()) {
case R.id.button1:
<ImageButton android:id="@+id/imageButton2"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:onClick="myClickHandler"
android:src="@drawable/icon" />
ImageButton imageButton2 = (ImageButton) this.findViewById(R.id.imageButton2);
imageButton2.setImageResource(R.drawable.icon);
ImageButton可设置focus. You can direct focus to a button using the arrow keys on the keypad or D-pad.
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:onClick="myClickHandler"
android:src="@drawable/icon" />
ImageButton imageButton2 = (ImageButton) this.findViewById(R.id.imageButton2);
imageButton2.setImageResource(R.drawable.icon);
可设置pressed. Pressed means that the button’s appearance changes when it has been pressed but before the user has let go.
<?
xml version="1.0" encoding="utf-8"
?>
< selector xmlns:android ="http://schemas.android.com/apk/res/android" >
< item android:state_pressed ="true"
android:drawable ="@drawable/button_pressed" /> <!-- pressed -->
< item android:state_focused ="true"
android:drawable ="@drawable/button_focused" /> <!-- focused -->
< item android:drawable ="@drawable/icon" /> <!-- default -->
</ selector >
Note: 第一,这段XML在drawable中配置,因此不需要加上<resources> tag;
< selector xmlns:android ="http://schemas.android.com/apk/res/android" >
< item android:state_pressed ="true"
android:drawable ="@drawable/button_pressed" /> <!-- pressed -->
< item android:state_focused ="true"
android:drawable ="@drawable/button_focused" /> <!-- focused -->
< item android:drawable ="@drawable/icon" /> <!-- default -->
</ selector >
第二,default状态要放在最后,因为会按照顺序测试状态,而default测试总是成功的
android:state_selected是选中
android:state_focused是获得焦点
android:state_pressed是点击
android:state_enabled是设置是否响应事件,指所有事件
根据这些状态同样可以设置button的selector效果。也可以设置selector改变button中的文字状态
然后在layout中设置 selector
<Button
android:src="@drawable/imagebuttonselector"
/>
# ToggleButton Control
<
ToggleButton
android:id
="@+id/cctglBtn"
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:text ="Toggle Button"
android:textOn ="Stop"
android:textOff ="Run" />
因为toggle button有两种状态显示TEXT,所以android:text不是很必要,尽管toggle button从TextView中继承了这个属性。
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:text ="Toggle Button"
android:textOn ="Stop"
android:textOff ="Run" />
# Check Boxes
<
LinearLayout
xmlns:android
="http://schemas.android.com/apk/res/android"
android:orientation ="vertical" android:layout_width ="fill_parent"
android:layout_height ="fill_parent" >
< CheckBox android:id ="@+id/chickenCB" android:text ="Chicken" android:checked ="true"
android:layout_width =“wrap_content" android:layout_height ="wrap_content" />
< CheckBox android:id ="@+id/fishCB" android:text ="Fish"
android:layout_width ="wrap_content" android:layout_height ="wrap_content" />
< CheckBox android:id ="@+id/steakCB" android:text ="Steak" android:checked ="true"
android:layout_width ="wrap_content" android:layout_height ="wrap_content" />
</ LinearLayout >
Note:如果android:checked未设置,默认是false.
android:orientation ="vertical" android:layout_width ="fill_parent"
android:layout_height ="fill_parent" >
< CheckBox android:id ="@+id/chickenCB" android:text ="Chicken" android:checked ="true"
android:layout_width =“wrap_content" android:layout_height ="wrap_content" />
< CheckBox android:id ="@+id/fishCB" android:text ="Fish"
android:layout_width ="wrap_content" android:layout_height ="wrap_content" />
< CheckBox android:id ="@+id/steakCB" android:text ="Steak" android:checked ="true"
android:layout_width ="wrap_content" android:layout_height ="wrap_content" />
</ LinearLayout >
设置check状态函数: setChecked() or toggle(), 获取当前状态 isChecked();
public
class CheckBoxActivity
extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.checkbox);
CheckBox fishCB = (CheckBox)findViewById(R.id.fishCB);
if(fishCB.isChecked())
fishCB.toggle(); // flips the checkbox to unchecked if it was checked
fishCB.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
Log.v("CheckBoxActivity", "The fish checkbox is now "
+ (isChecked?"checked":"not checked"));
}});
}
}
除了用CompoundButton.onCheckedChangeListener()外,也可以用onClick()函数,当然在函数中要设置checked状态,或者用isCheck() method来检测。
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.checkbox);
CheckBox fishCB = (CheckBox)findViewById(R.id.fishCB);
if(fishCB.isChecked())
fishCB.toggle(); // flips the checkbox to unchecked if it was checked
fishCB.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
Log.v("CheckBoxActivity", "The fish checkbox is now "
+ (isChecked?"checked":"not checked"));
}});
}
}
如果在XML中加入了android:onClick="myClickerHandler", 可以像BUTTON一样统一设定一个处理click的函数:
public
void myClickHandler(View view) {
switch(view.getId()) {
case R.id.steakCheckBox:
Log.v("CheckBoxActivity", "The steak checkbox is now " +
(((CheckBox)view).isChecked()?"checked":"not checked"));
}
}
switch(view.getId()) {
case R.id.steakCheckBox:
Log.v("CheckBoxActivity", "The steak checkbox is now " +
(((CheckBox)view).isChecked()?"checked":"not checked"));
}
}
# Radio Button 单选按钮
<
LinearLayout
xmlns:android
="http://schemas.android.com/apk/res/android"
android:orientation
="vertical"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
>
< RadioGroup android:id ="@+id/rBtnGrp" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:orientation ="vertical" >
< RadioButton android:id ="@+id/chRBtn" android:text ="Chicken" android:layout_width ="wrap_content" android:layout_height ="wrap_content" />
< RadioButton android:id ="@+id/fishRBtn" android:text ="Fish" android:checked ="true" android:layout_width ="wrap_content" android:layout_height ="wrap_content" />
< RadioButton android:id ="@+id/stkRBtn" android:text ="Steak" android:layout_width ="wrap_content" android:layout_height ="wrap_content" />
</ RadioGroup >
</ LinearLayout >
除了android:checked外,也可以在代码中用setChecked()
< RadioGroup android:id ="@+id/rBtnGrp" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:orientation ="vertical" >
< RadioButton android:id ="@+id/chRBtn" android:text ="Chicken" android:layout_width ="wrap_content" android:layout_height ="wrap_content" />
< RadioButton android:id ="@+id/fishRBtn" android:text ="Fish" android:checked ="true" android:layout_width ="wrap_content" android:layout_height ="wrap_content" />
< RadioButton android:id ="@+id/stkRBtn" android:text ="Steak" android:layout_width ="wrap_content" android:layout_height ="wrap_content" />
</ RadioGroup >
</ LinearLayout >
RadioButton steakBtn = (RadioButton)
this.findViewById(R.id.stkRBtn);
steakBtn.setChecked( true);
Also use toggle() method to toggle checked or unchecked state.
steakBtn.setChecked( true);
一样可以使用onCheckedChangeListener(),但和前面不同,这里要使用RadioGroup.onCheckedChangeListener()
RadioGroup只能影响group内的RadioButton, group外的RadioButton和group内的非RadioButton都无法影响。
RadioGroup radGrp = (RadioGroup)findViewById(R.id.radGrp);
RadioButton newRadioBtn = new RadioButton( this);
newRadioBtn.setText("Pork");
radGrp.addView(newRadioBtn);
一旦用户checked某个RadioButton,就不能uncheck by click it again, 唯一清除这个group选择情况的方法就是通过编码形式调用clearCheck().
RadioButton newRadioBtn = new RadioButton( this);
newRadioBtn.setText("Pork");
radGrp.addView(newRadioBtn);
不用逐个检查RadioButton是否checked,可以直接调用getCheckedRadioButtonId();
RadioGroup radGrp = (RadioGroup)findViewById(R.id.radGrp);
int checkedRadioButtonId = radGrp.getCheckedRadioButtonId();
getCheckedRadioButton() returns -1 if nothing is checked.
int checkedRadioButtonId = radGrp.getCheckedRadioButtonId();
# ImageView
<ImageView android:id="@+id/image1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon" />
<ImageView android:id="@+id/image2"
android:layout_width="125dip"
android:layout_height="25dip"
android:src="#555555" />
<ImageView android:id="@+id/image3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView android:id="@+id/image4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/manatee02"
android:scaleType="centerInside"
android:maxWidth="35dip" android:maxHeight="50dip" />
ImageView imgView = (ImageView)findViewById(R.id.image3);
imgView.setImageResource( R.drawable.icon );
imgView.setImageBitmap(BitmapFactory.decodeResource(
this.getResources(), R.drawable.manatee14) );
imgView.setImageDrawable( Drawable.createFromPath("/mnt/sdcard/dave2.jpg") );
imgView.setImageURI(Uri.parse("file://mnt/sdcard/dave2.jpg"));
setImageURI只能取得本地图片,如果要通过http协议获得,最好的办法还是用BitmapFactory和InputStream.
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon" />
<ImageView android:id="@+id/image2"
android:layout_width="125dip"
android:layout_height="25dip"
android:src="#555555" />
<ImageView android:id="@+id/image3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView android:id="@+id/image4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/manatee02"
android:scaleType="centerInside"
android:maxWidth="35dip" android:maxHeight="50dip" />
ImageView imgView = (ImageView)findViewById(R.id.image3);
imgView.setImageResource( R.drawable.icon );
imgView.setImageBitmap(BitmapFactory.decodeResource(
this.getResources(), R.drawable.manatee14) );
imgView.setImageDrawable( Drawable.createFromPath("/mnt/sdcard/dave2.jpg") );
imgView.setImageURI(Uri.parse("file://mnt/sdcard/dave2.jpg"));
# Adapter
# SimpleCursorAdapter
SimpleCursorAdapter( Context context,
int childLayout, Cursor c, String[] from,
int[] to );
from 和 to 的数量必须相同。
Android不会为每一行数据建立adapter,而只会根据view可显示的数量,在以childLayout形式建立adapter,并且会比同屏可显示的多一些(类似缓冲,提高浏览速度)。
# ArrayAdapter
ArrayAdapter is simpler than SimpleCursorAdapter
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
new string[]{"Dave","Satya","Dylan"});
和SimpleCursorAdapter一样需要pass context(this), childLayout(android.R.layout.simple_list_item_1) pram.
android.R.layout.simple_list_item_1,
new string[]{"Dave","Satya","Dylan"});
不同的是只pass了一组array as the actual data,没有pass a cursor or a "to array".
当childLayout对象不是TextView时,可以传递资源ID和TextView资源ID来接收数据。如果没有现成的string array, 可以用createFromResource()函数。
<Spinner android:id="@+id/spinner"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( this,
R.array.planets, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/values/planets.xml -->
<resources>
<string-array name="planets">
<item>Mercury</item>
<item>Venus</item>
<item>Earth</item>
<item>Mars</item>
<item>Jupiter</item>
<item>Saturn</item>
<item>Uranus</item>
<item>Neptune</item>
</string-array>
</resources>
ArrayAdapter允许动态调整特定数据,add()函数可在array末尾添加新data, insert()插入,remove()删除指定.
android:layout_width="wrap_content" android:layout_height="wrap_content" />
Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( this,
R.array.planets, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/values/planets.xml -->
<resources>
<string-array name="planets">
<item>Mercury</item>
<item>Venus</item>
<item>Earth</item>
<item>Mars</item>
<item>Jupiter</item>
<item>Saturn</item>
<item>Uranus</item>
<item>Neptune</item>
</string-array>
</resources>
另外:sort()可以重新排序array,当然这样会失去data array和ListView之间的同步,因此还要call notifyDataSetChanged() 来resync the ListView with the adapter.
# Adapters that Android provides:
ArrayAdapter<T>
//
This is an adapter on top of a generic array of arbitrary objects. It's meant to be used with a ListView.
CursorAdapter // This adapter, also meant to be used in a ListView, provides data to the list via a cursor.
SimpleAdapter // As the name suggests, this adapter is a simple adapter. It is generally used to populate a list with static data(possibly from resources).
ResourceCursorAdapter // This adapter extends CursorAdapter and knows how to create views from resources.
SimpleCursorAdapter // This adapter extends ResourceCursorAdapter and creates TextView/ImageView view from the columns in the cursor. The views are defined in resources.
CursorAdapter // This adapter, also meant to be used in a ListView, provides data to the list via a cursor.
SimpleAdapter // As the name suggests, this adapter is a simple adapter. It is generally used to populate a list with static data(possibly from resources).
ResourceCursorAdapter // This adapter extends CursorAdapter and knows how to create views from resources.
SimpleCursorAdapter // This adapter extends ResourceCursorAdapter and creates TextView/ImageView view from the columns in the cursor. The views are defined in resources.
# Using Adapter with AdapterView
# ListView: set data by calling setListAdapter() method.
public
class ListViewActivity
extends ListActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Cursor c = managedQuery(Contacts.CONTENT_URI,
null, null, null, Contacts.DISPLAY_NAME + " ASC");
String[] cols = new String[] {Contacts.DISPLAY_NAME};
int[] views = new int[] {android.R.id.text1};
SimpleCursorAdapter adapter = new SimpleCursorAdapter( this,
android.R.layout.simple_list_item_1,
c, cols, views);
this.setListAdapter(adapter);
}
}
Note: ListActivity包含了一个ListView,因此只要用this.setListAdapter(),也没有设置setContentView().
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Cursor c = managedQuery(Contacts.CONTENT_URI,
null, null, null, Contacts.DISPLAY_NAME + " ASC");
String[] cols = new String[] {Contacts.DISPLAY_NAME};
int[] views = new int[] {android.R.id.text1};
SimpleCursorAdapter adapter = new SimpleCursorAdapter( this,
android.R.layout.simple_list_item_1,
c, cols, views);
this.setListAdapter(adapter);
}
}
# Creating Custom Adapters
<?xml version="1.0" encoding="utf-8"?>
<!-- This file is at /res/layout/gridviewcustom.xml -->
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:verticalSpacing="10dip"
android:horizontalSpacing="10dip"
android:numColumns="auto_fit"
android:gravity="center"
/>
public class GridViewCustomAdapter extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.gridviewcustom);
GridView gv = (GridView)findViewById(R.id.gridview);
ManateeAdapter adapter = new ManateeAdapter( this);
gv.setAdapter(adapter);
}
public static class ManateeAdapter extends BaseAdapter {
private static final String TAG = "ManateeAdapter";
private static int convertViewCounter = 0;
private Context mContext;
private LayoutInflater mInflater;
static class ViewHolder {
ImageView image;
}
private int[] manatees = {
R.drawable.manatee00, R.drawable.manatee01,
R.drawable.manatee03, R.drawable.manatee04,
R.drawable.manatee06, R.drawable.manatee07,
R.drawable.manatee09, R.drawable.manatee10,
R.drawable.manatee12, R.drawable.manatee13,
R.drawable.manatee15, R.drawable.manatee16,
R.drawable.manatee18, R.drawable.manatee19,
R.drawable.manatee21, R.drawable.manatee22,
R.drawable.manatee24, R.drawable.manatee25,
R.drawable.manatee27, R.drawable.manatee28,
R.drawable.manatee30, R.drawable.manatee31,
R.drawable.manatee33
};
private Bitmap[] manateeImages = new Bitmap[manatees.length];
private Bitmap[] manateeThumbs = new Bitmap[manatees.length];
public ManateeAdapter(Context context) {
Log.v(TAG, "Constructing ManateeAdapter");
this.mContext = context;
mInflater = LayoutInflater.from(context);
for( int i=0; i<manatees.length; i++) {
manateeImages[i] = BitmapFactory.decodeResource(
context.getResources(), manatees[i]);
manateeThumbs[i] = Bitmap.createScaledBitmap(manateeImages[i],
100, 100, false);
}
}
@Override
public int getCount() {
Log.v(TAG, "in getCount()");
return manatees.length;
}
public int getViewTypeCount() {
Log.v(TAG, "in getViewTypeCount()");
return 1;
}
public int getItemViewType( int position) {
Log.v(TAG, "in getItemViewType() for position " + position);
return 0;
}
@Override
public View getView( int position, View convertView, ViewGroup parent) {
ViewHolder holder;
Log.v(TAG, "in getView for position " + position +", convertView is " + ((convertView == null)?"null":"being recycled"));
if (convertView == null) {
convertView = mInflater.inflate(R.layout.gridimage, null);
convertViewCounter++;
Log.v(TAG, convertViewCounter + " convertViews have been created");
holder = new ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.gridImageView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.image.setImageBitmap( manateeThumbs[position] );
return convertView;
}
@Override
public Object getItem( int position) {
Log.v(TAG, "in getItem() for position " + position);
return manateeImages[position];
}
@Override
public long getItemId( int position) {
Log.v(TAG, "in getItemId() for position " + position);
return position;
}
}
}
<!-- This file is at /res/layout/gridviewcustom.xml -->
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:verticalSpacing="10dip"
android:horizontalSpacing="10dip"
android:numColumns="auto_fit"
android:gravity="center"
/>
public class GridViewCustomAdapter extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.gridviewcustom);
GridView gv = (GridView)findViewById(R.id.gridview);
ManateeAdapter adapter = new ManateeAdapter( this);
gv.setAdapter(adapter);
}
public static class ManateeAdapter extends BaseAdapter {
private static final String TAG = "ManateeAdapter";
private static int convertViewCounter = 0;
private Context mContext;
private LayoutInflater mInflater;
static class ViewHolder {
ImageView image;
}
private int[] manatees = {
R.drawable.manatee00, R.drawable.manatee01,
R.drawable.manatee03, R.drawable.manatee04,
R.drawable.manatee06, R.drawable.manatee07,
R.drawable.manatee09, R.drawable.manatee10,
R.drawable.manatee12, R.drawable.manatee13,
R.drawable.manatee15, R.drawable.manatee16,
R.drawable.manatee18, R.drawable.manatee19,
R.drawable.manatee21, R.drawable.manatee22,
R.drawable.manatee24, R.drawable.manatee25,
R.drawable.manatee27, R.drawable.manatee28,
R.drawable.manatee30, R.drawable.manatee31,
R.drawable.manatee33
};
private Bitmap[] manateeImages = new Bitmap[manatees.length];
private Bitmap[] manateeThumbs = new Bitmap[manatees.length];
public ManateeAdapter(Context context) {
Log.v(TAG, "Constructing ManateeAdapter");
this.mContext = context;
mInflater = LayoutInflater.from(context);
for( int i=0; i<manatees.length; i++) {
manateeImages[i] = BitmapFactory.decodeResource(
context.getResources(), manatees[i]);
manateeThumbs[i] = Bitmap.createScaledBitmap(manateeImages[i],
100, 100, false);
}
}
@Override
public int getCount() {
Log.v(TAG, "in getCount()");
return manatees.length;
}
public int getViewTypeCount() {
Log.v(TAG, "in getViewTypeCount()");
return 1;
}
public int getItemViewType( int position) {
Log.v(TAG, "in getItemViewType() for position " + position);
return 0;
}
@Override
public View getView( int position, View convertView, ViewGroup parent) {
ViewHolder holder;
Log.v(TAG, "in getView for position " + position +", convertView is " + ((convertView == null)?"null":"being recycled"));
if (convertView == null) {
convertView = mInflater.inflate(R.layout.gridimage, null);
convertViewCounter++;
Log.v(TAG, convertViewCounter + " convertViews have been created");
holder = new ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.gridImageView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.image.setImageBitmap( manateeThumbs[position] );
return convertView;
}
@Override
public Object getItem( int position) {
Log.v(TAG, "in getItem() for position " + position);
return manateeImages[position];
}
@Override
public long getItemId( int position) {
Log.v(TAG, "in getItemId() for position " + position);
return position;
}
}
}