2013年4月24日

【Android】Gallery元件的自動輪播與無限循環效果

嘿嘿~~~各位Android安卓大大的開發者大家好啊!!! ^^

小黑人這次要向大家介紹一個元件,就是"Gallery"!
Gallery就是相片畫廊的意思,主要是運用來圖片瀏覽的部分,有許多開發者都會接觸運用到這個瀏覽圖片且滑動圖片的效果,但今天小黑人要介紹的不是單純的Gallery圖片檢視,小黑人會在Gallery添加"自動輪播"且"無限迴圈"播放的效果。

其實Gallery可以做非常多的事情,像不只是圖片可放在Gallery內,layout或者是list或者是View都可以置入,然後特效部分也可以運用到很多,像滑動時圖片可以放大縮小排列方式從水平排列變成V字形排列等效果。
這些功能特效運用小黑人會在日後向大家介紹 >///< ,這次就先向大家說明"Gallery"的"自動輪播"和"無限迴圈"吧!

首先在xml佈局裡先添加一個Gallery元件 :
<Gallery
android:id="@+id/gallery"               //新增元件ID
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fadingEdge="none"              //圖片的邊緣顏色不要有漸層
android:scrollbars="none"               //滾動圖片時不要有scrollbar的那一條
/>

接下來就是在程式裡 (.java) 要進行控制囉 :
private Gallery mGallery;
private Timer mTimer;
private TimerTask mTimerTask;
private Handler mHandler = new Handler();
private int[] Pics = {R.drawable.pic1,R.drawable.pic2,R.drawable.pic3,R.drawable.pic4,R.drawable.pic5} ;
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
       
    mGallery = ((Gallery) findViewById(R.id.gallery));
    //Pics為要顯示圖片的Resources陣列
    mGallery.setAdapter(new ImageAdapter(this , Pics));
    //圖片不透明
    mGallery.setUnselectedAlpha( 255 );
    //圖片不漸層,漸層長度為0
    mGallery.setFadingEdgeLength( 0 );
    //圖片不重疊,圖片間距為0
    mGallery.setSpacing(0);
    //圖片一開始顯示在第幾張設定在Integer.MAX_VALUE/2的位置(Integer.MAX_VALUE為int的最高值)
    mGallery.setSelection(Integer.MAX_VALUE/2);
    //圖片在切換圖片的速度
    mGallery.setAnimationDuration(2000);
    //設定點擊圖片時觸發
    mGallery.setOnItemClickListener(click);
}
private OnItemClickListener click = new OnItemClickListener()
{
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
    {
        Toast.makeText(MainActivity.this, "您點擊第" + ((arg2 % Pics.length) + 1) + "張圖片", Toast.LENGTH_SHORT).show();
    }
};
@Override
//程式暫停時將自動輪播功能的時間計時清除
protected void onPause()
{
    super.onPause();
       
    if(mTimer!=null)
    {
        mTimer.cancel();
        mTimer=null;
    }
       
    if(mTimerTask!=null)
    {
        mTimerTask.cancel();
        mTimerTask=null;
    }
}
@Override
//程式回復時建立自動輪播的時間計時
protected void onResume()
{
    super.onResume();
       
    //因下方會重新new Timer,避免重複佔據系統不必要的資源,在此確認mTimer是否為null
    if(mTimer!=null)
    {
        mTimer.cancel();
        mTimer=null;
    }
       
    //因下方會重新new TimerTask,避免重複佔據系統不必要的資源,在此確認mTimerTask是否為null
    if(mTimerTask!=null)
    {
        mTimerTask.cancel();
        mTimerTask=null;
    }
       
    //建立Timer
    mTimer = new Timer();
    //建立TimerTask
    mTimerTask = new TimerTask()
    {
        @Override
        public void run()
        {
            mHandler.post(new Runnable()
            {
                @Override
                public void run()
                {
                    //每3秒觸發時要做的事
                    //scroll 3
                    mGallery.onScroll(null, null, 3, 0);
                    //向右滾動
                    mGallery.onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT , null);
                }
            });
        }
    };

    //從3秒開始,每3秒觸發一次,每三秒自動滾動
    mTimer.schedule(mTimerTask, 3000, 3000);
}
//建立BaseAdapter並將此Adapter置入Gallery內
public class ImageAdapter extends BaseAdapter
{
    private Context mContext ;
    private int[] mPics ;
                          
    public ImageAdapter(Context c , int[] pics)
    {
        this.mContext = c;
        mPics = pics ;
    }

    @Override
    //Gallery圖片總數為int的最大值,目的為無限迴圈
    public int getCount()
    {
        return Integer.MAX_VALUE;
    }

    @Override
    //目前圖片位置除以圖片總數量的餘數
    public Object getItem(int position)
    {
        return position % mPics.length ;
    }
       
    @Override
    public long getItemId(int position)
    {
        return position;
    }
         
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        //建立圖片
        ImageView img = new ImageView(this.mContext);
        //將圖片置入img,置入的圖片為目前位置的圖片除以圖片總數取餘數,此餘數為圖片陣列的圖片位置
        img.setImageResource(mPics[position % mPics.length]);
        //保持圖片長寬比例
        img.setAdjustViewBounds(true);
        //縮放為置中
        img.setScaleType(ImageView.ScaleType.FIT_CENTER);
        //設置圖片長寬
        img.setLayoutParams(new Gallery.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
               
        //回傳此建立的圖片
        return img;
    }
}
以上就是可以讓Gallery自動輪播且無限循環的程式碼,大家可以嘗試看看唷。
希望大家可以互相交流,如有任何問題可以跟小黑人討論唷 ^^
呵呵~謝謝大家!!! >///<

14 則留言:

  1. mGallery.setFadingEdgeLength( 0 ); 是左右 影子的長度
    mGallery.setSpacing(0); 是間距
    註解跑位嚕!

    回覆刪除
    回覆
    1. 哈囉~您好 ^^
      感謝您提醒小黑人,小黑人不小心把那整段註解都標到上一行去了。
      呵呵~感謝您的發問與提醒!

      刪除
  2. 不好意思,想請問一下版主,不知是否遇過 gallery程式執行時,弱小圖滑動太快,則程式會跳出此頁或跳出錯誤對話框呢?不知如何解決?還煩請版主賜教,謝謝.

    回覆刪除
    回覆
    1. 問題已解決,為記憶體方面的問題,謝謝!!

      刪除
    2. 您好,很抱歉這麼久才回覆您!
      哈哈,小黑人這段時間忙著處理專題研究,真不好意思...
      根據您的提問小黑人向您解釋,
      因為Gallery元件會預載左右鄰近圖片,所以即使畫面沒有顯示,
      但Gallery已經會先載入方便滑動順暢,
      至於導致記憶體爆掉的原因可能應該是圖片尺寸過大,
      可能需要在讀取圖片時進行圖片縮圖。

      感謝您的提問!

      刪除
  3. 您好,很抱歉這麼久才回覆您!
    哈哈,小黑人這段時間忙著處理專題研究,真不好意思...
    根據您的提問小黑人向您解釋,
    因為Gallery元件會預載左右鄰近圖片,所以即使畫面沒有顯示,
    但Gallery已經會先載入方便滑動順暢,
    至於導致記憶體爆掉的原因可能應該是圖片尺寸過大,
    可能需要在讀取圖片時進行圖片縮圖。

    感謝您的提問!

    回覆刪除
  4. 我已經測試過了 但是會滑動的不順暢 然後最後停止自動關閉
    要怎麼解決效能的問題呢?

    回覆刪除
    回覆
    1. 您好,根據您的提問小黑人向您解釋,
      如果圖片滑一滑之後就會關閉程式的話,
      小黑人推測可能是圖片太大張的關係而導致手機記憶體不足的狀況,
      那您可以換個寫法試試,例如運用Bitmap方式把圖片匯入時進行縮小再放入ImageView,
      例如 :
      BitmapFactory.Options options = new BitmapFactory.Options();
      options.inJustDecodeBounds = false;
      options.inPurgeable = true;
      options.inInputShareable = true;
      options.inSampleSize = 2;

      Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), mPics[position % mPics.length], options);
      img.setImageBitmap(mBitmap);

      以Bitmap匯入方法可以有效減少圖片匯入時系統所佔據的資源,再請您試試看。

      感謝您的提問。

      刪除
    2. 作者已經移除這則留言。

      刪除
  5. 作者已經移除這則留言。

    回覆刪除
  6. 如何去抓取照片的人脸,然后可以通过人脸数量来搜索照片?

    回覆刪除
    回覆
    1. 您好,很抱歉這麼久才回覆您,
      根據您說的讀取人臉狀態,這可能需要臉部辨識系統才可以完成喔,
      小黑人這部分還尚未研究,很抱歉未能幫上您的忙...
      感謝您的留言!

      刪除
  7. 想請問如果要指定撥放資料夾的照片
    該怎麼設定呢?!
    感謝

    回覆刪除

謝謝大家支持,有任何問題都可以和小黑人一起討論!