Android 021 imageSwitcher 和 GridView 介面元件
之前看書看一看021 ImageSwicher 和 GridView 介面元件覺得講得有點含糊,Adapter 是什麼都沒解釋就繼承來寫 ImageAdapter,
然後就跑去看了 Android Developers 的 Layout 和 GridView,筆記在這邊: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.javapackage 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.javapackage 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.java的- getView()中設定 imageView 的地方加上一行- imageView.setCropToPadding(true);
 才不會長邊沒 padding,設定好以後每個縮圖看起來都是方方的。
- MainActivity.java把兩個- setBackgroundColor()都註解掉,這樣下面大圖區就不會有白白的背景了。
最後就變這樣:









