第5回 二弟呀,面子工程很重要

1.1.1.卷轴视图ScrollView

受到手机屏幕大小的限制,有时候要显示的内容在一个屏幕上显示不完。我们希望可以通过滑动屏幕的方式显示更多的内容。这个时候,我们就需要用到卷轴视图ScrollView了,下面我们来通过一个实例看一下如何使用ScrollView。在5.2.1的工程里新增加一个类,命名为ScrollViewActivity,内容如下:

ScrollViewActivity.java代码清单5-23:

/**

 * ScrollView展示类

 *

 * @author孔明

 */

publicclass ScrollViewActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// 设置标题

setTitle("ScrollViewActivity");

// 指定布局文件

setContentView(R.layout.scroll_view);

}

}

这个类的代码非常简单,只是做了一个简单的设置布局文件的操作,让我们看一下布局文件,如下所示:

scroll_view.xml代码清单5-23:

<?xml version=“1.0” encoding=“utf-8”?>

<ScrollViewxmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<LinearLayout

android:layout_width="fill_parent"

android:layout_height="wrap_content">

<TextView

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:ems="6"

android:text="@string/long_text"/>

</LinearLayout>

</ScrollView>

布局文件里,根结点就是一个ScrollView,里面定义了一个线性布局,线性布局里面又包含了一个TextView,这些都很好理解,这里需要注意的是ScrollView里面只能有一个直接的子结点,也就是说上面的布局文件中,如果再增加任何一个与LinearLayout平级的子结点就是错误的。

我们在string.xml定义了一个很长的字符串,命名为long_text,内容是“原始人工作室”的不断重复,因为这是六个字,我们设置ems的值为6(含义是TextView每一行的宽度为6个字符)。因此,运行程序后我们应该能看到每一行的内容都是“原始人工作室”,并且重复很多行。往上拖动屏幕,可以发现会有更多的行出现。实际的运行截图如5-35所示,与我们所期待的一模一样:

图5-35 ScrollView组件示意图

在本例中,我们在ScrollView里面只包含了一个TextView,在实际的应用中,我们在LinearLayout中可以包含许许多多的控件。

孔明:ScrollView实现的效果和PC机上的上下滑动网页的效果是一样的!额……好吧,这是一句没什么用的废话……

 

 


1.1.2.列表ListView

列表ListView可能是Android里面最常用的一个控件了。ListView实现简单但是能完成许多复杂的界面,下面我们从三个小例子中来学习ListView。在工程里面新建一个类ListViewActivity,在该类里面我们定义了三个按钮分别将我们的程序导向三个小例子,每一个例子使用不同的适配器Adapter来实现的,代码如下:

ListViewActivity.java代码清单5-24:

/**

 * ListView示例类

 * @author孔明

 */

publicclass ListViewActivity extends Activity {

// 定义三个引导按钮,分别对应我们要讲到的三种情况

// 使用ArrayAdapter适配的ListView

private Button mArrayBtn;

// 使用SimpleCursorAdapter适配的ListView

private Button mSimpleCursorBtn;

// 使用SimpleAdapter适配自定义ListView

private Button mSimpleBtn;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//设置标题

setTitle("ListViewActivity");

//指定布局文件

setContentView(R.layout.list_view);

// 通过id来加载按钮,并设置监听器

mArrayBtn = (Button) findViewById(R.id.array_list_btn);

mArrayBtn.setOnClickListener(mArrayBtnListener);

mSimpleCursorBtn = (Button) findViewById(R.id.simplecursor_list_btn);

mSimpleCursorBtn.setOnClickListener(mSimpleCursorBtnListener);

mSimpleBtn = (Button) findViewById(R.id.simple_list_btn);

mSimpleBtn.setOnClickListener(mSimpleBtnListener);

}

// mArrayBtn的监听器

private Button.OnClickListener mArrayBtnListener = new Button.OnClickListener() {

public void onClick(View v) {

//启动ArrayListViewActivity

Intent intent = newIntent();

intent.setClass(ListViewActivity.this, ArrayListViewActivity.class);

startActivity(intent);

}

};

// mSimpleCursorBtn的监听器

private Button.OnClickListener mSimpleCursorBtnListener = new Button.OnClickListener()

{

public void onClick(View v) {

//启动SimpleCursorListActivity

Intent intent = newIntent();

intent.setClass(ListViewActivity.this, SimpleCursorListActivity.class);

startActivity(intent);

}

};

// mSimpleBtn的监听器

private Button.OnClickListener mSimpleBtnListener = new Button.OnClickListener() {

public void onClick(View v) {

//启动SimpleListActivity

Intent intent = newIntent();

intent.setClass(ListViewActivity.this, SimpleListActivity.class);

startActivity(intent);

}

};

}

运行后,截图如5-36所示:

图5-36 ListView组件示意图

我们先来看第一个按钮导向的ArrayListViewActivity。在下面的例子中,我们使用了ArrayAdapter,并讲解了ListView的几个重要的监听器如何使用。ArrayListViewActivity的具体代码如下:

ArrayListViewActivity.java代码清单5-25:

/**

 * 使用ArrayAdapter进行适配的ListView示例

 * @author孔明

 */

publicclass ArrayListViewActivity extends Activity {

// 定义一个ListView作为成员变量

private ListView mListView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// 新建一個ListView

mListView = newListView(this);

// 设置ListView的适配器为ArrayAdapter

// 其中simple_expandable_list_item_1为Android自带的布局

mListView.setAdapter(new ArrayAdapter<String>(this,

                                                     android.R.layout.simple_expandable_list_item_1,getData()));

// 设置点击动作的监听器

mListView.setOnItemClickListener(mItemClickListener);

// 设置长按动作的监听器

mListView.setOnItemLongClickListener(mItemLongClickListener);

// 设置选择动作监听器

mListView.setOnItemSelectedListener(mItemSelectedListener);

// 设置长按菜单动作的监听器

mListView.setOnCreateContextMenuListener(mCreateContextMenuListener);

// 设置布局为ListView

setContentView(mListView);

}

// 私有函数,填充数据

private List<String> getData() {

List<String> data = new ArrayList<String>();

// 通过调用getString方法得到定义在string.xml文件中的字符串

data.add(getString(R.string.words));

data.add(getString(R.string.drawing));

data.add(getString(R.string.legend));

data.add(getString(R.string.fighter));

return data;

}

// 实现点击动作的监听器

private OnItemClickListener mItemClickListener = new OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent, View view, int position,

                                                     long id) {

TextView tv = (TextView)view;

// 设置一下标题,作为点击动作

setTitle("点击了" + tv.getText());

}

};

// 实现长按菜单动作的监听器

private OnCreateContextMenuListener mCreateContextMenuListener = new

OnCreateContextMenuListener() {

@Override

public void onCreateContextMenu(ContextMenu menu, View v,

                                                     ContextMenuInfomenuInfo) {

// 设置菜单的标题

menu.setHeaderTitle("长按菜单");

// 增加两个菜单

menu.add(0, 0, 0, "我喜欢!");

menu.add(0, 1, 0, "我超级喜欢!");

}

};

// 实现长按动作的监听器

private OnItemLongClickListener mItemLongClickListener = new

OnItemLongClickListener() {

@Override

public boolean onItemLongClick(AdapterView<?> parent, View view,

                                                     int position, long id) {

TextView tv = (TextView)view;

// 设置一下标题,作为点击动作

setTitle("长按了" + tv.getText());

// 返回false表示该长按事件没有被消耗掉

returnfalse;

}

};

// 实现选择动作的监听器

private OnItemSelectedListener mItemSelectedListener = new OnItemSelectedListener() {

@Override

public void onItemSelected(AdapterView<?> parent, View view,

                                                     int position, long id) {

TextView tv = (TextView)view;

// 显示一个Toast作为选择时的动作

Toast.makeText(ArrayListViewActivity.this,

"选择了" + tv.getText(), Toast.LENGTH_SHORT).show();

}

@Override

public void onNothingSelected(AdapterView<?> parent) {

          

}

};

@Override

public boolean onContextItemSelected(MenuItem item) {

// 设置一下标题,作为菜单被点击的结果

if(item.getItemId() == 0){

setTitle("你喜欢!");

} else {

setTitle("你超级喜欢!");

}

returnsuper.onContextItemSelected(item);

}

}

在onCreate()方法里面新建了一个ListView并保存到我们定义的成员变量里面,并为这个ListView设置了一个ArrayAdapter,数据来自于getData()方法,而布局使用的是Android自带的布局,并为ListView设置了四个监听器,分别是点击监听器,选择监听器,长按监听器和长按菜单监听器。

孔明:你们注意到了吗?在长按监听器的最后一定要返回false表示长按事件没有被消耗掉,如果返回true的话就会导致后面的长按菜单监听器没有反应。

 

 

 


运行我们的程序,首先我们会看到如下5-37的界面:

图5-37 使用ArrayAdapter适配的ListView组件示意图

 

当我们转动鼠标滚轮选中其中一个的时候,就会触发选择事件,会提示现在选择的是哪一个,如图5-38所示。

图5-38 ListView组件选择事件示意图

同样当我们点击其中一个的时候,也会提示点击的是哪一个,截图5-39所示,标题发生了变为“点击了刀疤鸭传说”。

图5-39 ListView组件点击事件示意图

当我们长按其中的一个的时候,会出现如图5-40中所示界面:

图5-40 ListView组件长按事件示意图

可以看到标题栏上已经显示了当前长按的是哪一个,并且出现了一个菜单,当我们选择其中一个子菜单的时候,出现如图5-41中所示界面:

图5-41 ListView组件子菜单点击事件示意图

标题栏上显示出来了我们选择的子菜单项。当然ListView的监听器还有许多其他的,以上列出的四个是最重要也是最常用的,其他的用法与此类似。在之前的例子当中,我们也提到过ArrayAdapter,这是一类非常简单的数组适配器,而SimpleCursorAdapter是数据库适配器。我们来看下SimpleCursorAdapter到底该如何使用。在下面的例子中,我们读取手机的通讯录的数据库,将名字显示到我们程序的ListView里面,为了能够访问通讯录,我们必须在AndroidMenifest.xml文件里加入相应的权限:

<uses-permissionandroid:name="android.permission.READ_CONTACTS"></uses-permission>

为了便于测试,我们在模拟器的手机通讯录里面新建两个通讯条目,如下图5-42中所示:

图5-42 创建的通讯录

SimpleCursorListActivity类的代码如代码清单5-26所示:

SimpleCursorListActivity.java代码清单5-26:

/**

 * SimpleCursorAdapter适配的ListView

 *

 * @author 关云长

 *

 */

public class SimpleCursorListActivity extends Activity {

       // 定义一个ListView作为成员变量

       private ListView mListView;

       @Override

       protected void onCreate(BundlesavedInstanceState) {

              super.onCreate(savedInstanceState);

              // 新建一个ListView

              mListView = newListView(this);

              // 新建一个与联系人相关联的游标

              Cursor cursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI,null, null, null, null);

              // 将游标的管理权交给Activity

              startManagingCursor(cursor);

              // 新建一个SimpleCursorAdapter

              ListAdapter listAdapter= new SimpleCursorAdapter(

this,android.R.layout.simple_expandable_list_item_1,

                cursor, new String[]{

ContactsContract.Contacts.DISPLAY_NAME},new int[]{android.R.id.text1});

              // 设置ListView的Adapter

              mListView.setAdapter(listAdapter);

              // 设置布局

              setContentView(mListView);

       }

}

代码中,我们新建了一个ListView和游标,并使得游标与联系人相关联,将游标的管理权交给Activity,新建一个SimpleCursorAdapter,并将这个SimpleCursorAdapter设置为ListView的SimpleCursorAdapter,设置Activity的布局为ListView。

运行程序之后,我们程序显示如图5-43所示:

图5-43 使用SimpleCursorAdapter适配的ListView示意图

还有最后一种类型的适配器,SimpleAdapter,这类的适配器能够发挥最大的灵活性,适合用来做自定义的ListView,下面我们来看下如何实现:

SimpleListActivity.java代码清单5-27:

/**

 * 利用SimpleAdapter实现自定义的Listview

 * @author孔明

 */

publicclass SimpleListActivity extends Activity {

// 定义一个ListView作为成员变量

private ListView mListView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// 新建一个ListView

mListView = newListView(this);

// 新建一个SimpleAdapter

SimpleAdapter adapter = new SimpleAdapter(this,getData(),

                                                     R.layout.single_list, new String[] { "title", "info","img" },

                                                     newint[] { R.id.title, R.id.info, R.id.img});

// 设置ListView的适配器

mListView.setAdapter(adapter);

// 设置布局

setContentView(mListView);

}

// 返回填充数据

private List<Map<String, Object>> getData() {

List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();

// 第一行的内容

Map<String, Object> map = new HashMap<String, Object>();

// 标题

map.put("title", getString(R.string.words));

// 信息

map.put("info", "背单词很轻松很快乐!");

// 图标

map.put("img", R.drawable.words_logo);

// 加到List里面去

list.add(map);

// 第二行的内容

map = newHashMap<String, Object>();

map.put("title", getString(R.string.legend));

map.put("info", "真的很好玩哦亲!");

map.put("img", R.drawable.legend_logo);

list.add(map);

// 第三行的内容

map = newHashMap<String, Object>();

map.put("title", getString(R.string.drawing));

map.put("info", "发挥你的绘画才艺吧!");

map.put("img", R.drawable.drawing_logo);

list.add(map);

return list;

}

}

我们为每一个ListView当中的一个子项定义了一个ImageView和两个TextView,在程序里面,我们用到了map为ListView的每一个子项来定义View,运行程序,截图如5-44所示:

图5-44 使用SimpleAdapter适配的ListView示意图

我们可以看到正如我们所布局的那样,每一个ListView的子项都有三个View在里面。

1.1.3.标签切换TabView

TabView用于标签之间的切换,下面我们来看一下如何实现这一功能,新增加一个类,命名为TabDemoActivity,代码如下:

TabDemoActivity.java代码清单5-28:

/**

 * Tab展示类

 * @author孔明

 */

publicclass TabDemoActivity extends TabActivity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// 设置标题

 setTitle("TabDemoActivity");

// 返回一个用于放置标签的host

TabHost tabHost = getTabHost();

// 将布局文件定义的界面映射到TabHost里面

LayoutInflater.from(this).inflate(R.layout.tab_demo,

tabHost.getTabContentView(), true);

// 分别设置三个tab的布局

tabHost.addTab(

tabHost.newTabSpec("tab1").setIndicator("tab1").setContent(R.id.view1));

tabHost.addTab(

tabHost.newTabSpec("tab2").setIndicator("tab2").setContent(R.id.view2));

tabHost.addTab(

tabHost.newTabSpec("tab3").setIndicator("tab3").setContent(R.id.view3));

}

}

代码里面,将布局文件映射到TabHost上,TabHost是Tab的容器。然后为TabHost增加了三个Tab,该类对应的布局文件tab_demo.xml为:

tab_demo.xml代码清单5-28:

<?xml version=“1.0” encoding=“utf-8”?>

<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<TextViewandroid:id="@+id/view1"

android:background="@drawable/blue"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:text="这里是Tab1里的内容。"/>

<TextViewandroid:id="@+id/view2"

android:background="@drawable/red"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:text="这里是Tab2的内容"/>

<TextViewandroid:id="@+id/view3"

android:background="@drawable/green"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:text="这里是Tab3的内容"/>

</FrameLayout>

这里,我们使用了FrameLayout。运行程序,截图如5-45所示:

图5-45 TabView组件示意图

点击不同的Tab可以显示不同的Tab。Tab可以做的更复杂一些,为每一个Tab定义不同的布局,为Tab增加图标等。

孔明:现在有越来越多的应用开始是用TabView组件了,因为TabView组件极大的提高了界面的容量。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值