Android仿微博加载长图滚动查看效果

本文实例为大家分享了Android加载长图片的具体代码,供大家参考,具体内容如下

解决步骤

1.将图片缩放到与控件等宽
2.判断缩放后的图片高度,如果高度大于控件高度较多(这里设置的是1.5倍),认定为长图,可滑动查看图片
                     |-如果高度小于控件高度的1.5倍,以控件高度为基准,重新缩放图片

package org.wandcf_ces.fairproject.widgets; 

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View; 

/**
 * Created by sunrui on 2017/3/8.
 * 加载长图片
 * 解决步骤
 * 1.将图片缩放到与控件等宽
 * 2.判断缩放后的图片高度,如果高度大于控件高度较多(这里设置的是1.5倍),认定为长图,可滑动查看图片
 *           |-如果高度小于控件高度的1.5倍,以控件高度为基准,重新缩放图片
 *
 */
public class LongImageView extends View { 

  private int width, height; 

  //需要绘制的Bitmap
  private Bitmap bitmap; 

  /**
   * 需要绘制的图片的区域
   */
  private Rect srcRect; 

  /**
   * 绘制的区域
   */
  private RectF dstRectF; 

  /**
   * 画笔
   */
  private Paint paint; 

  /**
   * 是否需要滑动
   */
  private boolean isNeedSlide; 

  /**
   * 已经滑动过的距离
   */
  private float slideLength; 

  /**
   * 绘制的Bitmap
   */
  private Bitmap drawBitmap; 

  {
    srcRect = new Rect();
    dstRectF = new RectF();
    paint = new Paint();
    paint.setAntiAlias(true);
    paint.setColor(Color.BLACK);
    paint.setStrokeWidth(1.0f);
  } 

  public LongImageView(Context context) {
    super(context);
  } 

  public LongImageView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
  } 

  public LongImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  } 

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  public LongImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
  } 

  /**
   * 设置Bitmap
   *
   * @param bitmap
   *     需要绘制的Bitmap
   */
  public void setBitmap(Bitmap bitmap) {
    this.bitmap = bitmap;
  } 

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int specSize = MeasureSpec.getSize(widthMeasureSpec);
    width = getPaddingLeft() + getPaddingRight() + specSize;
    specSize = MeasureSpec.getSize(heightMeasureSpec);
    height = getPaddingTop() + getPaddingBottom() + specSize;
    if (drawBitmap == null) {
      drawBitmap = resizeImage(bitmap, width);
      if (drawBitmap.getHeight() > 1.5 * height) {
        //需要滑动
        setNeedSlide(true);
      } else {
        //不需要滑动
        setNeedSlide(false);
        srcRect.left = 0;
        srcRect.top = 0;
        srcRect.right = drawBitmap.getWidth();
        srcRect.bottom = drawBitmap.getHeight();
        if (drawBitmap.getHeight() > height) {
          drawBitmap = resizeImageH(drawBitmap, height - 20);
        } else {
          float space = (height - drawBitmap.getHeight());
          dstRectF.left = 0;
          dstRectF.top = space;
          dstRectF.right = width;
          dstRectF.bottom = height - space;
        }
      }
    }
    setMeasuredDimension(width, height);
  } 

  @Override
  protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(drawBitmap, (width - drawBitmap.getWidth()) / 2, slideLength, paint);
  } 

  /**
   * 设置是否需要滑动
   *
   * @param needSlide
   *     true or false
   */
  public void setNeedSlide(boolean needSlide) {
    isNeedSlide = needSlide;
  } 

  /**
   * 触摸操作的坐标
   */
  private float lastX;
  private float lastY; 

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if (!isNeedSlide) {
      return super.onTouchEvent(event);
    }
    int action = event.getAction();
    switch (action) {
      case MotionEvent.ACTION_DOWN:
        //按下
        lastX = event.getX();
        lastY = event.getY();
        break;
      case MotionEvent.ACTION_MOVE:
        float moveX = event.getX();
        if (moveX - lastX > 50) {
          //判断为左右滑动
          return super.onTouchEvent(event);
        }
        float moveY = event.getY();
        float distance = moveY - lastY;
        lastY = moveY;
        slideLength += distance;
        if (slideLength >= 0) {
          slideLength = 0;
        }
        if (slideLength <= (-1) * (drawBitmap.getHeight() - height)) {
          slideLength = (-1) * (drawBitmap.getHeight() - height);
        }
        postInvalidate();
        break;
      default:
        break;
    }
    return true;
  } 

  public Bitmap resizeImage(Bitmap bitmap, int w) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    float scaleWidth = ((float) w) / width;
    Matrix matrix = new Matrix();
    matrix.postScale(scaleWidth, scaleWidth);
    return Bitmap.createBitmap(bitmap, 0, 0, width,
        height, matrix, true);
  } 

  public Bitmap resizeImageH(Bitmap bitmap, int h) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    float scaleWidth = ((float) h) / height;
    Matrix matrix = new Matrix();
    matrix.postScale(scaleWidth, scaleWidth);
    return Bitmap.createBitmap(bitmap, 0, 0, width,
        height, matrix, true);
  } 

} 

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

您可能感兴趣的文章:

  • android异步加载图片并缓存到本地实现方法
  • Android中Glide加载库的图片缓存配置究极指南
  • Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案
  • Android加载大分辨率图片到手机内存中的实例方法
  • Android实现加载广告图片和倒计时的开屏布局
  • Android关于Glide的使用(高斯模糊、加载监听、圆角图片)
  • Android中自定义加载样式图片的具体实现
  • Android 异步加载图片分析总结
  • Android使用控件ImageView加载图片的方法
  • Android图片加载利器之Picasso基本用法
(0)

相关推荐

  • Android关于Glide的使用(高斯模糊、加载监听、圆角图片)

    高斯模糊.加载监听.圆角图片这些相信大家都很熟悉,那如何实现这些效果,请大家参考本文进行学习. 1.引用 compile 'com.github.bumptech.glide:glide:3.7.0' 2.加载图片 2.1 基本加载 Glide.with(context)     .load(url)     .into(imageView); 2.2 设置加载中和加载失败的情况 Glide.with(context) .load(url) .placeholder(R.drawable.loa

  • Android加载大分辨率图片到手机内存中的实例方法

    还原堆内存溢出的错误首先来还原一下堆内存溢出的错误.首先在SD卡上放一张照片,分辨率为(3776 X 2520),大小为3.88MB,是我自己用相机拍的一张照片.应用的布局很简单,一个Button一个ImageView,然后按照常规的方式,使用BitmapFactory加载一张照片并使用一个ImageView展示. 代码如下: 复制代码 代码如下: btn_loadimage.setOnClickListener(new View.OnClickListener() { @Override   

  • Android中自定义加载样式图片的具体实现

    先让大家看看效果图吧,相信很多Android初学者都想知道这中效果是怎么实现的,来上图: 想实现上面这张图中的自定义加载样式,其实很简单,首先我们需要的布局组件有ProcessBar和TextView,下面是布局文件的代码(只是加载的页面的布局): 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.an

  • Android使用控件ImageView加载图片的方法

    在 Android 加载图片一般使用 ImageView,这里简单记录一下这个控件的使用方法. 最简单就是在 xml 里直接使用 ImageView 标签: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="

  • Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案

    Android ListView异步加载图片错位.重复.闪烁分析以及解决方案,具体问题分析以及解决方案请看下文. 我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如ListView上有100个Item,一屏只显示10个Item,我们知道getView()中convertView是用来复用View对象的,因为一个Item的对应一个View对象,而Ima

  • Android图片加载利器之Picasso基本用法

    今天开始我们来学习一下Picasso,计划包括以下几方面的内容: 图片加载利器之Picasso进阶 图片加载利器之Picasso源码解析 目前市场上比较流行的图片加载框架主要有UniversalImageLoader,Picasso,Glide,Fresco. 下面简单介绍一下这几个框架: UniversalImageLoader:这个可以说是非常非常经典的一个了,相信每个app的开发人员都使用过,只可惜作者已经停止该项目的维护了,所以不太推荐使用. Picasso:是Square公司出品的图片

  • Android 异步加载图片分析总结

    研究了android从网络上异步加载图像,现总结如下: (1)由于android UI更新支持单一线程原则,所以从网络上取数据并更新到界面上,为了不阻塞主线程首先可能会想到以下方法. 在主线程中new 一个Handler对象,加载图像方法如下所示 复制代码 代码如下: private void loadImage(final String url, final int id) { handler.post(new Runnable() { public void run() { Drawable

  • Android中Glide加载库的图片缓存配置究极指南

    零.选择Glide 为什么图片加载我首先推荐Glide? 图片加载框架用了不少,从afinal框架的afinalBitmap,Xutils的BitmapUtils,老牌框架universalImageLoader,著名开源组织square的picasso,google推荐的glide到FaceBook推出的fresco.这些我前前后后都体验过,那么面对这么多的框架,该如何选择呢?下面简单分析下我的看法. afinal和Xuils在github上作者已经停止维护了,开源社区最新的框架要属KJFra

  • android异步加载图片并缓存到本地实现方法

    在android项目中访问网络图片是非常普遍性的事情,如果我们每次请求都要访问网络来获取图片,会非常耗费流量,而且图片占用内存空间也比较大,图片过多且不释放的话很容易造成内存溢出.针对上面遇到的两个问题,首先耗费流量我们可以将图片第一次加载上面缓存到本地,以后如果本地有就直接从本地加载.图片过多造成内存溢出,这个是最不容易解决的,要想一些好的缓存策略,比如大图片使用LRU缓存策略或懒加载缓存策略.今天首先介绍一下本地缓存图片. 首先看一下异步加载缓存本地代码: 复制代码 代码如下: public

  • Android实现加载广告图片和倒计时的开屏布局

    这是一个android开屏布局的实例,可以用于加载广告图片和倒计时的布局.程序中设置的LayoutParams,划分额外空间比例为6分之5,具体权重比例可根据用户自己需求来自定义,异步加载广告图片,相关的Android代码. 具体实现代码如下: package cn.waps.extend; import android.app.Activity; import android.content.Context; import android.content.res.Configuration;

随机推荐