星期四, 5月 26, 2016

[X.Andriod] ImageView

查到這篇官網文章 Display An Image,文章就是把 drawable 內圖片顯示到 ImageView 上,稍微做點變化來練習 - 隨機顯示 drawable 內圖片

drawable 內放進三張圖片
[X.Andriod] ImageView-2

Main.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button
        android:id="@+id/myButton"
        android:layout_width="fill_parent"
        android:layout_height="50.0dp"
        android:text="@string/changeImage" />
    <ImageView
        android:src="@drawable/sample1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/DemoImageView"
        android:scaleType="fitCenter" />
</LinearLayout>
[X.Andriod] ImageView-1

MainActivity.cs
using System.Reflection;

namespace ImageViewBase
{
    [Activity(Label = "ImageView 基礎練習", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            SetContentView(Resource.Layout.Main);

            Button btn = FindViewById<Button>(Resource.Id.myButton);
            btn.Click += (sender, e) =>
            {

                var image = FindViewById<ImageView>(Resource.Id.DemoImageView);

                // 產生隨機整數
                Random r = new Random(Guid.NewGuid().GetHashCode());
                int IndexID = r.Next(0, typeof(Resource.Drawable).GetFields().Length);

                // 從 Drawable 內的圖片抓出來
                FieldInfo[] infos = typeof(Resource.Drawable).GetFields();

                //取得 Drawable 圖片名稱
                string FileName = infos[IndexID].Name.ToLower();

                // 取得 ResourceID
                int RecID = Resources.GetIdentifier(
                            FileName, 
                            "drawable", 
                            "ImageViewBase.ImageViewBase");

                // 利用 ResourceID 顯示圖片
                image.SetImageResource(RecID);
            };
        }
    }
}
[X.Andriod] ImageView-3


練習過程中遇到的情況
  • OutOfMemoryError
VS Emulator for Andriod 開了一個 512 MB 模擬器,當圖片是 1.6MB 時,會拋出 OutOfMemoryError Exception,換成 3G 模擬器就沒這個問題,查到這兩篇文章
[X.Andriod] ImageView-4

之前都是寫 Winform,沒在管圖片大小,變成 Web 或 App 就變的很重要
  • Resources.Drawable
一直以為 Drawable 是一個放置圖片的資料夾而已,查到用 Reflection 來抓出 Drawable 內圖片時,才意識到它也是一個 class,每張圖片是 field,這一點在 Resources.Designer.cs 內就可以觀察到啦

[X.Andriod] ImageView-5
  • Resources.GetIdentifier
要利用 GetIdentifier 來找出圖片的 Resource ID,下圖為官網介紹

[X.Andriod] ImageView-6

第三個參數 defPackage 可以在專案屬性內的 Andriod Manifest 內看見,如下圖

[X.Andriod] ImageView-7

GetIdentifier 另一個重點是 - 參數大小寫問題,因為丟進 Drawable 內圖片名稱是 Sample1、Sample2 和 Sample3,所以 name 參數,也就都把第一個字大寫,然後就 return 0 (表示找不到) 給你,Orz

參數大小寫情況
name一律小寫
defType一律小寫
defPackage請和專案屬性內一模一樣

官網說明根本就沒有這個,>.<
  • SetImageResource 
完成該範例後,上官網看說明,發現這段建議
This does Bitmap reading and decoding on the UI thread, which can cause a latency hiccup. If that's a concern, consider using setImageDrawable(android.graphics.drawable.Drawable) or setImageBitmap(android.graphics.Bitmap) and BitmapFactory instead.

沒有留言:

張貼留言