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高度时可能出现绘制速度赶不上滚动的速度,会出现错位,当然时间设置太短,也看不到这种滑动的效果了.暂时想到的做法就是这样,应该还会有更好的方法.

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

(0)

相关推荐

  • Android仿支付宝、京东的密码键盘和输入框

    首先看下效果图 一:布局代码 键盘由0~9的数字,删除键和完成键组成,也可以根据需求通过GridView适配器的getItemViewType方法来定义.点击键的时候背景有变色的效果. 密码输入框由六个EditText组成,每个输入框最对能输入一个数字,监听最后一个输入框来完成密码输入结束的监听. 二:键盘 键盘中的主要逻辑处理,键盘样式,item的点击事件 @Override public int getViewTypeCount() { return 2; } @Override publi

  • Android仿京东首页轮播文字效果

    京东客户端的轮播文字效果: 本次要实现的只是后面滚动的文字(前面的用ImageView或者TextView实现即可),看一下实现的效果 实现思路 上图只是一个大概的思路,要实现还需要完善更多的细节,下面会一步步的来实现这个效果: 1.封装数据源:从图上可以看到,轮播的文字是分为两个部分的,暂且把它们分别叫做前缀和内容,而且实际的使用过程中点击轮播图肯定是需要跳转页面的,而且大部分应该是WebView,不妨我们就设置点击时候需要获取的内容就是一个链接,那么数据源的结构就很明了了 创建ADEnity

  • Android中使用TextView实现高仿京东淘宝各种倒计时效果

    今天给大家带来的是仅仅使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.最近公司一直加班也没来得及时间去整理,今天难得休息想把这个分享给大家,只求共同学习,以及自己后续的复习.为什么会想到使用一个TextView来实现呢?因为最近公司在做一些优化的工作,其中就有一个倒计时样式,原来开发的这个控件的同事使用了多个TextView拼接在一起的,实现的代码冗余比较大,故此项目经理就说:小宏这个就交给你来优化了,并且还要保证有一定的扩展性,当时就懵逼了.不知道从何处开始

  • Android仿京东、天猫商品详情页

    前言 前面在介绍控件TabLayout控件和CoordinatorLayout使用的时候说了下实现京东.天猫详情页面的效果,今天要说的是优化版,是我们线上实现的效果,首先看一张效果: 项目结构分析 首先我们来分析一下要实现上面的效果,我们需要怎么做.顶部是一个可以滑动切换Tab,可以用ViewPager+Fragment实现,也可以使用系统的TabLayout控件实现:而下面的 View是一个可以滑动拖动效果的View,可以采用网上一个叫做DragLayout的控件,我这里是自己实现了一个,主要

  • Android 仿淘宝、京东商品详情页向上拖动查看图文详情控件DEMO详解

    一.淘宝商品详情页效果 我们的效果 二.实现思路 使用两个scrollView,两个scrollView 竖直排列,通过自定义viewGroup来控制两个scrollView的竖直排列,以及滑动事件的处理.如下图 三.具体实现 1.继承viewGroup自定义布局View 重写onMeasure()和onLayout方法,在onLayout方法中完成对两个子ScrollView的竖直排列布局,代码如下: 布局文件: <RelativeLayout xmlns:android="http:/

  • 安卓(android)仿电商app商品详情页按钮浮动效果

    1.效果图如下: 这效果用户体验还是很酷炫,今天我们就来讲解如何实现这个效果. 2.分析 为了方便理解,作图分析 如图所示,整个页面分为四个部分: 1.悬浮内容,floatView 2.顶部内容,headView 3.中间内容,与悬浮内容相同,middleView 4.商品详情展示页面,detailView 因为页面内容高度会超出屏幕,所以用Scrollview实现滚动,悬浮view与scrollview同级,都在一个帧布局或者相对布局中. 当y方向的滚动距离小于中间的内容middleView到

  • Android仿淘宝商品拖动查看详情及标题栏渐变功能

    绪论 最近一直比较忙,也没抽出时间来写博客,也不得不说是自己犯了懒癌,人要是一懒就什么事都不想做了,如果不能坚持下来的话,那么估计就废了,��.最近自己攒了好多东西,接下来的时间我会慢慢都分享出来的.好了废话不多说了,下面我们开始正题: 今天要分享的是淘宝的详情页,之前在淘宝上买东西的时候看到淘宝的详情页效果比较不错,所以今天就来仿一下它的效果吧,可能没有淘宝的好,希望见谅啊. 先上效果图: 这是淘宝的: 我自己做的: 怎么样效果还差不多吧?GIF图效果看的不太清楚,见谅. 下面我们来看看怎么实

  • Android TabLayout实现京东详情效果

    Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,Google给我们提供了更加规范的MD设计风格的控件.最重要的是,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2. 这两天需要做一个仿京东详情的页面,上面的Tab切换,以前都是自己写Viewpager+fragment

  • Android高仿京东垂直循环滚动新闻栏

    实现思路其实很简单,就是一个自定义的LinearLayout,并且textView能够循环垂直滚动,而且条目可以点击,显示区域最多显示2个条目,并且还有交替的属性垂直移动的动画效果,通过线程来控制滚动的实现. 不多说看效果: 代码实现 我们先来为控件设置自定义属性: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="JDAdv

  • Android仿京东首页画轴效果

    记得之前京东首页有一个效果,有一个画轴,然后可以滚动画轴,去打开画(不知道怎么去形容这个效果,就叫做画轴效果吧- -!),然后去做相关操作,刚开始看到这个效果,想法是动态的去改变一个ImageView的高度,基本效果也就出来了,不过滚动部分的内容,当时接触的也不是很多,只是看过一些大牛的博客,略微了解了一点,当时也忙着写项目,也就没去多想,前些天忽然想到这个效果,就想着实现一下,不过京东新版本好像去掉这个东西了,只能凭着自己的记忆来大概搞一下,也是对滑动这部分内容的一个小练习吧. 先看一下效果图

  • Android仿京东首页秒杀倒计时

    本文实例为大家分享了Android仿京东首页秒杀倒计时的具体代码,供大家参考,具体内容如下 xml配置 <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#FFFFFF" android:orientation="vertical"> <Linea

  • Android 仿京东商城底部布局的选择效果(Selector 选择器的实现)

    京东商城的底部布局的选择效果看上去很复杂,其实很简单,这主要是要感谢 selector 选择器,本文将讲解仿照京东商城的底部布局的选择效果,如何实现 selector 选择器,在不同的状态下,给 view 设置不同的背景. 京东商城底部布局的选择效果如下. View主要的几种状态 主要状态有8种,设置状态的代码以及相应的含义如下. android:state_pressed = "true/false" //true表示按下状态,false表示非按下状态. android:state_

  • Android仿京东分类模块左侧分类条目效果

    本文实例为大家分享了Android仿京东左侧分类条目效果的具体代码,供大家参考,具体内容如下 import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.LinearLayout; import android.widget.ScrollView; import android.widget.TextView; import com.frame.R;

  • Android仿京东分类效果

    本文实例为大家分享了Android仿京东分类效果展示的具体代码,供大家参考,具体内容如下 1.写一个fragment import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView;

  • Android仿京东快报信息滚动效果

    先来看看效果吧,Android仿京东快报信息滚动效果,具体内容如下 (截图效果不是很好,但是差不多出来了) 代码: package com.test.scrolltransptoolbar; import android.content.Context; import android.graphics.Color; import android.os.Handler; import android.text.TextUtils; import android.util.AttributeSet;

  • Android实现京东首页效果

    本文实例为大家分享了Android实现京东首页效果的具体代码,供大家参考,具体内容如下 1.效果图: 2.布局 源码链接 <?xml version="1.0" encoding="utf-8"?> <com.scwang.smart.refresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns

  • Android仿高德首页三段式滑动效果的示例代码

    目录 高德的效果 实现的效果 自定义View源码 xml布局中的使用 高德首页按钮处理 源码地址 最近发现很多app都使用了三段式滑动,比如说高德的首页和某宝等物流信息都是使用的三段式滑动方式,谷歌其实给了我们很好的2段式滑动,就是BottomSheet,所以这次我也是在这个原理基础上做了一个小小的修改来实现我们今天想要的效果. 高德的效果 实现的效果 我们实现的效果和高德差距不是很大,也很顺滑.具体实现其实就是继承CoordinatorLayout.Behavior 自定义View源码 /**

  • Android仿京东手机端类别页

    京东手机端的类别标签页, 是一个左侧滑动可选择类别, 右侧一个类别明细的列表联动页面. 当用户选择左侧选项, 可在右侧显示更多选项来选择. 实现方式也不少. 最常见的当然是左侧和右侧各一个Fragment, 左侧Fragment放置ListView, 右侧放显示类别明细的Fragment. 如果觉得页面包含的Fragment太多, 左侧直接给一个ListView就可以了.不影响效果. 效果图: 例子中值得注意的三点: 左侧列表点击某个Item可以自动上下滑动,使所点击的item自动移至列表中间

  • Android仿京东淘宝自动无限循环轮播控件思路详解

    在App的开发中,很多的时候都需要实现类似京东淘宝一样的自动无限轮播的广告栏,所以就自己写了一个,下面是我自定义控件的思路和过程. 一.自定义控件属性 新建自定义控件SliderLayout继承于RelativeLayout,首先要考虑的就是自定义的控件需要扩展那些属性,把这些属性列出来.在这里是要实现类似于京东淘宝的无限轮播广告栏,那么首先想到的就是轮播的时长.轮播指示器的样式等等.我在这里列举了一些并且结合到了代码中. 1.扩展属性 (1)是否开启自动轮播的功能. (2)指示器的图形样式,一

随机推荐