cn.changwentao.ad.BannerAdView.java Source code

Java tutorial

Introduction

Here is the source code for cn.changwentao.ad.BannerAdView.java

Source

/*
 * Copyright (C) 2014 Chang Wentao
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cn.changwentao.ad;

import java.util.List;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.RelativeLayout;

import com.joey.expresscall.R;

/**
 * ????
 * 
 */
public class BannerAdView extends RelativeLayout implements OnPageChangeListener, View.OnClickListener {

    /**
     * ?
     */
    private static final int DEFAULT_INTERVAL = 3 * 1000;

    /**
     * 
     */
    private static final float DEFAULT_PAPER_RATIO = 0.4f;

    private int mFlipInterval = DEFAULT_INTERVAL;

    /**
     * ViewPager
     */
    private ViewPager mPager;

    /**
     * ??
     */
    private AdIndicator mIndicator;

    private OnPageChangeListener mOnPageChangeListener;

    /**
     * 
     */
    private OnItemClickListener mOnItemClickListener;

    /**
     * ??
     */
    private boolean mAutoStart = true;

    private boolean mRunning = false;
    private boolean mStarted = false;
    private boolean mVisible = false;
    private boolean mUserPresent = true;

    // Measure?
    private int tmpHeightMeasureSpec;

    /**
     * 
     */
    private List<AdEntity> mAdList;

    /**
     * ?????????
     */
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (Intent.ACTION_SCREEN_OFF.equals(action)) {
                mUserPresent = false;
                updateRunning();
            } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
                mUserPresent = true;
                updateRunning();
            }
        }
    };

    public BannerAdView(Context context) {
        super(context);
        init();
    }

    public BannerAdView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public BannerAdView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    /**
     * ?
     */
    private void init() {
        if (isInEditMode()) {
            return;
        }

        LayoutInflater.from(getContext()).inflate(R.layout.banner_layout_2, this, true);
        mPager = (ViewPager) findViewById(R.id.banner_view_pager);
        mIndicator = (AdIndicator) findViewById(R.id.banner_indicator_root);
        mPager.setOnPageChangeListener(this);
    }

    /**
     * 
     * 
     * @param list
     *            
     */
    public void setAdList(List<AdEntity> list) {
        mAdList = list;
        mPager.setAdapter(new BillboardPagerAdapter());
        mIndicator.notifyPageCountChanged(mPager.getCurrentItem(), mPager.getAdapter().getCount());

    }

    /**
     * ??
     */
    public void showNext() {
        if (hasAdapter()) {
            int item = (mPager.getCurrentItem() + 1) % mPager.getAdapter().getCount();
            mPager.setCurrentItem(item);
        }
    }

    /**
     * ??
     */
    public void showPrevious() {
        if (hasAdapter()) {
            int item = (mPager.getCurrentItem() - 1 + mPager.getAdapter().getCount())
                    % mPager.getAdapter().getCount();
            mPager.setCurrentItem(item);
        }
    }

    /**
     * mPager?Adapter
     * 
     * @return ?
     */
    private boolean hasAdapter() {
        return mPager.getAdapter() != null;
    }

    /**
     * ????
     * 
     * @return ??
     */
    public int getCurrentItem() {
        return mPager.getCurrentItem();
    }

    /**
     * ?????{@link OnPageChangeListener}
     * 
     * @param listener
     *            
     */
    public void setOnPageChangeListener(OnPageChangeListener listener) {
        mOnPageChangeListener = listener;
    }

    /**
     * ??
     * 
     * @param milliseconds
     *            
     */
    public void setFlipInterval(int milliseconds) {
        mFlipInterval = milliseconds;
    }

    /**
     * ?
     */
    public void startFlipping() {
        mStarted = true;
        updateRunning();
    }

    /**
     * ?
     */
    public void stopFlipping() {
        mStarted = false;
        updateRunning();
    }

    /**
     * 
     * 
     * @return ?
     */
    public boolean isFlipping() {
        return mStarted;
    }

    /**
     * {@link #onAttachedToWindow}?{@link #startFlipping()}
     * ?
     * 
     * @param autoStart
     *            ?
     */
    public void setAutoStart(boolean autoStart) {
        mAutoStart = autoStart;
    }

    /**
     * View{@link #onAttachedToWindow}{@link #startFlipping()}
     * true
     * 
     * @return ?
     */
    public boolean isAutoStart() {
        return mAutoStart;
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        final IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_USER_PRESENT);
        getContext().registerReceiver(mReceiver, filter, null, mHandler);

        if (mAutoStart) {
            // ?
            startFlipping();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();

        mVisible = false;
        getContext().unregisterReceiver(mReceiver);
        updateRunning();
    }

    @Override
    protected void onWindowVisibilityChanged(int visibility) {
        super.onWindowVisibilityChanged(visibility);

        // ????View.VISIBLE????
        mVisible = visibility == VISIBLE;
        updateRunning();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        tmpHeightMeasureSpec = heightMeasureSpec;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (w != 0) {
            int specMode = MeasureSpec.getMode(tmpHeightMeasureSpec);
            int specSize = MeasureSpec.getSize(tmpHeightMeasureSpec);

            if (specMode == MeasureSpec.EXACTLY) {
                return;
            }

            float expectHight = getWidth() * DEFAULT_PAPER_RATIO;

            if (specMode == MeasureSpec.AT_MOST) {
                expectHight = Math.min(expectHight, specSize);
            }

            int finalHight = (int) Math.ceil(expectHight);

            if (finalHight != h) {
                ViewGroup.LayoutParams params = getLayoutParams();
                params.height = finalHight;
                setLayoutParams(params);
            }
        }
    }

    /**
     * 
     * 
     * @param listener
     *            
     */
    public void setOnItemClickListener(OnItemClickListener listener) {
        mOnItemClickListener = listener;
    }

    /**
     * ???
     */
    public interface OnItemClickListener {
        /**
         * ??
         * 
         * @param position
         *            ?
         */
        public void onItemClick(int position);
    }

    @Override
    public void onClick(View v) {
        AdEntity adEntity = mAdList.get(mPager.getCurrentItem());
        adEntity.responseClick();
        if (mOnItemClickListener != null) {
            mOnItemClickListener.onItemClick(mPager.getCurrentItem());
        }
    }

    private final int FLIP_MSG = 1;

    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == FLIP_MSG) {
                if (mRunning) {
                    showNext();
                    msg = obtainMessage(FLIP_MSG);
                    sendMessageDelayed(msg, mFlipInterval);
                }
            }
        }
    };

    /**
     * ??????{@link Message}
     */
    private void updateRunning() {
        boolean running = mVisible && mStarted && mUserPresent;
        if (running != mRunning) {
            if (running) {
                Message msg = mHandler.obtainMessage(FLIP_MSG);
                mHandler.sendMessageDelayed(msg, mFlipInterval);
            } else {
                mHandler.removeMessages(FLIP_MSG);
            }
            mRunning = running;
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        mIndicator.onPageScrollStateChanged(state);
        if (mOnPageChangeListener != null) {
            mOnPageChangeListener.onPageScrollStateChanged(state);
        }
        switch (state) {
        case ViewPager.SCROLL_STATE_DRAGGING:
            stopFlipping();
            break;
        default:
            startFlipping();
            break;
        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        mIndicator.onPageScrolled(position, positionOffset, positionOffsetPixels);
        if (mOnPageChangeListener != null) {
            mOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
        }
    }

    @Override
    public void onPageSelected(int position) {
        mIndicator.onPageSelected(position);
        if (mOnPageChangeListener != null) {
            mOnPageChangeListener.onPageSelected(position);
        }
    }

    private class BillboardPagerAdapter extends PagerAdapter {
        // TODO ??ListView?
        private SparseArray<ImageView> imageViews = new SparseArray<ImageView>();

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

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView localImageView = imageViews.get(position);

            if (localImageView == null) {
                localImageView = new ImageView(BannerAdView.this.getContext());
                localImageView
                        .setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
                localImageView.setImageBitmap(mAdList.get(position).getAdBitmap());
                localImageView.setScaleType(ScaleType.FIT_XY);
                localImageView.setOnClickListener(BannerAdView.this);
                imageViews.put(position, localImageView);
            }

            container.addView(localImageView);

            return localImageView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(imageViews.get(position));
        }
    }
}