您的位置:首页 > 移动开发 > Android开发

Android 中如何才能让 StackView 的 OnItemSelectedListener 侦听器响应选中事件

2015-02-27 17:11 393 查看
  StackView 组件能以堆叠方式显示一组图片,其滑动手指查看图片的操作方便而且直观。我们在切图的时候或许还希望更新一些文字描述等相关信息,这时你会发现 StackView 已经提供了一个 setOnItemSelectedListener() 方法,可以设置 OnItemSelectedListener() 侦听器以便在图片切换后执行后续工作。不过先别高兴得太早,测试时你会发现 OnItemSelectedListener() 懒洋洋的什么都没做。

  度娘了一下,有关 StackView 组件的文章极少(莫非少有人用?),只看到有说法是 Android 并没为 StackView 组件提供 OnItemSelectedListener() 的实现,解决方案却没有找到;或者只是建议设置另一监听器 setOnItemClickListener(),而该监听器只有在点击时才会响应——难道要我告诉用户,你滑动手指切换图片后,还得傻傻地再点击一次,所看到的才是相应的文本信息?

  翻墙,Google 帮忙在国外网站中找到了一个解决方案:通过扩展 StackView 并“激活”其 OnItemSelectedListener 侦听器即可。不过在实测中,当图片在最后一张和第一张之间循环切换时,应用会异常退出。跟踪发现重载方法 setDisplayedChild(int whichChild) 中接收到的 whichChild 本身应该是表示图片组中各图片序号的(相当于数组下标值),而该值在增长到最后一张图片时并不会停下来归零,而是继续增长,这样导致传给 onItemSelected 的参数出现了“越界”的错误,最终导致应用崩溃。查到原因后对症下药,问题自然解决。以下是扩展
StackView 的源码,在项目中创建该类后直接使用即可——

StackViewAdv.java

package com.yunbing.ui;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.StackView;
public class StackViewAdv extends StackView
{
public StackViewAdv(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public StackViewAdv(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
}
@Override
public void setDisplayedChild(int whichChild)
{
Log.d("test", "传入的 whichChild = " + whichChild);
// 当图片组由最后一张循环切换到第一张时,所获取的 whichChild 将发生越界(这里变为5);
// 当图片组由第一张倒循环切换到最后一张时,whichChild==-1,同样发生越界,因此做如下处理
int index = whichChild;
int countImg = 5;   //图片的总数,实际项目时暂时可考虑用全局变量
if (index < 0) index = countImg-1; // 由第一张倒循环切换到最后一张时,whichChild==-1
index = index % countImg;  //循环序号

// “激活” OnItemSelectedListener 侦听器
this.getOnItemSelectedListener().onItemSelected(this, null, index, -1);
super.setDisplayedChild(whichChild);
}
}


以下是项目应用示例——

布局文件:main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.yunbing.ui.StackViewAdv
android:id="@+id/mStackView"
android:layout_width="wrap_content"
android:layout_height="400dp"
android:layout_centerInParent="true"
android:loopViews="true" />

<TextView
android:id="@+id/tv_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
android:layout_alignParentBottom="true"/>

</RelativeLayout>


程序源文件:StackViewTest.java

package com.yunbing.ui;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.SimpleAdapter;
import android.widget.TextView;
/**
* Description:
* <br/>site: <a href="http://www.yunbing.com">云冰工作室</a>
* <br/>Copyright (C), 2015, Yunbing
* <br/>This program is protected by copyright Yunbing.
* <br/>Program Name: 自定义StackView
* <br/>Date: 2015-02-11
* @author  Yunbing jbl@yunbing.com
* @version  1.0
*/
public class StackViewTest extends Activity
{
StackViewAdv stackView;
TextView tvAbout;

int[] imageIds = new int[]
{
R.drawable.img01, R.drawable.img02, R.drawable.img03
, R.drawable.img04, R.drawable.img05};

//图片组的相应文本
String[] strAbouts = {"1. 人造卫星正在展开太阳帆", "2. 行星撞击地球的美丽瞬间",
"3. 壮观的九大行星", "4. 木星和他的小伙伴", "5. 太阳系的演变-yunbing.com"};

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

stackView = (StackViewAdv) findViewById(R.id.mStackView);
tvAbout = (TextView) findViewById(R.id.tv_text);
// 创建一个List对象,List对象的元素是Map
List<Map<String, Object>> listItems =
new ArrayList<Map<String, Object>>();
for (int i = 0; i < imageIds.length; i++)
{
Map<String, Object> listItem = new HashMap<String, Object>();
listItem.put("image", imageIds[i]);
listItems.add(listItem);
}

// 创建一个SimpleAdapter
SimpleAdapter simpleAdapter = new SimpleAdapter(this,
listItems
// 使用/layout/cell.xml文件作为界面布局
, R.layout.cell, new String[] { "image" },
new int[] { R.id.image1 });
stackView.setAdapter(simpleAdapter);
//图片切换时更新文本内容
stackView.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// 设置文本
tvAbout.setText(strAbouts[arg2]);
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub

}
});

stackView.setSelection(0);
}

}


本文的示例源码下载地址:

http://download.csdn.net/detail/midong2000/8459751
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐