首先声明:
1,关于自定义的slideShowVeiw控件不是我的原创,我也不会原创,至于是哪位大神的我也不清楚,现在在这里小弟先谢谢您!
2,因为项目中要使用焦点图翻转,通常都要实现对应图片的监听事件,我拿到这个slideShowVeiw控件后,自己不会写对应的图片监听,百度了几天也没结果,最后还在控件的适配器中通过position来对图片监听,结果可想而知,点击一次焦点图,然后焦点图每翻转一次,下面的几张图片不用点了,因为他自己就激发了点击事件,原因我估计是翻转的时候position在切换,所以事件就激发了,在这里我也不知道用激发这个字准不准确,自己理解的。
3,slideShowVeiw控件没有用来监听图片翻转的监听器,我不知道,即使有我也看不懂,通常。。。算了我编不下去,直接上我实现图片监听的代码!
/**
* ViewPager实现的轮播图广告自定义视图,如京东首页的广告轮播图效果;
* 既支持自动轮播页面也支持手势滑动切换页面
*
*
*/
public class SlideShowView111 extends FrameLayout implements View.OnClickListener {
/*自定义的焦点图添加Item监听事件,思路写个接口,创建回调方法*/
/*
* 步骤: 1 写个接口 该接口声明一个onClick方法
* 2对外爆出一个监听的调用的方法
*
*
* */
// 使用universal-image-loader插件读取网络图片,需要工程导入universal-image-loader-1.8.6-with-sources.jar
// private ImageLoader imageLoader = ImageLoader.getInstance();
// private BitmapUtils bitmapUtils;
//轮播图图片数量
private final static int IMAGE_COUNT = 4;
//自动轮播的时间间隔
private final static int TIME_INTERVAL = 5;
//自动轮播启用开关
private final static boolean isAutoPlay = false;
//跳转监听器
private OnClickListener goListener;
//自定义轮播图的资源
private String[] imageUrls;
// private int[] imageSrcs;
//放轮播图片的ImageView 的list
private List<ImageView> imageViewsList;
//放圆点的View的list
private List<View> dotViewsList;
private ViewPager viewPager;
//当前轮播页
private int currentItem = 0;
//定时任务
private ScheduledExecutorService scheduledExecutorService;
private Context context;
//Handler
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
viewPager.setCurrentItem(currentItem);
}
};
public SlideShowView111(Context context) {
this(context,null);
}
public SlideShowView111(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SlideShowView111(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (!isInEditMode()) {
this.context = context;
initData();
// 一步任务获取图片
new GetListTask().execute("");
if(isAutoPlay){
startPlay();
}
}
}
/**
* 开始轮播图切换
*/
public void startPlay(){
if (scheduledExecutorService==null) {
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(new SlideShowTask(), 4, 4, TimeUnit.SECONDS);
}
}
/**
* 停止轮播图切换
*/
private void stopPlay(){
scheduledExecutorService.shutdown();
}
/**
* 初始化相关Data
*/
private void initData(){
imageViewsList = new ArrayList<ImageView>();
dotViewsList = new ArrayList<View>();
}
@Override
public void onClick(View v) {
int a=v.getId();
switch (a){
case -1:
Toast.makeText(getContext(),"你摸了1",Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(getContext(),"你摸了2",Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(getContext(),"你摸了3",Toast.LENGTH_SHORT).show();
break;
case 3:
Toast.makeText(getContext(),"你摸了4",Toast.LENGTH_SHORT).show();
break;
case 4:
Toast.makeText(getContext(),"你摸了5",Toast.LENGTH_SHORT).show();
break;
case 5:
Toast.makeText(getContext(),"你摸了6",Toast.LENGTH_SHORT).show();
break;
case 6:
Toast.makeText(getContext(),"你摸了7",Toast.LENGTH_SHORT).show();
break;
default:
Toast.makeText(getContext(),"你摸了qita",Toast.LENGTH_SHORT).show();
}
}
/**
* 初始化Views等UI
*/
private void initUI(Context context){
if(imageUrls == null || imageUrls.length == 0)
return;
LayoutInflater.from(context).inflate(R.layout.layout_slideshow, this, true);
//viewPage的item布局
LinearLayout dotLayout = (LinearLayout)findViewById(R.id.dotLayout);//右下角的焦点布局
dotLayout.removeAllViews();
// 热点个数与图片特殊相等
for (int i = 0; i < imageUrls.length; i++) {
ImageView view = new ImageView(context);
view.setTag(imageUrls[i]);
view.setId(i);
// if(i==0)//给一个默认图
// view.setBackgroundResource(R.drawable.defalt);
view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
view.setOnClickListener(this);//后添加
// view.setScaleType(ScaleType.FIT_START);
//添加图片点击事件
// String urlStr = imageUrls[i];
imageViewsList.add(view);
ImageView dotView = new ImageView(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.leftMargin = 8;
params.rightMargin = 8;
dotLayout.addView(dotView, params);
dotViewsList.add(dotView);
}
/////////首次进入的时候初始化点点
for(int i=0;i < dotViewsList.size();i++){
if(i == 0){
((View)dotViewsList.get(0)).setBackgroundResource(R.drawable.shape_oval_dot_orage);
}else {
((View)dotViewsList.get(i)).setBackgroundResource(R.drawable.shape_oval_dot_dark);
}
}
//////////////////////////
if (imageViewsList.size()>0 && goListener!=null) {
imageViewsList.get(imageViewsList.size()-1).setOnClickListener(goListener);
}
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setFocusable(true);
viewPager.setAdapter(new MyPagerAdapter());
viewPager.setOnPageChangeListener(new MyPageChangeListener());
}
public void setOnGolistener(OnClickListener goListener) {
this.goListener = goListener;
}
/**
* 填充ViewPager的页面适配器
*
*/
private class MyPagerAdapter extends PagerAdapter {
@Override
//销毁多余的对象
public void destroyItem(View container, int position, Object object) {
// TODO Auto-generated method stub
//((ViewPag.er)container).removeView((View)object);
((ViewPager)container).removeView(imageViewsList.get(position));
}
@Override
/**
*
* 装填pager的方法,
* container:用来装填page的ViewPager对象
* position:装填过程中给每个pager的下标
* 返回的对象就是当前填充进去的pager对象
*
* 设置图片的监听事件
*
*/
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = imageViewsList.get(position);
if (!MyStrUtil.isEmpty(imageUrls)) {
//TODO load img
ImageOptions imageOptions = new ImageOptions.Builder()
// .setSize(DensityUtil.dip2px(120), DensityUtil.dip2px(120))
// .setRadius(DensityUtil.dip2px(5))
// 如果ImageView的大小不是定义为wrap_content, 不要crop.
.setCrop(true)
// 加载中或错误图片的ScaleType
//.setPlaceholderScaleType(ImageView.ScaleType.MATRIX)
.setImageScaleType(ImageView.ScaleType.CENTER_CROP)
// .setLoadingDrawableId(R.mipmap.ic_launcher)
// .setFailureDrawableId(R.mipmap.ic_launcher)
.build();
x.image().bind(imageView, imageView.getTag().toString(),imageOptions,new CustomBitmapLoadCallBack(imageView));
// bitmapUtils.display(imageView, imageView.getTag().toString());
}
imageView.setBackgroundResource(R.color.color_white);
container.addView(imageView);
return imageView;
}
@Override
//返回page的长度
public int getCount() {
// TODO Auto-generated method stub
return imageViewsList.size();
}
@Override
/*
判断instantiateItem(ViewGroup container, int position)
返回的要加载的pager对象是不是view视图,是则返回true并显示,不是返回false不显示。
*/
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1;
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
// TODO Auto-generated method stub
}
@Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}
@Override
public void startUpdate(View arg0) {
// TODO Auto-generated method stub
}
@Override
public void finishUpdate(View arg0) {
// TODO Auto-generated method stub
}
@Override
// 获取对应position的tab区域要显示的文字。
public CharSequence getPageTitle(int position) {
return super.getPageTitle(position);
}
}
/**
* ViewPager的监听器
* 当ViewPager中页面的状态发生改变时调用
*
*/
private class MyPageChangeListener implements OnPageChangeListener {
boolean isAutoPlay = false;
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
switch (arg0) {
case 1:// 手势滑动,空闲中
isAutoPlay = false;
break;
case 2:// 界面切换中
isAutoPlay = true;
break;
case 0:// 滑动结束,即切换完毕或者加载完毕
if (isAutoPlay) {
// 当前为最后一张,此时从右向左滑,则切换到第一张
if (viewPager.getCurrentItem() == viewPager.getAdapter().getCount() - 1 && !isAutoPlay) {
viewPager.setCurrentItem(0);
}
// 当前为第一张,此时从左向右滑,则切换到最后一张
else if (viewPager.getCurrentItem() == 0 && !isAutoPlay) {
viewPager.setCurrentItem(viewPager.getAdapter().getCount() - 1);
}
}
break;
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int pos) {
// TODO Auto-generated method stub
currentItem = pos;
for(int i=0;i < dotViewsList.size();i++){
if(i == pos){
((View)dotViewsList.get(pos)).setBackgroundResource(R.drawable.shape_oval_dot_orage);
}else {
((View)dotViewsList.get(i)).setBackgroundResource(R.drawable.shape_oval_dot_dark);
}
}
}
}
/**
*执行轮播图切换任务
*
*/
private class SlideShowTask implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (viewPager) {
currentItem = (currentItem+1)%imageViewsList.size();
handler.obtainMessage().sendToTarget();
}
}
}
/**
* 销毁ImageView资源,回收内存
*
*/
private void destoryBitmaps() {
for (int i = 0; i < IMAGE_COUNT; i++) {
ImageView imageView = imageViewsList.get(i);
Drawable drawable = imageView.getDrawable();
if (drawable != null) {
//解除drawable对view的引用
drawable.setCallback(null);
}
}
}
/**
* 释放资源,在activity结束时请调用
*/
public void destory() {
stopPlay();
destoryBitmaps();
}
public void setImageSrcs(int[] imageSrcs) {
if (MyStrUtil.isEmpty(imageSrcs)) {
return;
}
imageUrls = new String[imageSrcs.length];
for (int i = 0; i < imageSrcs.length; i++) {
imageUrls[i] = imageSrcs[i]+"";
}
}
public void setImageUrls(String[] imageUrls) {
this.imageUrls = imageUrls;
}
/**
* 异步任务,获取数据
*
*/
class GetListTask extends AsyncTask<String, Integer, Boolean> {
@Override
protected Boolean doInBackground(String... params) {
try {
// 这里一般调用服务端接口获取一组轮播图片,下面是从百度找的几个图片
// imageUrls = new String[]{
// “http://image.zcool.com.cn/59/54/m_1303967870670.jpg“,
// “http://image.zcool.com.cn/47/19/1280115949992.jpg“,
// “http://image.zcool.com.cn/59/11/m_1303967844788.jpg”
// };
// imageSrcs = new int[]{
// R.drawable.startup1,
// R.drawable.startup2,
// R.drawable.startup3
// };
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result) {
initUI(context);
}
}
}
}
看完代码是不是感觉没什么变化,确实,变化不大,下面是教你如何修改自己的SlideShowView代码:
1,让SlideShowView实现一个接口
该接口是:View.OnClickListener
我的代码中是:
public class SlideShowView extends FrameLayout implements View.OnClickListener
2,实现接口自然要实现该接口的方法
该接口需要实现的方法是:
@Override
public void onClick(View v){
}
这个方法里我们可以通过 参数 View v 从而获取view的id,
int a=v.getId();
然后再用switch(){
case 0:
Toast.makeText(getContext(),”你摸了1”,Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(getContext(),”你摸了1”,Toast.LENGTH_SHORT).show();
break;
default:
XXXXXXXXXXXXXXXXXXXXXXXXXXX
}
没错就在这个代码里实现对应翻转图片的监听
3,最重要的一步:
SlideShowView代码中少一句话:
这句话的作用是如果你不写,程序是不走public void onClick(View v)方法的,也就是说,你点击翻转的图片没有任何反应。
那么这句话就是:
view.setOnClickListener(this);
别问我这句话什么意思,我看不懂,知道干啥的就可以了!
这句话是我百度几天的成果之一。
这句话写在的位置是:
看矩形里面的代码,最后一个矩形就是该代码的位置。
4,最后最最重要的一句话千万不能不写!
如果这句话你不写,我们的焦点图在点击事件激发只会执行switch语句中的default:下面的代码,每一个图片都执行default语句,是不是很崩溃!
当时我很郁闷,这个为什么呢,不是说好的 这个v.getId()的方法值可以switch的么。这时都凌晨一点半了,算了,不看了,睡觉,明天到公司再看看原来另一个被弃用实现监听且翻转不利索的控件。
今早来到公司,我看了为什么每个图片的监听都执行default语句,原来v.getId()这个狗日的每次获取的值都是-1,没错,都是-1!而我的switch是从case 0:开始的。所以只执行default语句。
那么问题来了,我开始思考这个v.getId()是什么意思,确切说,我问了度娘。现在这个概念还模糊,
百度是这样说的:
***********************
在监听事件中想用ID来找到MAP中对应view的时候发现getid取的值永远是-1.
研究了下发现这里的getID一般是指的取你布局中设置的ID。如果 是代码中直接NEW出来的控件,他的geiid取的值是默认的-1.并非是内存中得id=345134512132之类的那个值。
收到了启发,我尝试写了这么一句话
view.setId(i);//后加
目的是给每个view设置指定的id,话又说回来不就是一个控件一个view,一个id,怎么还有多个id呢?我也不知道为啥,兄弟不容易,就凑合着用吧。
这句代码写在的位置:
在第3步我贴出图片中的代码189行。
最后感言:
0基础,没师傅,懂几句Java,自己搞Android,自己边学变带实习做项目, 我一直都是在网上看大神的代码,自己搞不出来,项目中各种拼接,我知道那种搞不出来的无奈,现在很高兴自己可以分享自己成果给业界的朋友,少走弯路,少点无奈。不管什么时候不放弃就是了,我们相信,用技术可以改变生活,也可以找到女票。坚持就是胜利。
最后希望有个业界师傅,感觉真的太需要了,因为又遇到一个问题,关于刷新请求网络解析json到recycleview,偶尔会出现闪退的现象。
这个是程序几次闪退报的异常:
java.lang.IndexOutOfBoundsException(越界异常): Inconsistency detected(不一致性检测).
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 191(offset:191).state:206
java.lang.IndexOutOfBoundsException: Invalid index 17, size is 1
我的逻辑是:
打开程序 检查本地是否有数据,
是,不请求网络,拿到本地json字符串,封装。通过适配器传递到Recycleview
不是,请求网路,获取数据接口字符串,封装。通过适配器传递到Recycleview
程序退出的时候在onDestroy() 方法中把数据写到data/data/files/路径下
刷新监听逻辑:
直接请求网络数据,解析~
现象:
新的数据出来了,但是在滑动的过程中,有时会出现闪退,或者关闭程序,再次打开,等会又瞬间闪退,闪退,这是死穴啊!
大神路过帮我给点建议,小弟先谢!
本文介绍了如何在Android的SlideShowView中添加图片点击监听。通过让SlideShowView实现View.OnClickListener接口,并在onClick方法中根据View的id进行处理,实现了不同图片的点击事件。关键步骤包括实现接口、设置监听以及处理点击事件。
2640

被折叠的 条评论
为什么被折叠?



