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

  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


	
	
	
	
	

程序源文件: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:
 * 
site: 云冰工作室 *
Copyright (C), 2015, Yunbing *
This program is protected by copyright Yunbing. *
Program Name: 自定义StackView *
Date: 2015-02-11 * @author Yunbing [email protected] * @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> listItems = new ArrayList>(); for (int i = 0; i < imageIds.length; i++) { Map listItem = new HashMap(); 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


你可能感兴趣的:(Java,Android,StackView)