先上效果图(点击图片可以跳转相应webview)
1.添加Glide依赖
implementation 'com.github.bumptech.glide:glide:3.7.0'
2.创建工具类
2.1创建CircleFlowIndicator工具类
package com.example.test.util;import android.content.Context; 2.2创建,FlowInicator工具类 package com.example.test.util;public interface FlowIndicator extends ViewFlow.ViewSwitchListener {/*** Set the current ViewFlow. This method is called by the ViewFlow when the* FlowIndicator is attached to it.* * @param view*/public void setViewFlow(ViewFlow view);/*** The scroll position has been changed. A FlowIndicator may implement this* method to reflect the current position* * @param h* @param v* @param oldh* @param oldv*/public void onScrolled(int h, int v, int oldh, int oldv); 2.3创建ViewFlow工具类 /** Copyright (C) 2011 Patrik Åkerfeldt* * 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.*/ 2.4创建ProgressWebView工具类(点击广告要跳转的webview) package com.example.test.util;import android.content.Context; 3.创建BaseWebActivity(及得在配置文件注册activity) package com.example.test.activity;import android.app.Activity; 3.drawable相关文件 3.1advertising_bg.xml 3.2progress_bar_states.xml 4.图片适配器ImagePagerAdapter /** Copyright 2014 trinea.cn All right reserved. This software is the confidential and proprietary information of* trinea.cn ("Confidential Information"). You shall not disclose such Confidential Information and shall use it only in* accordance with the terms of the license agreement you entered into with trinea.cn.*/ 5.相关layout文件 5.1activity_main_advertising.xml 5.2activity_baseweb.xml 6.value相关文件 6.1arrt.xml 6.2dimens.xml 6.3ids.xml 6.4设置完ids文件后再application的oncreate方法中添加下面代码 ViewTarget.setTagId(R.id.tag_glide); 7.主页Activity /*** 广告相关*/ @Override /*** 初始化控件*/ /*** 广告相关*/ /*** 初始化数据*/ //广告相关 } private void showDialog() {dialogs.setCanceledOnTouchOutside(false);//dialog弹出后会点击屏幕,dialog不消失;点击物理返回键dialog消失dialogs.show();dialogs.getWindow().setContentView(layout);dialogs.getWindow().setBackgroundDrawableResource(R.color.transparent); }
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;import com.example.test.R;public class CircleFlowIndicator extends View implements FlowIndicator,AnimationListener {private static final int STYLE_STROKE = 0;private static final int STYLE_FILL = 1;private float radius = 4;private float circleSeparation = 2*radius+radius;private float activeRadius = 0.5f;private int fadeOutTime = 0;private final Paint mPaintInactive = new Paint(Paint.ANTI_ALIAS_FLAG);private final Paint mPaintActive = new Paint(Paint.ANTI_ALIAS_FLAG);private ViewFlow viewFlow;private int currentScroll = 0;private int flowWidth = 0;private FadeTimer timer;public AnimationListener animationListener = this;private Animation animation;private boolean mCentered = false;/*** Default constructor* * @param context*/public CircleFlowIndicator(Context context) {super(context);initColors(0xFFFFFFFF, 0xFFFFFFFF, STYLE_FILL, STYLE_STROKE);}/*** The contructor used with an inflater* * @param context* @param attrs*/public CircleFlowIndicator(Context context, AttributeSet attrs) {super(context, attrs);// Retrieve styles attributsTypedArray a = context.obtainStyledAttributes(attrs,R.styleable.CircleFlowIndicator);// Gets the inactive circle type, defaulting to "fill"int activeType = a.getInt(R.styleable.CircleFlowIndicator_activeType,STYLE_FILL);int activeDefaultColor = 0xFFFFFFFF;// Get a custom inactive color if there is oneint activeColor = a.getColor(R.styleable.CircleFlowIndicator_activeColor,activeDefaultColor);// Gets the inactive circle type, defaulting to "stroke"int inactiveType = a.getInt(R.styleable.CircleFlowIndicator_inactiveType, STYLE_STROKE);int inactiveDefaultColor = 0x44FFFFFF;// Get a custom inactive color if there is oneint inactiveColor = a.getColor(R.styleable.CircleFlowIndicator_inactiveColor,inactiveDefaultColor);// Retrieve the radiusradius = a.getDimension(R.styleable.CircleFlowIndicator_radius, 4.0f);circleSeparation = a.getDimension(R.styleable.CircleFlowIndicator_circleSeparation, 2*radius+radius);activeRadius = a.getDimension(R.styleable.CircleFlowIndicator_activeRadius, 0.5f);// Retrieve the fade out timefadeOutTime = a.getInt(R.styleable.CircleFlowIndicator_fadeOut, 0);mCentered = a.getBoolean(R.styleable.CircleFlowIndicator_centered, false);initColors(activeColor, inactiveColor, activeType, inactiveType);}private void initColors(int activeColor, int inactiveColor, int activeType,int inactiveType) {// Select the paint type given the type attrswitch (inactiveType) {case STYLE_FILL:mPaintInactive.setStyle(Style.FILL);break;default:mPaintInactive.setStyle(Style.STROKE);}mPaintInactive.setColor(inactiveColor);// Select the paint type given the type attrswitch (activeType) {case STYLE_STROKE:mPaintActive.setStyle(Style.STROKE);break;default:mPaintActive.setStyle(Style.FILL);}mPaintActive.setColor(activeColor);}/** (non-Javadoc)* * @see android.view.View#onDraw(android.graphics.Canvas)*/@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int count = 3;if (viewFlow != null) {count = viewFlow.getViewsCount();}//this is the amount the first circle should be offset to make the entire thing centeredfloat centeringOffset = 0;int leftPadding = getPaddingLeft();// Draw stroked circlesfor (int iLoop = 0; iLoop
}
}
package com.example.test.util;import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.Scroller;import com.example.test.R;import java.util.ArrayList;
import java.util.LinkedList;/*** * A horizontally scrollable {@link ViewGroup} with items populated from an* {@link Adapter}. The ViewFlow uses a buffer to store loaded {@link View}s in.* The default size of the buffer is 3 elements on both sides of the currently* visible {@link View}, making up a total buffer size of 3 * 2 + 1 = 7. The* buffer size can be changed using the {@code sidebuffer} xml attribute.* * @author http://blog.csdn.net/finddreams*/
public class ViewFlow extends AdapterView
// && mCurrentScreen == getChildCount() - 1) {
// snapToScreen(0);
// }
// else if (velocityX > SNAP_VELOCITY
// && mCurrentScreen == 0) {
// snapToScreen(getChildCount() - 1);
// }else {snapToDestination();}if (mVelocityTracker != null) {mVelocityTracker.recycle();mVelocityTracker = null;}}mTouchState = TOUCH_STATE_REST;if(handler!=null){Message message = handler.obtainMessage(0);handler.sendMessageDelayed(message, timeSpan);}break;case MotionEvent.ACTION_CANCEL:snapToDestination();mTouchState = TOUCH_STATE_REST;}return true;}@Overrideprotected void onScrollChanged(int h, int v, int oldh, int oldv) {super.onScrollChanged(h, v, oldh, oldv);if (mIndicator != null) {/** The actual horizontal scroll origin does typically not match the* perceived one. Therefore, we need to calculate the perceived* horizontal scroll origin here, since we use a view buffer.*/int hPerceived = h + (mCurrentAdapterIndex - mCurrentBufferIndex)* getWidth();mIndicator.onScrolled(hPerceived, v, oldh, oldv);}}private void snapToDestination() {final int screenWidth = getWidth();final int whichScreen = (getScrollX() + (screenWidth / 2))/ screenWidth;snapToScreen(whichScreen);}private void snapToScreen(int whichScreen) {mLastScrollDirection = whichScreen - mCurrentScreen;if (!mScroller.isFinished())return;whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));mNextScreen = whichScreen;final int newX = whichScreen * getWidth();final int delta = newX - getScrollX();mScroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2);invalidate();}@Overridepublic void computeScroll() {if (mScroller.computeScrollOffset()) {scrollTo(mScroller.getCurrX(), mScroller.getCurrY());postInvalidate();} else if (mNextScreen != INVALID_SCREEN) {mCurrentScreen = Math.max(0,Math.min(mNextScreen, getChildCount() - 1));mNextScreen = INVALID_SCREEN;postViewSwitched(mLastScrollDirection);}}/*** Scroll to the {@link View} in the view buffer specified by the index.* * @param indexInBuffer* Index of the view in the view buffer.*/private void setVisibleView(int indexInBuffer, boolean uiThread) {mCurrentScreen = Math.max(0,Math.min(indexInBuffer, getChildCount() - 1));int dx = (mCurrentScreen * getWidth()) - mScroller.getCurrX();mScroller.startScroll(mScroller.getCurrX(), mScroller.getCurrY(), dx,0, 0);if(dx == 0)onScrollChanged(mScroller.getCurrX() + dx, mScroller.getCurrY(), mScroller.getCurrX() + dx, mScroller.getCurrY());if (uiThread)invalidate();elsepostInvalidate();}/*** Set the listener that will receive notifications every time the {code* ViewFlow} scrolls.* * @param l* the scroll listener*/public void setOnViewSwitchListener(ViewSwitchListener l) {mViewSwitchListener = l;}@Overridepublic Adapter getAdapter() {return mAdapter;}@Overridepublic void setAdapter(Adapter adapter) {setAdapter(adapter, 0);}public void setAdapter(Adapter adapter, int initialPosition) {if (mAdapter != null) {mAdapter.unregisterDataSetObserver(mDataSetObserver);}mAdapter = adapter;if (mAdapter != null) {mDataSetObserver = new AdapterDataSetObserver();mAdapter.registerDataSetObserver(mDataSetObserver);}if (mAdapter == null || mAdapter.getCount() == 0)return;setSelection(initialPosition); }@Overridepublic View getSelectedView() {return (mCurrentBufferIndex
// mCurrentAdapterIndex += mAdapter.getCount() - 2;
// mCurrentBufferIndex += mAdapter.getCount() - 2;
// }View recycleView = null;// Remove view outside buffer rangeif (mCurrentAdapterIndex > mSideBuffer) {recycleView = mLoadedViews.removeFirst();detachViewFromParent(recycleView);// removeView(recycleView);mCurrentBufferIndex--;}// Add new view to bufferint newBufferIndex = mCurrentAdapterIndex + mSideBuffer;if (newBufferIndex
// mCurrentBufferIndex -= mAdapter.getCount() - 2;
// }View recycleView = null;// Remove view outside buffer rangeif (mAdapter.getCount() - 1 - mCurrentAdapterIndex > mSideBuffer) {recycleView = mLoadedViews.removeLast();detachViewFromParent(recycleView);}// Add new view to bufferint newBufferIndex = mCurrentAdapterIndex - mSideBuffer;if (newBufferIndex > -1) {mLoadedViews.addFirst(makeAndAddView(newBufferIndex, false,recycleView));mCurrentBufferIndex++;}}requestLayout();setVisibleView(mCurrentBufferIndex, true);if (mIndicator != null) {mIndicator.onSwitched(mLoadedViews.get(mCurrentBufferIndex),mCurrentAdapterIndex);}if (mViewSwitchListener != null) {mViewSwitchListener.onSwitched(mLoadedViews.get(mCurrentBufferIndex),mCurrentAdapterIndex);}}private View setupChild(View child, boolean addToEnd, boolean recycle) {LayoutParams p = (LayoutParams) child.getLayoutParams();if (p == null) {p = new AbsListView.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT, 0);}if (recycle)attachViewToParent(child, (addToEnd ? -1 : 0), p);elseaddViewInLayout(child, (addToEnd ? -1 : 0), p, true);return child;}private View makeAndAddView(int position, boolean addToEnd, View convertView) {View view = mAdapter.getView(position, convertView, this);return setupChild(view, addToEnd, convertView != null);}class AdapterDataSetObserver extends DataSetObserver {@Overridepublic void onChanged() {View v = getChildAt(mCurrentBufferIndex);if (v != null) {for (int index = 0; index
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.webkit.WebView;
import android.widget.ProgressBar;import com.example.test.R;/*** @Description: 带进度条的WebView* @author http://blog.csdn.net/finddreams*/
@SuppressWarnings("deprecation")
public class ProgressWebView extends WebView {private ProgressBar progressbar;public ProgressWebView(Context context, AttributeSet attrs) {super(context, attrs);progressbar = new ProgressBar(context, null,android.R.attr.progressBarStyleHorizontal);progressbar.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,10, 0, 0));Drawable drawable = context.getResources().getDrawable(R.drawable.progress_bar_states);progressbar.setProgressDrawable(drawable);addView(progressbar);// setWebViewClient(new WebViewClient(){});setWebChromeClient(new WebChromeClient());//是否支持缩放getSettings().setSupportZoom(true);getSettings().setBuiltInZoomControls(true); }public class WebChromeClient extends android.webkit.WebChromeClient {@Overridepublic void onProgressChanged(WebView view, int newProgress) {if (newProgress == 100) {progressbar.setVisibility(GONE);} else {if (progressbar.getVisibility() == GONE)progressbar.setVisibility(VISIBLE);progressbar.setProgress(newProgress);}super.onProgressChanged(view, newProgress);}}@Overrideprotected void onScrollChanged(int l, int t, int oldl, int oldt) {LayoutParams lp = (LayoutParams) progressbar.getLayoutParams();lp.x = l;lp.y = t;progressbar.setLayoutParams(lp);super.onScrollChanged(l, t, oldl, oldt);}
}
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;import com.example.test.R;
import com.example.test.base.BaseApplication;
import com.example.test.util.ProgressWebView;/*** @Description:WebView界面,带自定义进度条显示* @author http://blog.csdn.net/finddreams*/
public class BaseWebActivity extends Activity {private static String TAG = BaseWebActivity.class.getSimpleName() + "===";protected ProgressWebView mWebView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_baseweb);BaseApplication.getApp().addActivity(this);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {Window window = getWindow();// 有些情况下需要先清除透明flagwindow.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);window.setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));}mWebView = (ProgressWebView) findViewById(R.id.baseweb_webview);mWebView.getSettings().setJavascriptEnabled(true);initData();}protected void initData() {Intent intent = getIntent();Bundle bundle = intent.getExtras();String urls = bundle.getString("url");mWebView.loadUrl(urls);mWebView.getSettings().setJavascriptEnabled(true);mWebView.getSettings().setAppCacheEnabled(true);//设置 缓存模式 mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);// 开启 DOM storage API 功能 mWebView.getSettings().setDomStorageEnabled(true);mWebView.setWebViewClient(new WebViewClient(){@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {// view.loadUrl(url);return super.shouldOverrideUrlLoading(view, url);}});}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {try{if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {mWebView.goBack();// 返回前一个页面return true;}else{BaseApplication.getApp().finishActivity(this);finish();}}catch (Exception e){}return super.onKeyDown(keyCode, event);}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();mWebView = null;BaseApplication.getApp().finishActivity(this);}}
package com.example.test.adapter;import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;import com.bumptech.glide.Glide;
import com.example.test.R;
import com.example.test.activity.BaseWebActivity;import java.util.List;/*** @author http://blog.csdn.net/finddreams* @Description: 图片适配器*/
public class ImagePagerAdapter extends BaseAdapter {private List
// Glide.with(context)
// .load(this.imageIdList.get(getPosition(position))).fitCenter().into(holder.imageView);
// imageLoader.displayImage(
// (String) this.imageIdList.get(getPosition(position)),
// holder.imageView, options);holder.imageView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {String url = linkUrlArray.get(ImagePagerAdapter.this.getPosition(position));Bundle bundle = new Bundle();bundle.putString("url", url);Intent intent = new Intent(arg0.getContext(), BaseWebActivity.class);intent.putExtras(bundle);arg0.getContext().startActivity(intent);dialogs.dismiss();}});return view;}private static class ViewHolder {ImageView imageView;}/*** @return the isInfiniteLoop*/public boolean isInfiniteLoop() {return isInfiniteLoop;}/*** @param isInfiniteLoop the isInfiniteLoop to set*/public ImagePagerAdapter setInfiniteLoop(boolean isInfiniteLoop) {this.isInfiniteLoop = isInfiniteLoop;return this;}@Overridepublic Object getItem(int arg0) {// TODO Auto-generated method stubreturn arg0;}@Overridepublic long getItemId(int arg0) {// TODO Auto-generated method stubreturn arg0;}}
private ViewFlow mViewFlow;
private CircleFlowIndicator mFlowIndicator;
private ArrayList
private ArrayList
private LayoutInflater inflater;
private RelativeLayout layout;
private ImageView iv_close;
private Dialog dialogs;
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);BaseApplication.getApp().addActivity(this);initView();initData();
}
private void initView() {
inflater = LayoutInflater.from(MainActivity.this);
layout = (RelativeLayout) inflater.inflate(R.layout.activity_main_advertising, null);
iv_close = (ImageView) layout.findViewById(R.id.iv_close);
mViewFlow = (ViewFlow) layout.findViewById(R.id.viewflow);
mViewFlow.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView> parent, View view, int position, long id) {dialogs.dismiss();}
});
mFlowIndicator = (CircleFlowIndicator) layout.findViewById(R.id.viewflowindic);
iv_close.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {dialogs.dismiss();}
});
private void initData() {
linkUrlArray.add("http://www.baidu.com");
linkUrlArray.add("https://www.csdn.net/");
linkUrlArray.add("https://www.oschina.net/");imageUrlList.add("http://cn.bing.com/az/hprichbg/rb/Dongdaemun_ZH-CN10736487148_1920x1080.jpg");
imageUrlList.add("http://pic.people.com.cn/NMediaFile/2019/0610/MAIN201906101623000225736784754.jpg");
imageUrlList.add("http://www.gregscott.com/gjs_2007_spring/hummingbird/20070311_1948_100_0560.rufous_humminbird.jpg");
initBanner(imageUrlList);
}/*** @param imageUrlList 广告图片url list*/
private void initBanner(ArrayList
}