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

來源:互聯網
上載者:User

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只會儲存第一個資料,不會對後續資料進行儲存...這個也是一個很大的注意點,自己就栽這裡很久,雖然很低級的錯誤,但是很有可能在不注意的情況下就犯下了...因此在這裡也算是給自己提個醒...下次不會再犯下這樣的錯誤的..

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.