文章目錄
  1. 1. 範例的程式碼和註解

之前看書看一看021 ImageSwicher 和 GridView 介面元件覺得講得有點含糊,Adapter 是什麼都沒解釋就繼承來寫 ImageAdapter,
然後就跑去看了 Android Developers 的 LayoutGridView,筆記在這邊:Layouts(Adapter) & GridView Example

範例的程式碼和註解

最後再回來看書做一遍範例,以下是範例的程式碼和註解。
activity_main.xml

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >


<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:numColumns="3"
android:layout_weight="0.4"
xmlns:android="http://schemas.android.com/apk/res/android" />


<ImageSwitcher
android:id="@+id/imgSwitcher"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="0.6"
android:layout_gravity="center"
android:layout_marginTop="10dp"
>

</ImageSwitcher>
</LinearLayout>

MainActivity.java

package com.example.gallery021;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher;

// 這邊多了 implements ViewSwitcher.ViewFactory 實做了 ViewFactory 這個介面
// ViewFactory 裡面的 makeView() 抽象方法,用來幫 ViewSwitcher 建立 View
public class MainActivity extends ActionBarActivity implements ViewSwitcher.ViewFactory {

// 宣告 layout 裡的兩個東西
private GridView mGridView;
private ImageSwitcher mImgSwitcher;

// 用來放圖片id的陣列
private Integer[] iThumbImgArr = {R.drawable.sample_0,
R.drawable.sample_1, R.drawable.sample_2,
R.drawable.sample_3, R.drawable.sample_4,
R.drawable.sample_5, R.drawable.sample_6,
R.drawable.sample_7};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// 用findViewById 把 xml 中設定的 ImageSwitcher 元件
mImgSwitcher = (ImageSwitcher) findViewById(R.id.imgSwitcher);
// 傳入ViewSwitcher.ViewFactory 用在 ViewSwitcher 翻轉之間建立兩個 View
mImgSwitcher.setFactory(this);
// 設定 View 進入和離開時要用哪種動畫
mImgSwitcher.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in));
mImgSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));

// 宣告一個 ImageAdapter 給 GridView 用
ImageAdapter imgAdap = new ImageAdapter(this, iThumbImgArr);
mGridView = (GridView) findViewById(R.id.gridView);
mGridView.setAdapter(imgAdap);

// 傳入 OnItemClickListener 裡面會寫當按下 GridView 項目被點擊時要呼叫的 Callback
mGridView.setOnItemClickListener(gridViewOnItemClick);
}

// menu 用,這個範例中沒用
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

// menu 用,這個範例中沒用
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}

// 建立 OnItemClickListener 裡面寫 GridView 項目被按下時要呼叫的 Callback
private AdapterView.OnItemClickListener gridViewOnItemClick = new AdapterView.OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// 設定 ImageSwitcher 要顯示的圖片 id
mImgSwitcher.setImageResource(iThumbImgArr[position]);
}
};

// ViewFactory 的抽象方法 用來幫 ViewSwitcher 建立 View
// return View
@Override
public View makeView() {
ImageView imageView = new ImageView(this);
// 書上不知道為什麼做了兩次 setBackgroundColor
// 0xFF000000 這種顏色格式,前面的 FF 是不透明度 100%,再來 R G B 都是 00,所以把後面的setBackgroundColor註解調圖片背景就會變黑的
imageView.setBackgroundColor(0xFF000000);
// 設定如果影像需要被改變大小時要怎麼做
// 有: matrix, fitXY, fitStart, fitCenter, fitEnd, center, centerCrop, centerInside
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setLayoutParams(new ImageSwitcher.LayoutParams(ImageSwitcher.LayoutParams.MATCH_PARENT, ImageSwitcher.LayoutParams.MATCH_PARENT));
// 書上不知道為什麼做了兩次 setBackgroundColor 第一次的設定會被第二次蓋掉,所以最後圖片背景是白的
imageView.setBackgroundColor(Color.WHITE);
return imageView;
}
}

這邊多了 implements ViewSwitcher.ViewFactory 實做了 ViewFactory 這個介面,所以必須要實做 ViewFactory 裡面的 makeView() 抽象方法,用來幫 ViewSwitcher 建立 View。

ImageAdapter.java

package com.example.gallery021;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;

// Adapter 可以把資料填入 AdapterView(像是ListView 或 GridView)
// 這邊繼承 BaseAdapter 做出 ImageAdapter 來把影像加入 GridView
public class ImageAdapter extends BaseAdapter {
private Context mContext; // 執行環境
private Integer[] mImgArr; // 影像 id 陣列

// 建構式 要把 Context 和 影像陣列丟進來
public ImageAdapter(Context context, Integer[] imgArr) {
mContext = context;
mImgArr = imgArr;
}

// 用來回傳項目數量,陣列的話就用 .length 回傳長度
@Override
public int getCount() {
return mImgArr.length;
}

// 傳入 position 回傳 Item
@Override
public Object getItem(int position) {
return null;
}

// 傳入 position 回傳 Item 的 id
@Override
public long getItemId(int position) {
return 0;
}

// 用來建立有放進 GridView 的 ImageView,回傳 ImageView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(10, 10, 10, 10);
} else {
imageView = (ImageView) convertView;
}

imageView.setImageResource(mImgArr[position]);
return imageView;
}
}

執行結果:

有個莫名其妙的白色背景,看起來很醜,還有上面的縮圖區,影像看起來靠左而且大小很不整齊。
所以自己做了一些調整:

  • layout xml GridView 多加一個 android:gravity="center" 讓裡面的影像會置中。
  • ImageAdapter.javagetView() 中設定 imageView 的地方加上一行 imageView.setCropToPadding(true);
    才不會長邊沒 padding,設定好以後每個縮圖看起來都是方方的。
  • MainActivity.java 把兩個 setBackgroundColor() 都註解掉,這樣下面大圖區就不會有白白的背景了。

最後就變這樣:

文章目錄
  1. 1. 範例的程式碼和註解