当前位置: 移动技术网 > IT编程>移动开发>Android > Android仿京东首页画轴效果

Android仿京东首页画轴效果

2019年07月24日  | 移动技术网IT编程  | 我要评论

轻纺城汽车站,陕西一套,ug6.0下载

记得之前京东首页有一个效果,有一个画轴,然后可以滚动画轴,去打开画(不知道怎么去形容这个效果,就叫做画轴效果吧- -!),然后去做相关操作,刚开始看到这个效果,想法是动态的去改变一个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高度时可能出现绘制速度赶不上滚动的速度,会出现错位,当然时间设置太短,也看不到这种滑动的效果了.暂时想到的做法就是这样,应该还会有更好的方法.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网