Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android學習筆記之圖片輪播...

Android學習筆記之圖片輪播...

編輯:關於Android編程

學習內容:   1.Android利用ViewPager和PagerAdapter實現圖片輪播...   2.使用反射機制獲取Android的資源信息...         圖片輪播是非常常見的一種動畫效果,在app中也是很常用的一個效果,這裡就簡單的來實現一下這個功能,Android中想要實現圖片輪播,需要使用到ViewPager這個控件來實現,這個控件的主要功能是實現圖片的滑動效果...那麼有了滑動,在滑動的基礎上附上圖片也就實現了圖片輪播的效果...這個控件類似於ListView,需要使用到適配器這個東西,適配器在這裡的作用是為輪播時設置一些效果...這裡需要使用到PagerAdapter適配器...下面來一個例子,這個例子的效果是在圖片輪播的同時顯示播放的是第幾張圖片的信息...並且下面的點也是會隨之進行變化的...     先上一下布局文件的代碼...這個布局文件其實還是有點說道的...<android.support.v4.view.ViewPager android:id="@+id/vp" android:layout_height="fill_parent" android:layout_width="fill_parent"/>這句話必須要引進...否則會出現錯誤...意思就是我設置了一個滑動的效果,這個效果填充整個FrameLayout...每一個View表示一個控件,這個控件的顯示方式在另外的xml文件當中...下面是兩個xml文件...  
<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid
        android:color="#000000">
    </solid>
    <corners 
        android:radius="5dip"/>
</shape>

 

     
<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid 
        android:color="#00ffff"/>
    <corners 
        android:radius="5dip"/>
</shape>

 

    上面通過配置xml文件來完成View的顯示方式,因為這五個點的形狀,大小,甚至是顯示方式基本都是相同的,如果再去找5個點圖片或者是一個點圖片,然後通過Drawable資源的調用完成圖片的顯示...通過加載5次的方式...這樣顯然是沒有必要的,會浪費不必要的資源..因此我們可以使用xml提供的自定義圖形來完成這個過程...xml為我們提供了shape屬性,自定義控件..這裡我定義了一個實心圓...這個實心圓來完成隨著圖像的滑動,這個點也隨之進行相應的變化...看起來並不是什麼難理解的東西...  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <FrameLayout 
        android:layout_height="300dip"
        android:layout_width="fill_parent">
        <android.support.v4.view.ViewPager
            android:id="@+id/vp"
            android:layout_height="fill_parent"
            android:layout_width="fill_parent"/>
        <LinearLayout 
            android:layout_height="30dip"
            android:layout_width="fill_parent"
            android:gravity="center"
            android:layout_gravity="bottom"
            android:orientation="vertical"
            android:background="#20000000"
            >
            <TextView 
                android:id="@+id/tv"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:textColor="@android:color/white"
                android:text="@string/hello_world"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="3dip"/>
            <LinearLayout 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:layout_marginTop="3dip">
                <View 
                    android:id="@+id/dot_0"
                    android:layout_width="5dip"
                    android:layout_height="5dip"
                    android:layout_marginRight="3dip"
                    android:layout_marginLeft="3dip"
                    android:background="@drawable/dot"/>
                <View 
                    android:id="@+id/dot_1"
                    android:layout_height="5dip"
                    android:layout_width="5dip"
                    android:layout_marginRight="3dip"
                    android:layout_marginLeft="3dip"
                    android:background="@drawable/dot_1"/>
                  <View 
                    android:id="@+id/dot_2"
                    android:layout_height="5dip"
                    android:layout_width="5dip"
                    android:layout_marginRight="3dip"
                    android:layout_marginLeft="3dip"
                    android:background="@drawable/dot_1"/>
                  <View 
                    android:id="@+id/dot_3"
                    android:layout_height="5dip"
                    android:layout_width="5dip"
                    android:layout_marginRight="3dip"
                    android:layout_marginLeft="3dip"
                    android:background="@drawable/dot_1"/>
                  <View 
                    android:id="@+id/dot_4"
                    android:layout_height="5dip"
                    android:layout_width="5dip"
                    android:layout_marginRight="3dip"
                    android:layout_marginLeft="3dip"
                    android:background="@drawable/dot_1"/>
            </LinearLayout>
        </LinearLayout>
    </FrameLayout>

</RelativeLayout>

 

      重要的部分還是如何去實現這個過程...這個過程的實現就再下面的代碼中,詳細解釋也在代碼當中...  
package com.example.picture_change;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
/*
 * HashMap存儲的鍵是不允許重復的...但是值是可以重復的...
 * 
 * */
public class MainActivity extends Activity {

    ArrayList<ImageView> imageSource=null; //存放圖像控件...
    ArrayList<View> dots=null;             //存放5個點...
    int []images=null;                     //存放圖像的資源...
    String []titles=null;                  //伴隨著圖像的變動,標題也會隨之變動...
    TextView tv=null;                      //TextView來來顯示title的變化...
    ViewPager viewpager;                   //ViewPager來完成滑動效果...
    MyPagerAdapter adapter;                //適配器...
    Map<String, Object>map=new HashMap<String, Object>(); 
    @SuppressLint("UseSparseArrays")
    Map<Integer,Object>mapValues=new HashMap<Integer, Object>();
    private int curr=0;
    private int old=0;
    int o=0;
    int mapsize;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toast.makeText(MainActivity.this, "a", Toast.LENGTH_LONG).show();
        /* 下面利用反射來完成Drawable的資源獲取...
         * 在這裡我獲取了5張圖片的資源數據..這5張圖片分別為a.jpg b.jpg c.jpg d.jpg e.jpg
         * 這裡使用了一個length<=1來完成數據的獲取...其實這個方式並不好,是我自己想出來的...
         * 暫時沒有更好的方法...我這裡使用反射的目的在下面會進行介紹...
         * */
        Field [] field=R.drawable.class.getFields();
        for(Field f:field){
            if(f.getName().length()<=1){
                try {
                    o++;
                    String str="image"+"_"+o;
                    map.put(str, f.getInt(R.drawable.class));//使用map以鍵值對的形式來保存圖片的數據資源...
                } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        mapsize=map.size()-1;
        /* 這裡我再次使用了一個map以鍵值對的形式只保存上一個map的Value值...
         * 這麼做的目的在下面進行說明...
         * 
         * */
        for(Entry<String, Object> entry:map.entrySet()){
            mapValues.put(mapsize, entry.getValue());
            mapsize--;
        }
        init();
    }

    public void init(){
        //數據信息的初始化...
        
        images=new int[]{R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.d,R.drawable.e};
        titles=new String[]{"this is the one picture","this is two picture","this is three picture","this is four picture","this is five picture"};
        imageSource=new ArrayList<ImageView>();
        //這裡初始化imageSource...
        for(int i=0;i<images.length;i++){
            ImageView iamgeview =new ImageView(this);
            iamgeview.setBackgroundResource(images[i]);
            imageSource.add(iamgeview);
        }
        //這裡使用了一個方法...我們沒有必要一次一次的findViewById()...使用下面的方法很有效的解決了多次findViewById()函數的引用...
        dots=new ArrayList<View>();
        for(int j=0;j<5;j++){
            String dotid="dot"+"_"+j;
            int resId=getResources().getIdentifier(dotid, "id", "com.example.picture_change");
            dots.add(findViewById(resId));
        }
        tv=(TextView) findViewById(R.id.tv);
        tv.setText(titles[0]);
        viewpager=(ViewPager) findViewById(R.id.vp);
        
        adapter=new MyPagerAdapter();   //這裡定義了一個適配器對象...
        viewpager.setAdapter(adapter);  //傳遞對象,綁定適配器...
        viewpager.setOnPageChangeListener(new onpagelistener());  //這裡設置了一個當圖片發生滑動後的一個監聽效果...
        
        ScheduledExecutorService scheduled =  Executors.newSingleThreadScheduledExecutor();//這裡我們開啟一個線程...
        scheduled.scheduleAtFixedRate(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                curr=(curr+1)%images.length;
                handler.sendEmptyMessage(0);//將信息發送給Handler,讓Handler處理數據,完成一些操作...
            }
        }, 2, 2, TimeUnit.SECONDS);  //實現內部方法,設置播放時間...
        
    }
    private class MyPagerAdapter extends PagerAdapter{

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return images.length;
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            // TODO Auto-generated method stub
            //判斷前後兩張的顯示圖片是否相同...
            return arg0==arg1;
        }
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            //銷毀...釋放內存...
            container.removeView(imageSource.get(position));
        }
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            /* 這個方法表示的是滑動到了第幾張圖片的定位...通過傳遞一個ViewGroup來完成數據的傳遞...
             * 我們上面使用到了一個Map來保存上一個Map的Value值,這個的真正目的就在這裡..目的是為了
             * 獲取當前顯示圖片的資源信息..說白了就是要獲取(R.drawable.屬性),為什麼要實現這個目的
             * 因為我們要實現,當這個顯示的圖片被點擊的時候,我們應該進行哪些操作...
             * */
            ImageView v=imageSource.get(position);//獲取當前圖片...
            //position是從0-4的值...因此可以獲取到Map中的值了...
            v.setClickable(true);  //設置圖片是可以點擊的...
            final int values=(Integer)mapValues.get(position); //這裡我們獲取map中保存的Values值...
            System.out.println(values);
            //下面就是實現觸發圖片時的監聽...
            v.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    switch(values){
                    case R.drawable.a:
                        Toast.makeText(MainActivity.this, "a", Toast.LENGTH_LONG).show();
                        break;
                    case R.drawable.b:
                        Toast.makeText(MainActivity.this, "b", Toast.LENGTH_LONG).show();
                        break;
                    case R.drawable.c:
                        Toast.makeText(MainActivity.this, "c", Toast.LENGTH_LONG).show();
                        break;
                    case R.drawable.d:
                        Toast.makeText(MainActivity.this, "d", Toast.LENGTH_LONG).show();
                        break;
                    case R.drawable.e:
                        Toast.makeText(MainActivity.this, "e", Toast.LENGTH_LONG).show();
                        break;
                    }
                }
            });
            container.addView(imageSource.get(position));  //將所有的圖片都加載到了container中...  
            return imageSource.get(position);
            
        }
    }
    //定義一個內部類實現圖片在變化的時候的監聽...
    class onpagelistener implements OnPageChangeListener{

        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void onPageSelected(int arg0) {
            // TODO Auto-generated method stub
            //當發生滑動後,要完成的一些相應操作...
            tv.setText(titles[arg0]);
            dots.get(arg0).setBackgroundResource(R.drawable.dot);
            dots.get(old).setBackgroundResource(R.drawable.dot_1);
            old=arg0;
            curr=arg0;
        }
        
    }
    
    @SuppressLint("HandlerLeak")
    private Handler handler=new Handler(){
        public void handleMessage(Message msg) {
            //接收到消息後,更新頁面
            viewpager.setCurrentItem(curr);
        };
    };
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

 

      這裡我使用了反射機制來獲取Drawable的圖像資源,然後通過switch方法來完成了當圖片被點擊的時候需要完成的操作...這是筆者我自己想出來的一種方法...因為Android沒有提供ImageClickListener()這類的方法,因此我們只能夠自己去進行書寫圖片被點擊的方法...至於更好的方法,我是還沒有發現...也是確實是能力有限制了,這個方法今天也想了整整一個下午才折騰出來的...     注意:給自己的一個提醒,HashMap的鍵是絕對不能夠重復保存的...但是值是可以保存重復的數據的,如果保存了重復的鍵,那麼在map只會保存第一個數據,不會對後續數據進行保存...這個也是一個很大的注意點,自己就栽這裡很久,雖然很低級的錯誤,但是很有可能在不注意的情況下就犯下了...因此在這裡也算是給自己提個醒...下次不會再犯下這樣的錯誤的..
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved