Java tutorial
/* * 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)); } } }