使用Android的GridView与BaseAdapter能够轻易完成网格式图片浏览器。下面用一个例子还说明,同时说明安卓是如何访问图片资源。其实所谓的图片资源,就是你拷贝到安卓工程的图片。相当于你把几张图片放到网页的站点文件夹,之后用<img>标签引用就这么简单。
如下图,在安卓工程中有8张我自己拷贝进去的图片,与自带的ic_launcher.png,共9张图片。
下面完成一个网格式图片浏览器,一开始先读取这9张图片,点击任何一张查看大图,可以按右上角的菜单返回,也可以按返回键返回。
一、图片资源的整合
1、这个与你做网页一样,先把你要在app读取的图片拷贝到安卓工程目录的res\drawable-xx文件夹,任意一个都可以的,这里以drawable-hdpi为例子。
唯一要注意的一点是,拷贝的时候,你的图片只使用小写字母、数字、下划线、点作为文件名,否则安卓工程无法把你的图片注册到R文件。会在控制台报以下的错误:
如果成功拷贝之后,你可以打开gen\你的工程包名\R.java,可以发现ADT已经帮你把这些图片资源注册到安卓工程之中了。之后的安卓编程则可以像使用app图片一样,使用这些图片资源了。
二、网格式图片浏览器的编写
1、首先是对res\values\strings.xml的修改。修改好,程序名、菜单选项,与ViewActivity查看大图的Activity中对图片描述,没有这个图片描述,ADT会出现警告。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">网格式图片查看器</string>
<string name="menu_exit">退出</string>
<string name="imageView_description">大图</string>
</resources>
2、先对MainActivity查询多张图片着手,对MainActivity的布局文件res\layout\activity_main.xml修改如下。就摆一个带id网格视图GridView,指定每行显示两个图片。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false" >
<GridView
android:id="@+id/gridView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2" >
</GridView>
</LinearLayout>
3、再于MainActivity.java完成网格视图的布置。网格视图GridView要配合适配器BaseAdapter才能达到效果。
package com.imageviewer;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.app.Activity;
import android.content.Intent;
public class MainActivity extends Activity {
private GridView gridView1;
private int[] imageId = new int[] { R.drawable.img1, R.drawable.img2,
R.drawable.img3, R.drawable.img4, R.drawable.img5, R.drawable.img6,
R.drawable.img7, R.drawable.img8, R.drawable.ic_launcher };//把要显示的图片放到一个图片id数组里面便于操作
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView1 = (GridView) findViewById(R.id.gridView1);//获取组件
//编写一个适配器,完成网格视图的布置。
BaseAdapter baseAdapter = new BaseAdapter() {
@Override
public View getView(int position, View convertView, ViewGroup arg2) {
ImageView imageView1;
if (convertView == null) {
imageView1 = new ImageView(MainActivity.this);
imageView1.setAdjustViewBounds(true);//自动缩放为宽高比
imageView1.setScaleType(ScaleType.CENTER_INSIDE);//设置图片保持宽高比显示
imageView1.setPadding(5, 5, 5, 5);
} else {
imageView1 = (ImageView) convertView;
}
imageView1.setImageResource(imageId[position]);//设置要显示的图片,这里自动对imageId这个数组进行变量
return imageView1;
}
//获取当前选项
@Override
public long getItemId(int position) {
return position;
}
@Override
public Object getItem(int position) {
return position;
}
//获取数量
@Override
public int getCount() {
return imageId.length;
}
};
gridView1.setAdapter(baseAdapter);//把适配器与网格视图链接起来
gridView1.setOnItemClickListener(new OnItemClickListener() {//点击网格组件的任意一张图片时候的事件
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,//position为点击的id
long arg3) {
Intent intent=new Intent(MainActivity.this,ViewActivity.class);//激活ViewActivity
Bundle bundle=new Bundle();
bundle.putInt("imgId", imageId[position]);//传递点击的图片的id到ViewActivity
intent.putExtras(bundle);
startActivity(intent);
}
});
}
}
4、之后是新建一个查看大图的ViewActivity.java,如何在一个app中多个Activity共存并相互传递数值在《【Android】多个Activity之间利用bundle传递数值》(
点击打开链接)中已经说过了,这里不再赘述。先在src中新建一个继承android.app.Activity的类ViewActivity.java,然后在AndroidManifest.xml中注册ViewActivity,具体把AndroidManifest.xml修改如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.imageviewer"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.imageviewer.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.imageviewer.ViewActivity"
android:label="@string/app_name" > <!-- 注册ViewActivity -->
</activity>
</application>
</manifest>
5、之后在res\layout新建viewactivity.xml作为ViewActivity的布局文件,也是非常简单,就放一个带ID的ImageView图片视图,其中图片描述android:contentDescription只是为了消除警告而存在。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/imageView_description"
/>
</LinearLayout>
6、同时完成对查看大图的ViewActivity中菜单的修改,对res\menu\main.xml修改如下,这个菜单本来是MainActivity的自带菜单来的,由于MainActivity不使用菜单,何不直接拿给ViewActivity用呢?被浪费,app的菜单在《【Android】日期拾取器、时间拾取器与菜单》(
点击打开链接)说过了,这里不再赘述。
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menu_exit"
android:title="@string/menu_exit"/>
</menu>
7、最后对ViewActivity.java进行编写,则完成整个工程。其中ViewActivity.java涉及三部分的功能,一个是把MainActivity存过来的图片资源的id拿到,进行读取,一个是对菜单的监听,一个是对返回键的监听,这个也在《【Android】各式各样的弹出框与对菜单键、返回键的监听》(
点击打开链接)中说过了,这里不再赘述。
package com.imageviewer;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
public class ViewActivity extends Activity {
private ImageView imageView1;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewactivity);
imageView1 = (ImageView) findViewById(R.id.imageView1);
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
int imgId = bundle.getInt("imgId");
imageView1.setImageResource(imgId);//读取相应的图片,放到图片视图imageView1
}
// 创建menu的方法,没有该方法,不会在右上角设置菜单。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// 设置menu界面为res\menu\menu.xml
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
// 处理菜单事件
public boolean onOptionsItemSelected(MenuItem item) {
// 得到当前选中的MenuItem的ID,
int item_id = item.getItemId();
switch (item_id) {
// 设置id为menu_exit的菜单子项所要执行的方法。
case R.id.menu_exit:
finish();// 关闭这个Activity。
break;
}
return true;
}
// 对物理按钮的监听
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
finish();// 关闭这个Activity。
break;
}
return super.onKeyDown(keyCode, event);
}
}