android:id="@+id/icon"android:layout_width="wrap_content"android:layout_height="fil" />
当前位置:文档之家› Android listview 专题

Android listview 专题

Android listview 专题
Android listview 专题

Android ListView专题之一多层树完美实现

.xml:

代码

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

android:id="@+id/icon"

android:layout_width="wrap_content"

android:layout_height="fill_parent"

android:layout_alignParentBottom="true"

android:layout_alignParentTop="true"

android:layout_marginRight="6.0dip"/>

android:id="@+id/text"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_alignParentBottom="true"

android:layout_alignParentTop="true"

android:layout_toRightOf="@id/icon"

android:gravity="center_vertical"

android:singleLine="true"

android:textAppearance="?android:textAppearanceMedium"

android:textColor="#ffffff"/>

TreeElement.java:

private String id;

private String outlineTitle;

privateboolean mhasParent;

privateboolean mhasChild;

private TreeElement parent;

privateint level;

private ArrayListchildList = new ArrayList();

public String getId() {

return id;

}

publicvoid setId(String id) {

this.id = id;

}

public String getOutlineTitle() {

return outlineTitle;

}

publicvoid setOutlineTitle(String outlineTitle) {

this.outlineTitle = outlineTitle;

}

publicboolean isMhasParent() {

return mhasParent;

}

publicvoid setMhasParent(boolean mhasParent) { this.mhasParent = mhasParent;

}

publicboolean isMhasChild() {

return mhasChild;

}

publicvoid setMhasChild(boolean mhasChild) { this.mhasChild = mhasChild;

}

publicint getLevel() {

return level;

}

publicvoid setLevel(int level) {

this.level = level;

}

publicboolean isExpanded() {

return expanded;

}

publicvoid setExpanded(boolean expanded) { this.expanded = expanded;

}

public TreeElement getParent() {

return parent;

}

publicvoid setParent(TreeElement parent) { this.parent = parent;

}

// private OutlineElement outlineElement; privateboolean expanded;

c.parent = this;

c.level = this.level + 1;

}

public TreeElement(String id, String title) {

super();

this.id = id;

this.outlineTitle = title;

this.level = 0;

this.mhasParent = true;

this.mhasChild = false;

this.parent = null;

}

public TreeElement(String id, String outlineTitle, boolean mhasParent,

boolean mhasChild, TreeElement parent, int level, boolean expanded) { super();

this.id = id;

this.outlineTitle = outlineTitle;

this.mhasParent = mhasParent;

this.mhasChild = mhasChild;

this.parent = parent;

if (parent != null) {

this.parent.getChildList().add(this);

}

this.level = level;

this.expanded = expanded;

}

}

TreeView.java:

@Override

publicvoid onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

initialData();

treeViewAdapter = new TreeViewAdapter(this, https://www.doczj.com/doc/8613520488.html,yout.main,

mPdfOutlinesCount);

setListAdapter(treeViewAdapter);

registerForContextMenu(getListView());

}

mPdfOutlinesCount.add(element1);

mPdfOutlinesCount.add(element2);

mPdfOutlinesCount.add(element9);

element2.addChild(element3);

element1.addChild(element4);

element1.addChild(element5);

element1.addChild(element6);

element1.addChild(element7);

element7.addChild(element8);

element9.addChild(element10);

element9.addChild(element11);

element11.addChild(element12);

element11.addChild(element13);

element10.addChild(element14);

element10.addChild(element15);

element10.addChild(element16);

element10.addChild(element17);

element10.addChild(element18);

element10.addChild(element19); }

publicint getCount() {

return mfilelist.size();

}

public Object getItem(int position) {

return position;

}

publiclong getItemId(int position) {

return position;

}

@Override

publicvoid onClick(View v) {

Log.i("TreeView", "obj.id:" + obj.getId());

}

});

holder.icon.getPaddingTop(), 0,

holder.icon.getPaddingBottom());

holder.text.setText(obj.getOutlineTitle());

if (obj.isMhasChild() && (obj.isExpanded() == false)) {

holder.icon.setImageBitmap(mIconCollapse);

} elseif (obj.isMhasChild() && (obj.isExpanded() == true)) {

holder.icon.setImageBitmap(mIconExpand);

} elseif (!obj.isMhasChild()) {

holder.icon.setImageBitmap(mIconCollapse);

holder.icon.setVisibility(View.INVISIBLE);

}

return convertView;

}

class ViewHolder {

TextView text;

ImageView icon;

}

}

@Override

protectedvoid onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id);

Log.i("TreeView", "position:" + position);

if (!mPdfOutlinesCount.get(position).isMhasChild()) {

Toast.makeText(this, mPdfOutlinesCount.get(position)

.getOutlineTitle(), 2000);

return;

}

if (mPdfOutlinesCount.get(position).isExpanded()) {

mPdfOutlinesCount.get(position).setExpanded(false);

TreeElement element = mPdfOutlinesCount.get(position);

ArrayList temp = new ArrayList();

for (int i = position + 1; i

if (element.getLevel() >= mPdfOutlinesCount.get(i).getLevel()) { break;

}

temp.add(mPdfOutlinesCount.get(i));

}

mPdfOutlinesCount.removeAll(temp);

treeViewAdapter.notifyDataSetChanged();

} else {

TreeElement obj = mPdfOutlinesCount.get(position);

obj.setExpanded(true);

int level = obj.getLevel();

int nextLevel = level + 1;

for (TreeElement element : obj.getChildList()) {

element.setLevel(nextLevel);

element.setExpanded(false);

mPdfOutlinesCount.add(position + 1, element);

}

treeViewAdapter.notifyDataSetChanged();

// setListAdapter(fileExploreAdapter);

}

}

}

在res/xml文件夹下面新建attrs.xml

Java代码

name="title"

format="string"/>

name="titleTextSize"

format="dimension"/>

name="titleTextColor"

format="color"/>

name="leftTextColor"

format="color"/>

name="leftBackground"

format="string"/>

name="leftText"

format="string"/>

name="rightTextColor"

format="color"/>

name="rightBackground"

format="string"/>

name="rightText"

format="string"/>

布局文件:

Java代码

xmlns:custom="https://www.doczj.com/doc/8613520488.html,/apk/res/com.android.custom"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical">

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#ff00ff00"/>

android:id="@+id/topBar"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:background="#0000ff"

custom:leftBackground="@drawable/icon"

custom:leftText="左侧"

custom:leftTextColor="#123123"

custom:rightBackground="@drawable/icon"

custom:rightText="右侧"

custom:rightTextColor="#ff0000"

custom:title="自定义标题"

custom:titleTextColor="#ff0000"

custom:titleTextSize="14.0sp">

Android ListView专题之二滚动卡的问题

写了个类似下面的GridView,滚动的时候有卡或者跳格的现象,尤其当记录比较多的时候。

ListView替换GridView,问题依旧。

实现的示例大致是这个样子:

测试数据有600条左右。不过,即使减到40条左右,也是会卡的。在ddms log中监控dalvik日志,会有大量下面的信

息:

01-14 10:37:47.579: DEBUG/dalvikvm(13626): GC_EXTERNAL_ALLOC freed 58 objects / 2072 bytes in 37ms

基本上每滚动一次,就会出10多条。这是造成卡的主要原因。也就是说,要释放大量的临时对象。这些临时对象还不是我自己创建的对象,我把结果集合已经一次性加载到内存中了。也不是图片显示造成的,我把图片去掉现象一样。

另外,也考虑了比如扩大堆内存的方法,但是不对症下药,因为并不是内存达到堆的上限造成full gc。有关堆的日志可以过滤dalvikvm-heap看到。如果堆内存full gc会有类似这样的日志:

dalvikvm-heap(11651): Heap Massage needed (768000-byte external allocation too big)

dalvikvm-heap(11651): Full GC (don’t collect SoftRe ferences)

可以初步判断,是GridView/ListView为实现滚屏产生的瞬态使用对象,随着滚动而被快速丢弃了,需要垃圾回收,造成性能问题。

可是,为什么Android自带的通讯录却不卡呢?我的手机上的通讯录也有将近300条的记录。通过ddms日志观察,没有频繁的GC_EXTERNAL_ALLOC日志,从头滚动到尾只出现了1-2次。

于是决定查看通讯录的源代码。这几行:

@Override

public View getView(int position, View convertView, ViewGroup parent) {

……

View v;

if (convertView == null || convertView.getTag() == null) {

newView = true;

v = new View(mContext, cursor, parent);

} else {

newView = false;

v = convertView;

}

说明了对ListView元素视图的复用。再查api:

convertView The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view.

因此,可以认为,convertView是元素的缓存,因为元素本身没有变化,因此可以判断如果非空,就可以复用。比如我示例中是这样写的:

if (convertView == null) {

convertView=activity.getLayoutInflater().inflate(

https://www.doczj.com/doc/8613520488.html,yout.album_grid_element, parent, false);

之前是每次直接创建新的view的,没有考虑复用convertView。这是造成卡的根本原因。

这次的另外的一个教训是,解决问题没有从api层面层层深入解决问题,即这样的次序:api是否能解决?是否需要通过自己的优化解决?是否需要系统的部署方面的配置比如堆的调整来解决等。

结果是走了弯路,消耗了时间。

以后还是要先通读api文档。这次出问题,是建立在以前随手写的简单示例基础上的。

Android ListView专题之三快速滚动示例增加首字母提示

(2011-11-04 11:56:13)

在自定义ListView FastScroller滑块图片中实现了快速滚动。在原有示例基础上增加了这样的功能:

本文和上面示例借鉴了:https://www.doczj.com/doc/8613520488.html,/sodino/archive/2010/12/15/6077017.aspx做的比较简单。需要为ListView注册一个滚动监听器:

listView.setOnScrollListener(new OnScrollListener() {

boolean visible;

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

visible = true;

if (scrollState == ListView.OnScrollListener.SCROLL_STA TE_IDLE) {

overlay.setVisibility(View.INVISIBLE);

}

}

@Override

public void onScroll(AbsListView view, int firstVisibleItem,

int visibleItemCount, int totalItemCount) {

if (visible) {

overlay.setText(items[firstVisibleItem].substring(0, 1));

overlay.setVisibility(View.VISIBLE);

}

}

});

当然,还需要提示信息的布局文件:

android:background="#99000088"

android:gravity="center"

android:maxWidth="80dp"

android:minWidth="80dp"

android:padding="10dp"

android:textColor="#ffffffff"

android:textSize="70sp"

android:visibility="invisible"/>

理论上,可以做出很花哨的提示界面。

在Activity的onCreate方法中加入这个界面:

this.overlay = (TextView) View.inflate(this, https://www.doczj.com/doc/8613520488.html,yout.overlay, null);

getWindowManager()

.addView(

overlay,

new https://www.doczj.com/doc/8613520488.html,youtParams(

LayoutParams.WRAP_CONTENT,

LayoutParams.WRAP_CONTENT,

https://www.doczj.com/doc/8613520488.html,youtParams.TYPE_APPLICATION,

https://www.doczj.com/doc/8613520488.html,youtParams.FLAG_NOT_FOCUSABLE

| https://www.doczj.com/doc/8613520488.html,youtParams.FLAG_NOT_TOUCHABLE,

PixelFormat.TRANSLUCENT));

这里要注意:

listView.setOnScrollListener(new OnScrollListener() {

boolean visible;

监听器代码中增加了一个visible标志位。用于判断是否滚动状态变化过。否则,启动Activity后,无论提示界面是否invisible,都会显示,因为会调用onScroll方法。

源代码见:

https://www.doczj.com/doc/8613520488.html,/svn/tags/ListViewCustomerFastScroller-0.2/

Android ListView专题之四自定义对话框以及列表形式的切换

从界面变化来看,主要是增加了自定义对话框,以及列表形式的切换。看截图:

长按后还是显示checkbox。点击view按钮,将出现对话框:

如果touch对话框以外的区域,对话框将消失,这就比较类似ios里的popover了。

view mode下的radio按钮,可以切换列表形式,比如从缩略图(默认的模式)转换到列表模式下。

说一下如何实现自定义对话框。大致步骤有:

编写类,继承Dialog

覆盖超类的onTouchEvent方法。基本思路是在该方法中,判断一下touch的坐标是在对话框包含的视图坐标里还是外,如果是外,就hide(或者也可dismess)对话框对象。

代码如下:

class MyDialog extends Dialog {

public MyDialog(Context context) {

super(context);

}

public MyDialog(Context context, boolean cancelable,

OnCancelListener cancelListener) {

super(context, cancelable, cancelListener);

}

public MyDialog(Context context, int theme) {

super(context, theme);

}

@Override

public boolean onT ouchEvent(MotionEvent event) {

Rect rect = new Rect();

View view = findViewById(R.id.dialogLayout);// 取对话框最外层视图

view.getWindowVisibleDisplayFrame(rect);// 得到window的矩形

// 因为对话框居中,因此对话框相对于window的坐标可通过对话框长和宽以及window矩形计算出来

Rect rect2 = new Rect((rect.right – view.getRight()) / 2,

+ (rect.right – view.getRight()) / 2,

view.getBottom() + (rect.bottom – view.getBottom()));

if (!rect2.contains((int) event.getRawX(), (int) event.getRawY())) {

this.dismiss();

return true;

}

return super.onTouchEvent(event);

}

}

切换表的表现形式,说起来很简单,其实就是为ListView设置不同的adapter即可。即:ListView.setAdapter()方法。每次设置不同的adapter实例,就会即可改变列表的表现形式。

在本例中,因为有数据的变化等因素,代码比在原有ListView示例上做的改进要复杂很多。

另外,本例使用sqlite数据库替代了大部分原来用数组和列表模拟的数据集合。见com.easymorse.list.datasource包下的三个类,是一个标准的dao实现。dao的代码,主要实现了crud。代码:

public class RecordDao {

@SuppressWarnings("unused")

private static final String TAG = "listview";

// 由于模拟图片数据

private static final int[] drawables = { R.drawable.a1, R.drawable.a2,

R.drawable.a3, R.drawable.a4, R.drawable.a5, R.drawable.a6,

R.drawable.a7, R.drawable.a8, R.drawable.a9, R.drawable.a10,

R.drawable.a12, R.drawable.a13 };

// 图片的缓存,使用SoftReference是为了防止oom

private static Map> drawableCache = new HashMap>();

private Context context;

private SQLiteDatabase database;

public RecordDao(Context context) {

this.context = context;

init();

}

public Drawable getDrawable(Long id) {

// 如果缓存中有,使用缓存的

if (drawableCache.get(id) != null

&& drawableCache.get(id).get() != null) {

return drawableCache.get(id).get();

}

// 未在缓存中,可能是没加入缓存,也可能是垃圾回收,则重新获取,并加载缓存中

if (id >= 1 && id <= drawables.length) {

Drawable drawable = context.getResources().getDrawable(

drawables[id.intValue() - 1]);

drawableCache.put(id, new SoftReference(drawable));

return drawable;

return null;

}

private void init() {

this.database = context.openOrCreateDatabase("mydata",

Context.MODE_PRIVATE, null);

//TODO 正式使用时,取消下面初始化代码,改为使用SQLiteOpenHelper dropTables();

createTables();

for (int i = 0; i < 12; i++) {

create(new Record(null, "柴可夫司机"));

}

}

public void create(Record record) {

SQLiteStatement statement = database

.compileStatement("insert into mydata (name) values(?)");

statement.bindString(1, record.getName());

statement.execute();

statement.close();

//需要设置record的id,否则没有唯一标识,无法和数据库交互

Cursor cursor = database.rawQuery(

"select last_insert_rowid() from mydata", new String[] {});

if (cursor.moveT oFirst()) {

record.setId(cursor.getLong(0));

}

cursor.close();

}

public void browse(Page page) {

page.setResults(new ArrayList());

Cursor cursor = database.rawQuery("select count(*) from mydata ", new String[] {});

if (cursor.moveT oFirst()) {

page.setCount(cursor.getInt(0));

}

cursor.close();

if (page.getCount() > page.getSize() * (page.getNo() – 1)) {

cursor = database.rawQuery(

"select id,name from mydata limit " + page.getSize()

* (page.getNo() – 1) + " , " + page.getSize(),

new String[] {});//使用limit子句

while (cursor.moveToNext()) {

Record record = new Record(cursor.getLong(0),

cursor.getString(1));

page.getResults().add(record);

}

cursor.close();

}

public void delete(Long id) {

SQLiteStatement statement = database

.compileStatement("delete from mydata where id=?");

statement.bindLong(1, id);

statement.execute();

statement.close();

}

public Record get(Long id) {

Record record = null;

Cursor cursor = database.rawQuery("select name from mydata where id="

+ id, new String[] {});

if (cursor.moveT oFirst()) {

record = new Record();

record.setName(cursor.getString(0));

record.setId(id);

}

cursor.close();

return record;

}

private void dropTables() {

database.execSQL("drop table if exists mydata");

}

private void createTables() {

database.execSQL("create table if not exists mydata("

+ " id integer primary key autoincrement," + " name text" + ")");

}

}

另外,这里做了个简单的缓存Drawable对象,使用SoftReference,软引用,这样当虚拟机内存够用的时候保持在内存中。当内存不足才清除。

源代码见:

https://www.doczj.com/doc/8613520488.html,/svn/tags/ListViewDemo-0.8/

续:

对话框的使用小结

曾经在ListView自定义对话框以及列表形式的切换中写过处理对话框退出的方式,touch对话框以外的区域退出对话框。刚才查Dialog javadoc的时候,发现其实可以这样:

dialog.setCanceledOnTouchOutside(true);

效果是一样的。而且,应该更好。因为我自定义的实现,只能在对话框居中的时候才有效。官方的方法应该可以处理对话框偏移的情况,不过我没有时间测试了。如果想做出不带标题栏的对话框,比如这样的对话框:

只需:

dialog.requestWindowFeature(Window.FEA TURE_NO_TITLE); Android ListView专题之五实现类似Gallery的功能利用ListView,实现类似Android Gallery的功能。效果类似这样:

长按列表中元素:

勾选列表中元素,点击“选择”按钮:

点击删除按钮,则删掉所选元素:

再次长按屏幕中元素,按钮和多选框消失。另外,按系统回退按钮也可使按钮和多选框消失。如果没有多选框和按钮的时候,回退按钮将执行系统操作,退出应用。

实现这部分代码有几个难点:

长按界面中元素,所有元素都显示CheckBox,当然可以遍历所有元素(视图)并设置相应的CheckBox为visible,这样逻辑会比较乱,本例中使用了java提供的对观察者模式的支持类

删除其中某几个元素,应该保持在当前位置,其他相邻元素填补删除的空缺

下面说说难点的实现方法。先说观察者模式。实际上是引入了第三个对象,可观察对象,你可以把它看作中间人,所有元素都在这个中间人对象上注册了监听器,当其中一个被长按后,通知所有元素设置checkbox。

可以通过:

https://www.doczj.com/doc/8613520488.html,/Code/Java/Design-Pattern/AsimpledemoofObservableandObserver.htm

中的示例了解观察者模式以及java Observer的使用方法。

在本例中,通过内部类实现了Observable接口:

class MyObservable extends Observable {

public void toobarStatusChanged(boolean visible) {

setChanged();

notifyObservers(visible);

}

}

这里实现了Observer的继承类,并为每个元素创建示例注册到Observable中:

// 创建观察者,用于监控是否有Checkbox可见性事件,然后加入到可观察对象中

Observer observer = new Observer() {

@Override

public void update(Observable observable, Object data) {

checkBox.setVisibility((Boolean) data ? View.VISIBLE

: View.INVISIBLE);

checkBox.setChecked(checkedIds.contains(index));

};

observable.addObserver(observer);

另外,实现了一个Observer实例用于监控长按事件的变化,来生成或者取消工具条按钮。

这个实现目前可以工作,但是可能还有问题,造成大量的Observer对象的存在,因为每次创建ListView的Row都会重新创建,等有时间再解决。

如何做到删除其中几个元素,后面相邻元素自动补位,而且屏幕保持在当前位置。我的做法基本思路是,取到当前屏幕显示的各行,在Nexusone的分辨率下可取到3行,然后获取各行的ViewGroup对象,清空它的子视图,然后再根据数据源(本文是一个List)重新填充行的内容。

如何得到当前在屏幕的行的ViewGroup呢?其实并不复杂:

myListView.getChildCount()

可得到屏幕上能看到几行。

再通过遍历:

myListView.getChildAt(i)

就可以得到各行的ViewGroup。ListView的实现原理是,只保存当前可见的几行视图。并保存在ViewGroup的childView 数组中,上述的两个方法getChildCount和getChildAt实际上是ViewGroup的,ListView并未覆盖。

完整的代码类似这样:

for (int i = 0; i < myListView.getChildCount(); i++) {

ViewGroup viewgroup = (ViewGroup) myListView.getChildAt(i);

viewgroup.removeAllViews();

generateRowElements(

myListView.getPositionForView(viewgroup), viewgroup);

}

完整源代码包含了详细的注释:

package com.easymorse.list;

import java.util.ArrayList;

import java.util.Collections;

import java.util.HashSet;

import java.util.List;

import java.util.Observable;

import java.util.Observer;

import java.util.Set;

import android.app.Activity;

import android.os.Bundle;

import android.view.KeyEvent;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.View.OnKeyListener;

import android.view.View.OnLongClickListener;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.Button;

import android.widget.CheckBox;

import https://www.doczj.com/doc/8613520488.html,poundButton;

import https://www.doczj.com/doc/8613520488.html,poundButton.OnCheckedChangeListener;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.Toast;

public class ListViewDemoActivity extends Activity {

class MyObservable extends Observable {

public void toobarStatusChanged(boolean visible) {

setChanged();

notifyObservers(visible);

}

}

// 每行显示几个图片

private static final int ROW_ELEMENTS_SIZE = 5;

// 本例中的ListView

private ListView myListView;

// checkbox是否可见的标志位

private boolean checkItemVisible;

private ViewGroup toolbar;

// 存放选中的checkbox条目的图片列表下标

private Set checkedIds = new HashSet(); // 创建观察对象

private MyObservable observable = new MyObservable();

// 演示用的图片数据集合

@SuppressWarnings("serial")

private List drawables = new ArrayList() { {

add(R.drawable.defense_mechanism);

add(R.drawable.gzorah);

add(R.drawable.jay_z_linkin_park);

add(R.drawable.korn);

add(R.drawable.defense_mechanism);

add(R.drawable.gzorah);

add(R.drawable.jay_z_linkin_park);

add(R.drawable.korn);

add(R.drawable.defense_mechanism);

add(R.drawable.gzorah);

add(R.drawable.jay_z_linkin_park);

add(R.drawable.korn);

add(R.drawable.defense_mechanism);

add(R.drawable.gzorah);

add(R.drawable.jay_z_linkin_park);

add(R.drawable.korn);

add(R.drawable.defense_mechanism);

add(R.drawable.gzorah);

Android简单的登陆界面的设计开发

通信实训报告 -Android移动平台开发 学院:信息工程学院 班级: 学号: 姓名:

实训内容: 一.1.Andriod的简介 Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。目前,最新版本为Android 2.4 Gingerbread 和Android 3.0 Honeycomb。 Android是基于Linux开放性内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。 Android早期由原名为"Android"的公司开发,谷歌在2005年收购"Android.Inc"后,继续对Android系统开发运营,它采用了软件堆层(software stack,又名软件叠层)的架构,主要分为三部分。底层Linux内核只提供基本功能,其他的应用软件则由各公司自行开发,部分程序以Java编写。2011年初数据显示,仅正式上市两年的操作系统Android已经超越称霸十年的塞班系统,使之跃居全球最受欢迎的智能手机平台。现在,Android系统不但应用于智能手机,也在平板电脑市场急速扩张,在智能MP4方面也有较大发展。采用Android系统主要厂商包括台湾的HTC,(第一台谷歌的手机G1由HTC生产代工)美国摩托罗拉,SE等,中国大陆厂商如:魅族(M9),华为、中兴、联想、蓝魔等。 2.Android构架图 二.1软件下载 Android SDK,网址是https://www.doczj.com/doc/8613520488.html,. JDK的下载地址https://www.doczj.com/doc/8613520488.html,/javase/downloads/widget/jdk6.jsp。Eclipse的下载网址是https://www.doczj.com/doc/8613520488.html,/downloads/ 2.Android开发环境搭建

第4章 Android用户界面设计

视图组件的使用模式 常用组件 高级组件 提示框与警告对话框

就是Android应用程序的开发过程。一般过程是先通过XML布局文件或Java代码创建界面布局,设定组件显示样式,随后获取UI组件对象,并处理组件事件响应。 视图组件的定义 资源的访问 生成视图组件资源标识 视图组件的引用 视图组件的事件响应 组件的常用属性

1.1视图组件的定义 使用XML布局文件定义视图组件 使用Java代码定义视图组件(不推荐)

1.1视图组件的定义 使用XML布局文件定义视图组件 Android平台为大多数视图组件以及其子类提供了XML标记,可通过XML布局文件中的标记来定义视图组件。XML中的每个元素代表了一个组件,即元素名称对应相应的Java类。

1.1视图组件的定义

相关文档 最新文档