使用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); } }