Android仿京东首页画轴效果
记得之前京东首页有一个效果,有一个画轴,然后可以滚动画轴,去打开画(不知道怎么去形容这个效果,就叫做画轴效果吧- -!),然后去做相关操作,刚开始看到这个效果,想法是动态的去改变一个imageview的高度,基本效果也就出来了,不过滚动部分的内容,当时接触的也不是很多,只是看过一些大牛的博客,略微了解了一点,当时也忙着写项目,也就没去多想,前些天忽然想到这个效果,就想着实现一下,不过京东新版本好像去掉这个东西了,只能凭着自己的记忆来大概搞一下,也是对滑动这部分内容的一个小练习吧.
先看一下效果图:
一、需求分析
看到效果之后,先来分析一下:
首先是需要一个可以滑动的画轴,并且这个画轴需要一定的滑动空间,有滑动的效果,这个用scroller帮助完成就可以了.
然后看一下画轴点击移动时候的背景图,是跟随画轴移动,动态改变高度的.这个用一个imageview来搞定,设置imageview的scaletype就可以了,不过这个地方有一些小问题,下面会说.
二、具体实现
简单分析完,来实现一下,先来做一下画轴.创建一个scrollpaintview继承自relativelayout,因为需要一定的滑动空间,所以需要是一个viewgroup.
scrollpaintview的一些基本属性:
public class scrollpaintview extends relativelayout { /** * tag */ private static final string tag = "scrollpaintview"; /** * 默认滚轴高度 */ private final int default_paint_scroll_height = 25; /** * 默认滚动的速度 */ private final int default_scroll_speed = 1000; /** * 默认分割点高度 */ private final int default_partition_node = 150; /** * 默认画轴文字大小 */ private final int default_paint_scroll_txt_size = 16; /** * scroller */ private scroller mscroller; /** * 滚轴iv */ private imageview mpaintscrollimageview; /** * 滚轴tv */ private textview mpaintscrolltextview; /** * 图画iv */ private imageview mpaintview; /** * 画轴图 */ private bitmap mpaintscrollbp; /** * 画轴高度 */ private int mpaintivheight; /** * 画轴文字 */ private string mpaintscrolltxt; /** * 画轴文字大小 */ private float mpaintscrolltxtsize; /** * 画轴文字颜色 */ private int mpaintscrolltxtcolor; /** * 图画开始时的高度 */ private int mpaintstartheight; /** * 上一次获取的y */ private int mlasty; /** * 滚动速度 */ private int mscrollspeed; /** * 分隔节点 */ private int partitionnode; /** * 是否是向上滚动 */ private boolean isscrllertop = false; /** * 是否正在点击 */ private boolean isclick = false; /** * 布局参数 */ private layoutparams lpp; /** * 屏幕高度 */ private int screenheight; /** * 屏幕宽度 */ private int screenwidth; /** * 回调监听 */ private scrollpaintcompletelistener listener; /** * 上一次滚动的y值 */ private int lastscrolly; /** * 构造方法 */ public scrollpaintview(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); // 获取属性 typedarray ta = context.obtainstyledattributes(attrs, r.styleable.scrollpaintview); mpaintivheight = (int) ta.getdimension(r.styleable.scrollpaintview_paintscrollheight, typedvalue.applydimension( typedvalue.complex_unit_dip, default_paint_scroll_height, getresources().getdisplaymetrics())); mscrollspeed = ta.getinteger(r.styleable.scrollpaintview_scrollspeed, default_scroll_speed); partitionnode = ta.getinteger(r.styleable.scrollpaintview_scrollpartitionnode, default_partition_node); mpaintscrollbp = drawabletobitamp(ta.getdrawable(r.styleable.scrollpaintview_paintscrollsrc)); mpaintscrolltxt = ta.getstring(r.styleable.scrollpaintview_paintscrolltxt); mpaintscrolltxtcolor = ta.getcolor(r.styleable.scrollpaintview_paintscrolltxtcolor, color.black); mpaintscrolltxtsize = px2sp(ta.getdimensionpixelsize(r.styleable.scrollpaintview_paintscrolltxtsize, default_paint_scroll_txt_size)); ta.recycle(); } }
看一下创建画轴:
/** * 创建滚轴 */ private void makepaintscroll() { // 如果已经存在,则不再创建 if (null != mpaintscrollimageview || null != mpaintscrolltextview) { return; } // 创建滚轴 mpaintscrollimageview = new imageview(getcontext()); layoutparams lp = new layoutparams(layoutparams.match_parent, layoutparams.match_parent); lp.height = mpaintivheight; mpaintscrollimageview.setlayoutparams(lp); mpaintscrollimageview.setscaletype(imageview.scaletype.fit_xy); mpaintscrollimageview.setimagebitmap(null == mpaintscrollbp ? makedefaultscroll() : mpaintscrollbp); addview(mpaintscrollimageview); // 创建文字 mpaintscrolltextview = new textview(getcontext()); layoutparams lpt = new layoutparams(layoutparams.match_parent, layoutparams.match_parent); lpt.height = mpaintivheight; mpaintscrolltextview.setlayoutparams(lpt); mpaintscrolltextview.settext(null == mpaintscrolltxt ? "" : mpaintscrolltxt); mpaintscrolltextview.settextsize(mpaintscrolltxtsize); mpaintscrolltextview.settextcolor(mpaintscrolltxtcolor); mpaintscrolltextview.setgravity(gravity.center); addview(mpaintscrolltextview); } /** * 设置默认的滚轴 * * @return */ private bitmap makedefaultscroll() { bitmap defaultbp = bitmap.createbitmap(screenwidth, mpaintivheight, bitmap.config.argb_8888); //填充颜色 defaultbp.erasecolor(color.parsecolor("#ff0000")); return defaultbp; }
创建了一个画轴imageview和一个文字textview作为初始的画轴,如果没有传入画轴的图片,则默认去创建一个画轴.不难理解,接着去配合scroller,让画轴滚动起来.
简单滚动:
/** * 处理view */ private void handleview() { // 初始化scroller mscroller = new scroller(getcontext()); // 画轴点击效果 mpaintscrollimageview.setontouchlistener(new ontouchlistener() { @override public boolean ontouch(view view, motionevent event) { int x = (int) event.getrawx(); int y = (int) event.getrawy(); int action = event.getaction(); switch (action) { case motionevent.action_down: isclick = true; mlasty = y; if (!mscroller.isfinished()) { // 如果上次的调用没有执行完就取消。 mscroller.abortanimation(); } return true; case motionevent.action_move: // 移动的距离 int dy = y - mlasty; mlasty = y; // 滑动 scrollby(0, -dy); return true; case motionevent.action_up: mscroller.startscroll(getscrollx(), getscrolly(), -getscrollx(), -getscrolly(), 1000); invalidate(); return true; } return false; } }); } /** * 滑动处理 */ @override public void computescroll() { if (mscroller.computescrolloffset()) { // 计算新位置,并判断上一个滚动是否完成。 scrollto(mscroller.getcurrx(), mscroller.getcurry()); invalidate(); } }
这样滑动处理就做完了,在布局中引用一下,看一下效果
activity_main:
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#eeeeee" tools:context="com.example.junweiliu.scrollpaintdemo.mainactivity"> <!--画轴控件--> <com.example.junweiliu.scrollpaintdemo.widget.scrollpaintview android:id="@+id/spv_paint" android:layout_width="match_parent" android:layout_height="match_parent" app:paintscrollheight="25dp" app:paintscrollsrc="@mipmap/paint_scroll_img" app:paintscrolltxt="拉我看看" app:paintscrolltxtcolor="#ff000000" app:paintscrolltxtsize="16sp" > </com.example.junweiliu.scrollpaintdemo.widget.scrollpaintview> </relativelayout>
效果图:
滚动条基本能用了,接着来设置一个imageview来配合使用下,先获取到一个imageview,然后拖动画轴时,来动态改变imageview的高度,在做这部分内容前,先来考虑下,因为需求需要的是图画整体不会变形,是一点一点拉开的感觉,就像是打开一幅画一样,那么用哪种scaletype能满足呢.试了好多种,来分别看一下:
相关代码:
提供一个设置imageview的方法
在motionevent.action_move:中动态改变imageview的高度
滑动时动态改变imageview的高度
/** * 设置paintview * * @param paintview */ public void setpaintview(imageview paintview) { if (null == paintview) { log.e(tag, "设置的view为空"); return; } mpaintview = paintview; }
motionevent.action_move:
// 滑动处理 case motionevent.action_move: ... // 动态改变高度 if (math.abs(getscrolly()) > 0) { lpp.height = mpaintstartheight + math.abs(getscrolly()); mpaintview.setlayoutparams(lpp); }
滑动处理:
/** * 滑动处理 */ @override public void computescroll() { if (mscroller.computescrolloffset()) { // 计算新位置,并判断上一个滚动是否完成。 // 请求处理点击事件,防止父控件滑动 requestdisallowintercepttouchevent(true); scrollto(mscroller.getcurrx(), mscroller.getcurry()); // 重新设置显示的控件高度 if (0 < math.abs(mscroller.getcurry())) { if (!isscrllertop) { lpp.height = mpaintstartheight + math.abs(mscroller.getcurry()) + mpaintivheight / 2; } else { lpp.height = mpaintstartheight + math.abs(mscroller.getcurry()) - mpaintivheight / 2; } } else { lpp.height = mpaintstartheight; } mpaintview.setlayoutparams(lpp); invalidate(); } }
设置不同scaletype效果,简单试几个效果:
fitxy:
centercrop:
matrix:
观察一下,好像那个效果都不是很好,不过matrix拉开的效果和预期需要的是一样的,不过用matrix之后,就没有办法设置其他scaletype了,没办法把图片进行缩放了,这肿么办呢,其实很简单,只需要把显示的图片提前进行一下缩放就可以了.
处理图片相关:
/** * 设置paintview * * @param paintview */ public void setpaintview(imageview paintview) { if (null == paintview) { log.e(tag, "设置的view为空"); return; } // 处理图片,对图片按照屏幕宽高比进行缩放 bitmap bp = drawabletobitamp(paintview.getdrawable()); paintview.setimagebitmap(scalebitmal(bp)); // 设置缩放形式 paintview.setscaletype(imageview.scaletype.matrix); mpaintview = paintview; } /** * drawable转bitmap * * @param drawable * @return */ private bitmap drawabletobitamp(drawable drawable) { if (null == drawable) { return null; } if (drawable instanceof bitmapdrawable) { bitmapdrawable bd = (bitmapdrawable) drawable; return bd.getbitmap(); } int w = drawable.getintrinsicwidth(); int h = drawable.getintrinsicheight(); bitmap bitmap = bitmap.createbitmap(w, h, bitmap.config.argb_8888); canvas canvas = new canvas(bitmap); drawable.setbounds(0, 0, w, h); drawable.draw(canvas); return bitmap; } /** * 按照屏幕宽高缩放图片 * * @param bp * @return */ private bitmap scalebitmal(bitmap bp) { // 宽度比例 float scalew = (float) screenwidth / (float) bp.getwidth(); // 高度比例 float scaleh = (float) screenheight / (float) bp.getheight(); // 矩阵,用于缩放图片 matrix matrix = new matrix(); matrix.postscale(scalew, scaleh); // 缩放后的图片 bitmap scalebp = bitmap.createbitmap(bp, 0, 0, bp.getwidth(), bp.getheight(), matrix, true); return scalebp; }
看一下效果:
效果还不错,接下来就是做一下细节上的处理,设置一个临界点,让画轴向上或者向下滚动,设置边界点,让画轴不越界等等.还有一般都是在scrollview中使用到这个效果,所以要去处理一下事件冲突,当然还有去重写一下onmeasure方法,不然会出现不显示的情况.(相信大家也遇到过scrollview里边嵌套listview导致listview显示不全)这里就不再详细介绍了.直接贴下代码.
三、完整代码
mainactivity:
package com.example.junweiliu.scrollpaintdemo; import android.content.intent; import android.os.bundle; import android.os.handler; import android.os.message; import android.support.v7.app.appcompatactivity; import android.view.view; import android.widget.imageview; import android.widget.textview; import android.widget.toast; import com.example.junweiliu.scrollpaintdemo.widget.scrollpaintview; public class mainactivity extends appcompatactivity { private static final string tag = "mainactivity"; /** * 需要显示的iv */ private imageview mpaintiv; /** * 画轴 */ private scrollpaintview mscrollpaintview; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); initview(); } /** * 初始化控件 */ private void initview() { mpaintiv = (imageview) findviewbyid(r.id.iv_paint); mscrollpaintview = (scrollpaintview) findviewbyid(r.id.spv_paint); mscrollpaintview.setpaintview(mpaintiv); mpaintiv.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { toast.maketext(mainactivity.this, "功夫!", toast.length_short).show(); } }); mscrollpaintview.setscrollpaintcompletelistener(new scrollpaintview.scrollpaintcompletelistener() { @override public void onscrolltouch(textview tv) { mpaintiv.setvisibility(view.visible); } @override public void onscrolltop(textview tv) { // log.e(tag, "收缩了"); tv.settext("拉我看看"); if (view.visible == mpaintiv.getvisibility()) { mpaintiv.setvisibility(view.gone); } } @override public void onscrollbottom(textview tv) { // log.e(tag, "展开了"); tv.settext("到底了"); intent intent = new intent(mainactivity.this, detailactivity.class); startactivity(intent); // 延迟800毫秒重置位置 new handler(new handler.callback() { @override public boolean handlemessage(message message) { mscrollpaintview.replacescroll(); return false; } }).sendemptymessagedelayed(0, 600); } @override public void onscrollmove(textview tv) { // log.e(tag, "移动了"); tv.settext("请上下拖动"); } }); } }
scrollpaintview:
package com.example.junweiliu.scrollpaintdemo.widget; import android.app.activity; import android.content.context; import android.content.res.typedarray; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.color; import android.graphics.matrix; import android.graphics.rect; import android.graphics.drawable.bitmapdrawable; import android.graphics.drawable.drawable; import android.util.attributeset; import android.util.displaymetrics; import android.util.log; import android.util.typedvalue; import android.view.gravity; import android.view.motionevent; import android.view.view; import android.widget.imageview; import android.widget.relativelayout; import android.widget.scroller; import android.widget.textview; import com.example.junweiliu.scrollpaintdemo.r; /** * created by junweiliu on 16/12/10. */ public class scrollpaintview extends relativelayout { /** * tag */ private static final string tag = "scrollpaintview"; /** * 默认滚轴高度 */ private final int default_paint_scroll_height = 25; /** * 默认滚动的速度 */ private final int default_scroll_speed = 1000; /** * 默认分割点高度 */ private final int default_partition_node = 150; /** * 默认画轴文字大小 */ private final int default_paint_scroll_txt_size = 16; /** * scroller */ private scroller mscroller; /** * 滚轴iv */ private imageview mpaintscrollimageview; /** * 滚轴tv */ private textview mpaintscrolltextview; /** * 图画iv */ private imageview mpaintview; /** * 画轴图 */ private bitmap mpaintscrollbp; /** * 画轴高度 */ private int mpaintivheight; /** * 画轴文字 */ private string mpaintscrolltxt; /** * 画轴文字大小 */ private float mpaintscrolltxtsize; /** * 画轴文字颜色 */ private int mpaintscrolltxtcolor; /** * 图画开始时的高度 */ private int mpaintstartheight; /** * 上一次获取的y */ private int mlasty; /** * 滚动速度 */ private int mscrollspeed; /** * 分隔节点 */ private int partitionnode; /** * 是否是向上滚动 */ private boolean isscrllertop = false; /** * 是否正在点击 */ private boolean isclick = false; /** * 布局参数 */ private layoutparams lpp; /** * 屏幕高度 */ private int screenheight; /** * 屏幕宽度 */ private int screenwidth; /** * 回调监听 */ private scrollpaintcompletelistener listener; /** * 上一次滚动的y值 */ private int lastscrolly; /** * 回调接口 */ public interface scrollpaintcompletelistener { /** * 点击时的回调 */ public void onscrolltouch(textview tv); /** * 收缩时的回调 */ public void onscrolltop(textview tv); /** * 展开时的回调 */ public void onscrollbottom(textview tv); /** * 滚动中的回调 */ public void onscrollmove(textview tv); } public scrollpaintview(context context) { this(context, null); } public scrollpaintview(context context, attributeset attrs) { this(context, attrs, 0); } public scrollpaintview(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); // 获取属性 typedarray ta = context.obtainstyledattributes(attrs, r.styleable.scrollpaintview); mpaintivheight = (int) ta.getdimension(r.styleable.scrollpaintview_paintscrollheight, typedvalue.applydimension( typedvalue.complex_unit_dip, default_paint_scroll_height, getresources().getdisplaymetrics())); mscrollspeed = ta.getinteger(r.styleable.scrollpaintview_scrollspeed, default_scroll_speed); partitionnode = ta.getinteger(r.styleable.scrollpaintview_scrollpartitionnode, default_partition_node); mpaintscrollbp = drawabletobitamp(ta.getdrawable(r.styleable.scrollpaintview_paintscrollsrc)); mpaintscrolltxt = ta.getstring(r.styleable.scrollpaintview_paintscrolltxt); mpaintscrolltxtcolor = ta.getcolor(r.styleable.scrollpaintview_paintscrolltxtcolor, color.black); mpaintscrolltxtsize = px2sp(ta.getdimensionpixelsize(r.styleable.scrollpaintview_paintscrolltxtsize, default_paint_scroll_txt_size)); ta.recycle(); init(); makepaintscroll(); handleview(); } /** * 设置paintview * * @param paintview */ public void setpaintview(imageview paintview) { if (null == paintview) { log.e(tag, "设置的view为空"); return; } // 处理图片,对图片按照屏幕宽高比进行缩放 bitmap bp = drawabletobitamp(paintview.getdrawable()); paintview.setimagebitmap(scalebitmal(bp)); // 设置缩放形式 paintview.setscaletype(imageview.scaletype.matrix); mpaintview = paintview; } /** * 设置回调 */ public void setscrollpaintcompletelistener(scrollpaintcompletelistener listener) { if (null != listener) { this.listener = listener; } } /** * 初始化 */ private void init() { mscroller = new scroller(getcontext()); lpp = new layoutparams(layoutparams.match_parent, layoutparams.match_parent); // 获取屏幕信息 displaymetrics displaymetrics = new displaymetrics(); ((activity) getcontext()).getwindowmanager().getdefaultdisplay() .getmetrics(displaymetrics); // 屏幕高度 screenheight = displaymetrics.heightpixels; // 屏幕宽度 screenwidth = displaymetrics.widthpixels; } /** * 创建滚轴 */ private void makepaintscroll() { // 如果已经存在,则不再创建 if (null != mpaintscrollimageview || null != mpaintscrolltextview) { return; } // 创建滚轴 mpaintscrollimageview = new imageview(getcontext()); layoutparams lp = new layoutparams(layoutparams.match_parent, layoutparams.match_parent); lp.height = mpaintivheight; mpaintscrollimageview.setlayoutparams(lp); mpaintscrollimageview.setscaletype(imageview.scaletype.fit_xy); mpaintscrollimageview.setimagebitmap(null == mpaintscrollbp ? makedefaultscroll() : mpaintscrollbp); addview(mpaintscrollimageview); // 创建文字 mpaintscrolltextview = new textview(getcontext()); layoutparams lpt = new layoutparams(layoutparams.match_parent, layoutparams.match_parent); lpt.height = mpaintivheight; mpaintscrolltextview.setlayoutparams(lpt); mpaintscrolltextview.settext(null == mpaintscrolltxt ? "" : mpaintscrolltxt); mpaintscrolltextview.settextsize(mpaintscrolltxtsize); mpaintscrolltextview.settextcolor(mpaintscrolltxtcolor); mpaintscrolltextview.setgravity(gravity.center); addview(mpaintscrolltextview); } /** * 测量方法 * * @param widthmeasurespec * @param heightmeasurespec */ @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); if (null != mpaintview && gettop() + mpaintivheight != mpaintview.getheight()) { // 重新设置图画高度 mpaintstartheight = gettop() + mpaintivheight / 2; lpp.height = mpaintstartheight; mpaintview.setlayoutparams(lpp); } // 测量状态栏高度 rect frame = new rect(); ((activity) getcontext()).getwindow().getdecorview().getwindowvisibledisplayframe(frame); int statusbarheight = frame.top; // 高度为屏幕高度减去状态栏高度和top的高度 setmeasureddimension(screenwidth, screenheight - gettop() - statusbarheight); } /** * 处理view */ private void handleview() { mpaintscrollimageview.setontouchlistener(new ontouchlistener() { @override public boolean ontouch(view view, motionevent event) { if (null == mpaintview) { log.e(tag, "设置的view为空"); return true; } // 获取点击的xy坐标 int x = (int) event.getrawx(); int y = (int) event.getrawy(); int action = event.getaction(); switch (action) { case motionevent.action_down: { // 请求处理点击事件 requestdisallowintercepttouchevent(true); isclick = true; mlasty = y; if (!mscroller.isfinished()) { // 如果上次的调用没有执行完就取消。 mscroller.abortanimation(); } if (null != listener) { listener.onscrolltouch(mpaintscrolltextview); } return true; } case motionevent.action_move: { // 移动的距离 int dy = y - mlasty; mlasty = y; // 滑动 scrollby(0, -dy); // 如果是向上滑动并且是在初始位置,则不去做处理 if (getscrolly() >= 0 && dy <= 0) { lpp.height = mpaintstartheight; mpaintview.setlayoutparams(lpp); scrollto(0, 0); return true; } // 如果是向下滑动并且超过屏幕高度,则不去处理 if (math.abs(getscrolly()) >= getheight() - mpaintivheight && dy >= 0) { lpp.height = mpaintstartheight + getheight() - mpaintivheight; mpaintview.setlayoutparams(lpp); scrollto(0, -(getheight() - mpaintivheight)); return true; } // 滚动回调 if (null != listener) { listener.onscrollmove(mpaintscrolltextview); } // 重新设置显示的控件高度 if (math.abs(getscrolly()) > 0) { lpp.height = mpaintstartheight + math.abs(getscrolly()); mpaintview.setlayoutparams(lpp); } return true; } case motionevent.action_up: // 恢复事件处理 requestdisallowintercepttouchevent(false); isclick = false; // 没有发生移动 if (getscrolly() >= 0) { if (null != listener) { listener.onscrolltop(mpaintscrolltextview); } return true; } if (-getscrolly() < partitionnode) { // 如果小于临界值,则返回起始坐标 // xy都从滑动的距离回去,最后一个参数是多少毫秒内执行完这个动作。 isscrllertop = true; mscroller.startscroll(getscrollx(), getscrolly(), -getscrollx(), -getscrolly(), mscrollspeed); } else { // 如果大于临界值,则展开 isscrllertop = false; mscroller.startscroll(getscrollx(), getscrolly(), -getscrollx(), -(getheight() - (-getscrolly()) - mpaintivheight), mscrollspeed); } invalidate(); return true; } return false; } }); } /** * 滑动处理 */ @override public void computescroll() { if (mscroller.computescrolloffset()) { // 计算新位置,并判断上一个滚动是否完成。 // 请求处理点击事件,防止父控件滑动 requestdisallowintercepttouchevent(true); scrollto(mscroller.getcurrx(), mscroller.getcurry()); // 重新设置显示的控件高度 if (0 < math.abs(mscroller.getcurry())) { if (!isscrllertop) { lpp.height = mpaintstartheight + math.abs(mscroller.getcurry()) + mpaintivheight / 2; } else { lpp.height = mpaintstartheight + math.abs(mscroller.getcurry()) - mpaintivheight / 2; } } else { lpp.height = mpaintstartheight; } mpaintview.setlayoutparams(lpp); invalidate(); } else { // 重新设置画图高度,防止高度异常 if (mpaintview.getheight() > mpaintstartheight + math.abs(mscroller.getcurry()) && !isscrllertop && mscroller.getstarty() > 0) { lpp.height = mpaintstartheight + math.abs(mscroller.getcurry()); mpaintview.setlayoutparams(lpp); } } // 防止多次调用 if (lastscrolly != mscroller.getcurry()) { // 收缩完成 if (mscroller.getcurry() >= 0 && !isclick) { if (null != listener) { listener.onscrolltop(mpaintscrolltextview); } } // 展开完成 if (-mscroller.getcurry() >= getheight() - mpaintivheight && !isclick) { if (null != listener) { listener.onscrollbottom(mpaintscrolltextview); } } lastscrolly = mscroller.getcurry(); } } /** * 重置滚动 */ public void replacescroll() { // 重置信息 scrollto(0, 0); mscroller.setfinaly(0); lastscrolly = 0; lpp.height = mpaintstartheight; mpaintview.setlayoutparams(lpp); if (null != listener) { listener.onscrolltop(mpaintscrolltextview); } } /** * drawable转bitmap * * @param drawable * @return */ private bitmap drawabletobitamp(drawable drawable) { if (null == drawable) { return null; } if (drawable instanceof bitmapdrawable) { bitmapdrawable bd = (bitmapdrawable) drawable; return bd.getbitmap(); } int w = drawable.getintrinsicwidth(); int h = drawable.getintrinsicheight(); bitmap bitmap = bitmap.createbitmap(w, h, bitmap.config.argb_8888); canvas canvas = new canvas(bitmap); drawable.setbounds(0, 0, w, h); drawable.draw(canvas); return bitmap; } /** * 按照屏幕宽高缩放图片 * * @param bp * @return */ private bitmap scalebitmal(bitmap bp) { // 宽度比例 float scalew = (float) screenwidth / (float) bp.getwidth(); // 高度比例 float scaleh = (float) screenheight / (float) bp.getheight(); // 矩阵,用于缩放图片 matrix matrix = new matrix(); matrix.postscale(scalew, scaleh); // 缩放后的图片 bitmap scalebp = bitmap.createbitmap(bp, 0, 0, bp.getwidth(), bp.getheight(), matrix, true); return scalebp; } /** * 设置默认的滚轴 * * @return */ private bitmap makedefaultscroll() { bitmap defaultbp = bitmap.createbitmap(screenwidth, mpaintivheight, bitmap.config.argb_8888); //填充颜色 defaultbp.erasecolor(color.parsecolor("#ff0000")); return defaultbp; } /** * 将px值转换为sp值,保证文字大小不变 */ public int px2sp(float pxvalue) { final float fontscale = getcontext().getresources().getdisplaymetrics().scaleddensity; return (int) (pxvalue / fontscale + 0.5f); } }
activity_main:
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#eeeeee" tools:context="com.example.junweiliu.scrollpaintdemo.mainactivity"> <scrollview android:layout_width="match_parent" android:layout_height="match_parent"> <relativelayout android:layout_width="match_parent" android:layout_height="match_parent"> <!--头部图片部分--> <imageview android:id="@+id/iv_banner" android:layout_width="match_parent" android:layout_height="200dp" android:scaletype="fitxy" android:src="@mipmap/show_banner"/> <!--中间内容部分--> <linearlayout android:id="@+id/ll_first" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/iv_banner" android:layout_margintop="20dp" android:orientation="horizontal" android:padding="16dp"> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_a"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="艺术片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_b"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="怀旧片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_c"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="科幻片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_d"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="动画片" android:textcolor="#666666"/> </linearlayout> </linearlayout> <linearlayout android:id="@+id/ll_sencond" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/ll_first" android:layout_margintop="20dp" android:orientation="horizontal" android:padding="16dp"> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_a"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="艺术片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_b"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="怀旧片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_c"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="科幻片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_d"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="动画片" android:textcolor="#666666"/> </linearlayout> </linearlayout> <linearlayout android:id="@+id/ll_threeth" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/ll_sencond" android:layout_margintop="20dp" android:orientation="horizontal" android:padding="16dp"> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_a"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="艺术片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_b"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="怀旧片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_c"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="科幻片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_d"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="动画片" android:textcolor="#666666"/> </linearlayout> </linearlayout> <linearlayout android:id="@+id/ll_fourth" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/ll_threeth" android:layout_margintop="20dp" android:orientation="horizontal" android:padding="16dp"> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_a"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="艺术片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_b"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="怀旧片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginright="16dp" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_c"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="科幻片" android:textcolor="#666666"/> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <imageview android:layout_width="80dp" android:layout_height="120dp" android:scaletype="fitxy" android:src="@mipmap/movie_playbill_d"/> <textview android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:gravity="center" android:text="动画片" android:textcolor="#666666"/> </linearlayout> </linearlayout> <!--需要显示的图--> <imageview android:id="@+id/iv_paint" android:layout_width="match_parent" android:layout_height="match_parent" android:scaletype="matrix" android:src="@mipmap/show_img" android:visibility="gone"/> <!--画轴控件--> <com.example.junweiliu.scrollpaintdemo.widget.scrollpaintview android:id="@+id/spv_paint" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/iv_banner" app:paintscrollheight="25dp" app:paintscrollsrc="@mipmap/paint_scroll_img" app:paintscrolltxt="拉我看看" app:paintscrolltxtcolor="#ff000000" app:paintscrolltxtsize="16sp" > </com.example.junweiliu.scrollpaintdemo.widget.scrollpaintview> </relativelayout> </scrollview> </relativelayout>
attr:
<?xml version="1.0" encoding="utf-8"?> <resources> <!--画轴的高度--> <attr name="paintscrollheight" format="dimension"/> <!--画轴的图片--> <attr name="paintscrollsrc" format="reference"/> <!--画轴文字--> <attr name="paintscrolltxt" format="string"/> <!--画轴文字颜色--> <attr name="paintscrolltxtcolor" format="color"/> <!--画轴文字大小--> <attr name="paintscrolltxtsize" format="dimension"/> <!--滚动速度--> <attr name="scrollspeed" format="integer"/> <!--分割节点--> <attr name="scrollpartitionnode" format="integer"/> <declare-styleable name="scrollpaintview"> <attr name="paintscrollheight"/> <attr name="paintscrollsrc"/> <attr name="paintscrolltxt"/> <attr name="paintscrolltxtcolor"/> <attr name="paintscrolltxtsize"/> <attr name="scrollspeed"/> <attr name="scrollpartitionnode"/> </declare-styleable> </resources>
四、问题
滚动的时间不宜设置太短,因为动态设置imageview高度时可能出现绘制速度赶不上滚动的速度,会出现错位,当然时间设置太短,也看不到这种滑动的效果了.暂时想到的做法就是这样,应该还会有更好的方法.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。