Android基础笔记整理:基本控件(下)—7.10 拖拉图片(画廊视图):Gallery

目录

一、Gallery组件简单介绍

Gallery类的继承结构如下:

Gallery类提供的常用方法

Gallery的实现

方式一:继承BaseAdapter类实现

方式二:直接使用SimpleAdapter类实现

二、案例代码实现

(1)自定义适配器类的方式实现

表7-21 BaseAdapter类的常用方法

【例7-61】定义一个表示Gallery图片的适配器类 ImageGalleryAdapter

提示:ImageGalleryAdapter也可以使用List集合保存数据。

【例7-62】在main.xml文件中定义组件

【例7-63】编写Activity程序,显示选中图片的信息

(2)使用 SimpleAdapter 类方式实现

提示:关于反射机制

【例7-64】定义显示模板 grid_layout.xml

【例7-65】定义 Activity 程序,显示 Gallery

提示:开发中采用SimpleAdapter类完成

(3)Gallery和 ImageSwitcher两个组件联合使用

【例7-66】在main.xml文件中定义组件

【例7-67】定义Activity程序,进行图片显示


一、Gallery组件简单介绍

使用过Android手机的用户应该知道,在Android中可以使用一些软件方便地进行图片的拖拽浏览,这样的功能可以通过Gallery组件实现。使用 Gallery组件可以定义一组图片浏览框,如图7-37所示, 可以降低开发者对于图片浏览功能的开发难度

 

Gallery类的继承结构如下:

 

Gallery类提供的常用方法

如表7-20所示。

 

Gallery的实现

在使用Gallery设置图片集时需要使用setAdapter()方法,此时设置的是SpinnerAdapter接口的对象,

主要的功能::定义一组要显示的组件的适配器,而对于这种适配器操作有两种可选方式。

方式继承BaseAdapter类实现

用一个自定义的类直接继承SpinnerAdapter接口的子类 android.widget.BaseAdapter类实现,这样用户只需要覆写核心操作方法即可,不需要的方法可以不覆写。

方式二:直接使用SimpleAdapter类实现

下面分别演示如何采用这两种方式完成操作。

 

二、案例代码实现

(1)自定义适配器类的方式实现

如果要采用自定义适配器类的方式完成,可以直接覆写BaseAdapter类中的几个方法,如表7-21所示

 

7-21 BaseAdapter类的常用方法

 

【例7-61】定义一个表示Gallery图片的适配器类 ImageGalleryAdapter

package org.lxh.demo;

import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;

/**
 * 定义一个表示Gallery图片的适配器类:ImageGalleryAdapter
 * @author luminal
 */
public class ImageGalleryAdapter extends BaseAdapter {
	
	private Context myContext; // Context对象
	private int imgRes[] = new int[] { R.drawable.ispic_a, R.drawable.ispic_b,
			R.drawable.ispic_c, R.drawable.ispic_d, R.drawable.ispic_e };

	public ImageGalleryAdapter(Context c) { // 接收Context
		this.myContext = c;
	}

	@Override
	public int getCount() { // 返回图片个数
		return this.imgRes.length;
	}

	@Override
	public Object getItem(int position) { // 取得指定位置的图片
		return this.imgRes[position];
	}

	@Override
	public long getItemId(int position) { // 取得指定位置的图片
		return this.imgRes[position];
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		
		ImageView img = new ImageView(this.myContext);
		
		img.setBackgroundColor(Color.BLACK);//背景颜色-黑色
		img.setImageResource(this.imgRes[position]); // 给ImageView设置资源
		img.setScaleType(ImageView.ScaleType.CENTER); // 居中显示
		img.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT)); // 布局参数
		return img;
		
	}

}

本程序首先将需要显示的5张图片分别保存在drawable-*文件夹中,然后将所有图片资源的

ID通过imgRes数组进行保存,再实现BaseAdapter类中所需要的相关方法即可。

 

提示:ImageGalleryAdapter也可以使用List集合保存数据。

ImageGalleryAdapter类中,所有的资源是通过imgRes数组保存的

如果用户觉得数组用不方便,也可以将其替换成List集合.

下面直接通过Gallery定义一个图片浏览操作,在选中某张图片之后,通过android.widget.Toast显示选中图片的资源编号。

 

【例7-62】main.xml文件中定义组件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/MyLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <!-- 
    android:gravity="center_vertical"水平居中摆放组件
    android:spacing="3px"显示的间距为3像素
     -->
    <Gallery
        android:id="@+id/myGallery"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:spacing="3px" />

</LinearLayout>

本程序只在布局管理器中定义了一个普通的Gallery组件,而且设置了组件中各个图片项的间距为3像素(3px)

 

【例7-63】编写Activity程序,显示选中图片的信息

package org.lxh.demo;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Gallery;
import android.widget.Toast;

/**
 * 编写Activity程序,显示选中图片的信息
 * @author luminal
 */
public class MyGalleryDemo extends Activity {
	
	private Gallery gallery = null; // 声明Gallery组件

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.main);// 调用布局文件
		
		this.gallery = (Gallery) super.findViewById(R.id.myGallery);// 取得组件
		this.gallery.setAdapter(new ImageGalleryAdapter(this));// 设置图片集
		this.gallery.setOnItemClickListener(new OnItemClickListenerImpl());// 设置单击事件
		//this.gallery.setSelection(2);// 设置以第三项为中心
		
	}

	
	private class OnItemClickListenerImpl implements OnItemClickListener {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			Toast.makeText(MyGalleryDemo.this, "" + position,
					Toast.LENGTH_SHORT).show();// 显示图片编号

		}
	}
	
	
}

本程序中首先通过findViewByld()方法取得了Gallery组件的对象,之后使用 setAdapter()方法将定义的Image图片数组进行转换,当用户选择了某张图片时,会通过Toast类将对应的图片编号进行短暂的显示程序的运行效果如图7-38所示。

 

(2)使用 SimpleAdapter 类方式实现

釆用方式一操作,可以通过自定义适配器类的方式显示图片,除此之外,也可以直接釆用SimpleAdapter类的方式完成,通过自定义显示模板的方式显示所有的图片资源,但是考虑到有些用户有可能随时修改资源文件,所以本程序将采用反射机制加载所有的资源ID

 

提示:关于反射机制

本程序将使用java.lang.reflect.Field类动态地取出所有保存的图片资源,此部分内容可以参考《名师讲坛——Java开发实战经典》第15章的内容。

 

【例7-64】定义显示模板 grid_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal" 
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:background="#FFFFFF">
	
    <!-- 
    android:scaleType="center" 居中对齐
     -->
	<ImageView
		android:id="@+id/img"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:scaleType="center"/>
	
</LinearLayout>

程序直接采用了线性布局管理器,其中只定义了一个ImageView组件,而且所有的布局参数和组件参数与之前所编写的ImageGalleryAdapter类中的getView()方法返回的组件是一样 的,

即本程序将直接通过此配置文件替换掉 ImageGalleryAdapter类中的getView方法。

 

7-65】定义 Activity 程序,显示 Gallery

package org.lxh.demo;

import java.lang.reflect.Field;
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.OnItemClickListener;
import android.widget.Gallery;
import android.widget.SimpleAdapter;
import android.widget.Toast;

/**
 * 定义 Activity 程序,显示 Gallery
 * 釆用SimpleAdapter类的方式完成,
 * 通过自定义显示模板的方式显示所有的图片资源
 * @author luminal
 */
public class MyGalleryDemo extends Activity {
	
	private Gallery gallery = null;// 声明Gallery组件
	private List<Map<String, Integer>> list = new ArrayList<Map<String, Integer>>();
	private SimpleAdapter simpleAdapter = null;// 适配器

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.main);// 调用布局文件
		
		this.initAdapter();// 初始化适配器
		
		this.gallery = (Gallery) super.findViewById(R.id.myGallery);// 取得组件
		this.gallery.setAdapter(this.simpleAdapter);// 设置图片集
		this.gallery.setOnItemClickListener(new OnItemClickListenerImpl());// 设置单击事件
		
	}

	private class OnItemClickListenerImpl implements OnItemClickListener {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			
			Toast.makeText(MyGalleryDemo.this, "" + position,
					Toast.LENGTH_SHORT).show(); // 显示图片编号
			
		}
	}

	/**
	 * 初始化适配器
	 */
	public void initAdapter() {
		
		//获取drawable目录下所有图片
		Field[] fields = R.drawable.class.getDeclaredFields();
		
		for (int x = 0; x < fields.length; x++) {
			if (fields[x].getName().startsWith("ispic_")) { // 所有ispic_*命名的图片
				
				Map<String, Integer> map = new HashMap<String, Integer>(); // 定义Map
				try {
					map.put("img", fields[x].getInt(R.drawable.class));// 设置图片资源
				}catch (Exception e) { 
					e.printStackTrace();
				}
				this.list.add(map); // 保存Map,到 List集合里面
			}
		}
		
		// 实例化SimpleAdapter
		this.simpleAdapter = new SimpleAdapter(this, 
				this.list,// 要包装的数据集合
				R.layout.grid_layout,// 要使用的显示模板
				new String[] { "img" },// 定义要显示的 Map 的 Key
				new int[] { R.id.img });// 与模板中的组件匹配
	}
	
	
}

程序中采用了 SimpleAdapter类完成了适配器的操作,而后定义了个 initAdapter()方法,通过反射取得了所有资源中的图片信息,之后将所有以“ispic_*”命名的图片保存到了 List集合中, 再通过此集合为 SimpleAdapter类实例化,并显示所有的图片,程序的运行效果与图7-38 一致。

 

提示:开发中采用SimpleAdapter类完成

通过比校,读者应该清楚了自定义适配器类与SimpleAdapter类的使用区别及联系,而在开发中为了方便,大部分程序都会采用SimpleAdapter类的方式完成,这样可以很好地实现“代码和配置”相分离,而且与MVC设计模式的要求相吻合,而对于MVC设计模式不 清楚的读者,可以参考《名师讲坛——Java Web开发实战经典》一书。

对于自定义适配器类的操作形式一般在用户需要手工处理列表项的情况下发生,而且对于之前讲解的ListView组件,也可以采用自定义适配器的操作形式完成,这些都将在后面讲解。

以上只是完成了一个最简单的图片列表的功能,当用户选择某张图片之后,会利用Toast 组件显示用户选择图片的编号。

 

(3)GalleryImageSwitcher两个组件联合使用

下面再开发一个更实用的组件,当用户从图片浏览框中选择了张图片之后,可以在屏幕上将这张图片完整地显示出来,而此功能就可以将GalleryImageSwitcher两个组件联合起来使用

 

【例7-66】main.xml文件中定义组件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/MyLayout"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:gravity="bottom">
	<ImageSwitcher
		android:id="@+id/myImageSwitcher"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"/>
	<Gallery
		android:id="@+id/myGallery"
		android:gravity="center_vertical"
		android:spacing="3px"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"/>
		<!-- 
		android:spacing="3px" 各个列表项之间的间距 
		-->
</LinearLayout>

在本布局管理器中定义了ImageSwitcher和一个Gallery组件,当通过Gallery选择一张图片时,可以在ImageSwitcher中显示相关的图片。

 

【例7-67】定义Activity程序,进行图片显示

package org.lxh.demo;

import java.lang.reflect.Field;
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.OnItemClickListener;
import android.widget.Gallery;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;
import android.widget.SimpleAdapter;
import android.widget.ViewSwitcher.ViewFactory;

/**
 * 定义Activity程序,进行图片显示
 * @author luminal
 */
public class MyGalleryDemo extends Activity {
	
	private Gallery gallery = null; // 声明 Gallery组件
	private List<Map<String, Integer>> list = new ArrayList<Map<String, Integer>>();
	private SimpleAdapter simpleAdapter = null; // 适配器
	private ImageSwitcher myImageSwitcher = null; // 图片切换
	

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.main); // 调用布局文件
		
		this.initAdapter(); // 初始化适配器
		this.gallery = (Gallery) super.findViewById(R.id.myGallery); // 取得组件
		this.myImageSwitcher = (ImageSwitcher) super
				.findViewById(R.id.myImageSwitcher); // 取得组件

		this.myImageSwitcher.setFactory(new ViewFactoryImpl()); // 设置图片工厂
		
		this.gallery.setAdapter(this.simpleAdapter); // 设置图片集
		this.gallery.setOnItemClickListener(new OnItemClickListenerImpl());// 设置单击事件
	}

	
	private class OnItemClickListenerImpl implements OnItemClickListener {
		@SuppressWarnings("unchecked")
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			
			Map<String, Integer> map = (Map<String, Integer>) MyGalleryDemo.this.simpleAdapter
					.getItem(position); // 取出Map
			MyGalleryDemo.this.myImageSwitcher.setImageResource(map.get("img")); // 设置显示图片
			
		}
	}

	
	/**
	 * 初始化适配器
	 */
	public void initAdapter() { 
		Field[] fields = R.drawable.class.getDeclaredFields();
		for (int x = 0; x < fields.length; x++) {
			if (fields[x].getName().startsWith("ispic_")) { // 所有ispic_*命名的图片
				Map<String, Integer> map = new HashMap<String, Integer>(); // 定义Map
				try {
					map.put("img", fields[x].getInt(R.drawable.class));
				} catch (Exception e) { // 设置图片资源
				}
				this.list.add(map); // 保存Map
			}
		}
		this.simpleAdapter = new SimpleAdapter(this, // 实例化SimpleAdapter
				this.list, // 要包装的数据集合
				R.layout.grid_layout, // 要使用的显示模板
				new String[] { "img" }, // 定义要显示的Map的Key
				new int[] { R.id.img }); // 与模板中的组件匹配
	}
	
	/**
	 * 定义视图工厂类
	 */
	private class ViewFactoryImpl implements ViewFactory { 
		@Override
		public View makeView() {
			ImageView img = new ImageView(MyGalleryDemo.this); // 实例化图片显示
			img.setBackgroundColor(0xFFFFFFFF); // 设置背景颜色
			img.setScaleType(ImageView.ScaleType.CENTER); // 居中显示
			img.setLayoutParams(new ImageSwitcher.LayoutParams( // 自适应图片大小
					LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));// 定义组件
			return img;
		}
	}

}

本程序在之前的代码基础上增加了 ImageSwitcher组件,当选择相关的图片之后会触发单击事件,而在此事件处理中,会首先根据用户选择图片的位置(position)SimpleAdapter类中取得相关的配置项(Map),并取得对应的资源ID,之后使用setlmageResource()方法将选择的图片在 ImageSwitcher组件中进行显示。程序的运行效果如图7-39所示。

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

被开发耽误的大厨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值