AndroidApp圖片輪播效果的元件化

image_c發表於2017-07-15
版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/voidreturn/article/details/75139689

簡介

一個通用的圖片輪播效果的通用元件,方便開發者快速整合。

初學者,其實應該實現一個自定義控制元件的,改天有空,在學習下吧,學習能力一般,以前也沒寫過java,這個元件都寫了好久,慚愧啊。

背景

筆者參考http://blog.csdn.net/allen315410/article/details/39294343 學習了圖片輪播效果的實現。在瀏覽程式碼的過程中,總覺得圖片輪播的效果和Android Activity的耦合過高,如果一個開發者要整合該功能,會將整個功能程式碼和自己的App程式碼攪在一起,提高程式碼的複雜度。同時圖片和圖片文字描述存放在兩個獨立的ArrayList,這樣的對應關係要由開發者手動維護,時刻關注對應關係正確性。
為什麼需要元件:元件開發的目的,即讓開發者用最少的程式碼,呼叫最少的介面,實現開發者的需求。
以上的描述是筆者對元件概念的最基本的認識,也是基於該原則,筆者基於http://blog.csdn.net/allen315410/article/details/39294343 進行了重構,實現了一個相對內聚的元件。

圖片輪播的要素

如果一個開發者需要開發一個圖片輪播的功能,開發者最少需要提供的元素有哪些:

  • 輪播的圖片元素
  • 每個圖片對應的文字描述
  • 輪播圖片在佈局中的位置
  • 圖片描述在佈局中的位置
  • 圖片輪播的時間間隔

理論上講,開發者只需要提高以上幾個元素即可,剩下的就有元件完成吧。基於以上思路,開發者大概只需要完成類似程式碼即可:

public class MainActivity extends Activity {
    //提供一個ViewPagerItem型別陣列,ViewPagerItem包括了圖片資訊和圖片對應描述資訊,採用一一對應的方式,方便維護
    private ViewPagerItem[] viewPagerItem = new ViewPagerItem[] {
            new ViewPagerItem(R.drawable.a, "0圖片描述資訊0"),
            new ViewPagerItem(R.drawable.b, "1圖片描述資訊1"),
            new ViewPagerItem(R.drawable.c, "2圖片描述資訊2"),
            new ViewPagerItem(R.drawable.d, "3圖片描述資訊3"),
            new ViewPagerItem(R.drawable.e, "4圖片描述資訊4"),
            new ViewPagerItem(R.drawable.e, "5圖片描述資訊5"),
    };

    private ViewPagerShow mViewPagerShow;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //提供一個layout佈局容器,用來指定圖片展示的位置
        LinearLayout container = (LinearLayout) findViewById(R.id.dot_container);
        //new一個ViewPagerShow,提供相應引數
        mViewPagerShow = new ViewPagerShow(viewPagerItem, this, (ViewPager)findViewById(R.id.vp), mHandler,
                (TextView)findViewById(R.id.title), container);

    }

    @Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();
    }

    /**
     * 接收子執行緒傳遞過來的資料,呼叫ViewPagerShow提供的update方法,實現ui的更新
     */
    private Handler mHandler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            mViewPagerShow.update();
        };
    };

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
    }
}

瀏覽以上程式碼,不難發現該功能的加入,對開發者原有的程式碼的侵入範圍不是很大。

用盡量少的程式碼,完成功能需求,是軟體開發人員不斷的追求。

輪播元件的實現

下面附上圖片輪播效果元件的程式碼實現:

package com.example.image.view;

import android.content.Context;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static android.content.ContentValues.TAG;

/**
 * Created by image on 2017/7/14.
 */

class ViewPagerItem {
    public int iMageId;
    public String iMageTitle;

    public ViewPagerItem(int iMageId, String iMageTitle) {
        this.iMageId = iMageId;
        this.iMageTitle = iMageTitle;
    }
}

class ViewPagerAdapter extends PagerAdapter {
    private List<ImageView> iMageViews;

    public ViewPagerAdapter(List<ImageView> iMageViews) {
        this.iMageViews = iMageViews;
    }

    @Override
    public int getCount() {
        return iMageViews.size();
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == arg1;
    }

    @Override
    public void destroyItem(ViewGroup view, int position, Object object) {
        // TODO Auto-generated method stub
        view.removeView(iMageViews.get(position));
    }

    @Override
    public Object instantiateItem(ViewGroup view, int position) {
        // TODO Auto-generated method stub
        view.addView(iMageViews.get(position));
        return iMageViews.get(position);
    }
}

class cloneView extends View {

    public cloneView(Context context) {
        super(context);
    }

    public cloneView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public cloneView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public cloneView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public Object clone(){
        Object o=null;
        try {
            o=super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return o;
    }
}

class ViewPagerShow {
    private ArrayList<View> dots;
    private ViewPagerItem[] viewPagerItem;
    private List<ImageView> iMagesList;
    private Context context;
    private ViewPagerAdapter mViewPagerAdapter;
    private ViewPager mViewPager;
    private ScheduledExecutorService scheduledExecutorService;
    private Handler mHandler;
    private int currentItem = 0;
    private TextView titleText;
    private LinearLayout container;
    private View dot_focus, dot_unfocus;

    private class ViewPageTask implements Runnable{
        @Override
        public void run() {
            currentItem = (currentItem + 1) % viewPagerItem.length;
            mHandler.sendEmptyMessage(0);
        };
    }

    public void dotUpdate() {
        container.removeAllViews();
        View view;
        for (int i = 0; i < this.viewPagerItem.length; i++) {
            if (i == currentItem) {
                view = LayoutInflater.from(context).inflate(R.layout.dot_focus, null);
                container.addView(view);
            } else {
                view = LayoutInflater.from(context).inflate(R.layout.dot_unfocus, null);
                container.addView(view);
            }
        }
    }

    public ViewPagerShow(final ViewPagerItem[] viewPagerItem, Context context, ViewPager mViewPager, Handler mHandler,
                         final TextView titleText, LinearLayout container) {
        this.viewPagerItem = viewPagerItem;
        this.context = context;
        this.mViewPager = mViewPager;
        this.mHandler = mHandler;
        this.titleText = titleText;
        this.container = container;
        this.dot_focus = dot_focus;
        this.dot_unfocus = dot_unfocus;

        /* show first pic title */
        titleText.setText(viewPagerItem[0].iMageTitle);

        iMagesList = new ArrayList<ImageView>();
        for (int i = 0; i < this.viewPagerItem.length; i++) {
            ImageView imageView = new ImageView(context);
            imageView.setBackgroundResource(viewPagerItem[i].iMageId);
            imageView.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Log.d(TAG, "onClick: onClick");;
                }
            });
            iMagesList.add(imageView);
        }
        dotUpdate();


        mViewPagerAdapter = new ViewPagerAdapter(iMagesList);
        mViewPager.setAdapter(mViewPagerAdapter);

        mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                titleText.setText(viewPagerItem[position].iMageTitle);
                currentItem = position;
                dotUpdate();
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {

            }

            @Override
            public void onPageScrollStateChanged(int arg0) {

            }
        });

        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.scheduleWithFixedDelay(new ViewPageTask(), 5, 5, TimeUnit.SECONDS);
    }

    public void update() {
        mViewPager.setCurrentItem(currentItem);
        titleText.setText(viewPagerItem[currentItem].iMageTitle);
        dotUpdate();
    }
}

圖片輪播的原理,基本都是參考http://blog.csdn.net/allen315410/article/details/39294343 該篇blog的介紹,這裡做的主要的事情即把相關的介面進行一個整理,集中,剝離出一個通用的處理元件,方便開發者的整合。

目前該元件的實現還比較粗糙,待後續持續的更新,完善

文章寫的很隨意,時間精力關係很多細節沒有講到,最後附上github地址,供參考:https://github.com/imagec/ViewPager


相關文章