美文网首页成长中的Android我爱编程
一个简单的图片滑动展示控件

一个简单的图片滑动展示控件

作者: flychen11 | 来源:发表于2018-04-17 10:38 被阅读0次

  首先声明本人Android新人一枚,这是本人第一篇博客,用于对自己知识的巩固,同时把自己写的东西分享出来,希望能帮到有需要的人。

      今天朋友需要一个图片滑动展示的控件,要求图片折叠时除第一张图片,其他都只保留底部一部分可见,可上下滑动展示。

      先讲讲我的思路,本来想用RecyclerView配合隐藏图片来完成的,可是后来一想这样适配性太差,只能用于已知图片数量的情况,于是我决定写一个自定义控件来完成这个需求。这个控件里面最重要的就是控件的大小,绘制图片,控件中图片滑动响应,处理父控件滑动事件的屏蔽。

      首先控大小,我们通过重写onMeasure方法来完成,

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    if (infoList.size() ==0) {

setMeasuredDimension(pWidth, bHeight);//设置控件宽高

    }else {

setMeasuredDimension(pWidth, bHeight +infoList.get(infoList.size() -1).hightTop);//设置控件宽高

    }

}

宽度直接是使用的屏幕宽度,高度我设置了一个默认图片,以这个默认图片的高度bHeight来计算,每多一张图片高度就增加bHeight/4,由于需要对滑动后的控件大小进行改变,我这边用的最后一张图片顶部高度来计算控件高度,效果是一致的。

ViewGroup.LayoutParams layoutParams =this.getLayoutParams();

layoutParams.height =bHeight +infoList.get(infoList.size() -1).hightTop;

this.setLayoutParams(layoutParams);

invalidate();

这是我对滑动后控件大小进行改变的操作。

完成控件大小的设置,就要来绘制图片了,这个我们在onDraw中进行处理,

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

    Rect srcRect =new Rect(0, 0, pWidth, bHeight);//要绘制的bitmap 区域

    if (list.size() ==0) {

Rect destRect =new Rect(0, 0, pWidth, bHeight);//要将bitmap 绘制在屏幕的什么地方

        canvas.drawBitmap(bitmap, srcRect, destRect, paint);

    }else {

for (int i =list.size() -1; i >=0; i--) {

BitmapInfo bitmapInfo =infoList.get(i);

            Rect destRect =new Rect(bitmapInfo.widthLeft, bitmapInfo.hightTop, bitmapInfo.widthRight, bitmapInfo.hightTop +bHeight);//要将bitmap 绘制在屏幕的什么地方

            canvas.drawBitmap(list.get(i), srcRect, destRect, paint);

        }

}

}

接下来就要处理控件中图片滑动的响应了,首先重写onTouchEvent方法来对手势进行监听,

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN://按下

            getParent().requestDisallowInterceptTouchEvent(true);//屏蔽父类的事件屏蔽

            down_y = (int) event.getY();

break;

        case MotionEvent.ACTION_UP://抬起

            oldy =0;

break;

        case MotionEvent.ACTION_MOVE://移动

            getParent().requestDisallowInterceptTouchEvent(true);//屏蔽父类的事件屏蔽

            moveImageView((int) (event.getY() -down_y));

break;

    }

return true;

}

分别对手指按下,抬起,移动进行了处理,按下时获取手指坐标,移动时获取坐标,计算出移动距离,并对图片进行移动,最后返回true,表示在手势完成后,不会再发送给父类进行处理了。

private void moveImageView(int y) {

if (infoList.size() ==0) {

return;

    }

if (y <0) {//向上滑动

        for (int i =0; i

BitmapInfo bitmapInfo =infoList.get(i);

            if (i ==0) {

if (bitmapInfo.hightTop > (-infoList.size() +1) *bHeight) {

bitmapInfo.setHightTop(bitmapInfo.hightTop + y -oldy);

                    if (bitmapInfo.hightTop < (-infoList.size() +1) *bHeight) {

bitmapInfo.setHightTop((-infoList.size() +1) *bHeight);

                    }

}

}else {

BitmapInfo lastBitmapInfo =infoList.get(i -1);

                if (bitmapInfo.hightTop > (-infoList.size() + i +1) *bHeight && lastBitmapInfo.hightTop <= -(4 - i) *bHeight /4) {

bitmapInfo.setHightTop(bitmapInfo.hightTop + y -oldy);

                    if (bitmapInfo.hightTop < (-infoList.size() + i +1) *bHeight) {

bitmapInfo.setHightTop((-infoList.size() + i +1) *bHeight);

                    }

}

}

}

}else {//向下滑动

        for (int i =list.size() -1; i >=0; i--) {

BitmapInfo bitmapInfo =infoList.get(i);

            if (bitmapInfo.hightTop < i *bHeight /4) {

bitmapInfo.setHightTop(bitmapInfo.hightTop + y -oldy);

                if (bitmapInfo.hightTop > i *bHeight /4) {

bitmapInfo.setHightTop(i *bHeight /4);

                }

}

}

}

oldy = y;

    ViewGroup.LayoutParams layoutParams =this.getLayoutParams();

    layoutParams.height =bHeight +infoList.get(infoList.size() -1).hightTop;

    this.setLayoutParams(layoutParams);

    invalidate();

}

由于在移动图片是会用到上一步移动的距离oldy,所以在抬起手指的手势处理中多oldy进行初始化,为了更好的处理图片移动时,位置的变化,我用了一个内部bean类来记录图片的位置信息,

private class BitmapInfo {

private int widthLeft;

    private int hightTop;

    private int widthRight;

    private int hightBottom;

    BitmapInfo(int widthLeft, int hightTop, int widthRight, int hightBottom) {

this.widthLeft = widthLeft;

        this.hightTop = hightTop;

        this.widthRight = widthRight;

        this.hightBottom = hightBottom;

    }

void setHightTop(int hightTop) {

this.hightTop = hightTop;

    }

}

到这里控件其实已经完成了,不过在我们把控件放到ScrollView中时,我们会发现我们的图片滑动不了,我们的手指触摸事件被ScrollView屏蔽了,这里我们就要在对应的触摸事件中队父控件的屏蔽事件进行屏蔽,

getParent().requestDisallowInterceptTouchEvent(true);//屏蔽父类的事件屏蔽

,到这里整个控件就大功告成了。

总结:这是一个很简单的控件,没有花哨的效果,这里面会用到Android自定义控件及事件分发机制的知识。

这边是源码:https://github.com/flychen11/MySlideImageView.git

相关文章

  • 一个简单的图片滑动展示控件

    首先声明本人Android新人一枚,这是本人第一篇博客,用于对自己知识的巩固,同时把自己写的东西分享出来,希望能...

  • PageView学习

    PageView控件可以实现一个“图片轮播”的效果,PageView不仅可以水平滑动也可以垂直滑动,简单用法如下:...

  • 开源一个网络图片浏览器HooPhotoBrowser

    在公司开发项目中需要弹出展示从网络上下载的图片,并提供滑动展示功能。目前采用同事开发的图片浏览器,但还有优化的控件...

  • 38-Swift之UIScrollView

    一 、 UIScrollView 的介绍 UIScrollView 是一个用于滑动展示的控件。 二、 UIScro...

  • Android 多点触控与图片缩放

    ScaleImageview 一个图片缩放控件,支持在viewpager等滑动控件中使用 文章讲解如下:Andro...

  • 安卓开发中Gallery控件的使用

    本文将介绍Gallery控件的简单使用,Gallery控件用于灵活展示图片。先附上我的布局文件: 接下来,我们需要...

  • Qt滑块图片验证码

    Qt滑块图片验证码 @[toc] (一)、控件介绍 自定义随机图片 滑动条滑动验证 重定义验证图片 抠图位置随机 ...

  • Android九宫格

    Android九宫格图片展示控件 简单说下NineGridLayout的实现吧,NineGridLayout继承的...

  • QQ空间之个性化可拉伸界面

    qq空间页面的可拉伸效果,主要在于上下滑动的时候,怎么实现导航栏的颜色变化和图片尺寸的变化 效果展示: 控件结构 ...

  • 自定义View之九宫格图片展示控件

    NineImageView 一个简单实用的九宫格图片展示控件 导入 说明 自定义属性 名称格式说明nineImag...

网友评论

    本文标题:一个简单的图片滑动展示控件

    本文链接:https://www.haomeiwen.com/subject/zfdukftx.html