滑动ListView列表然后 listView上边的视图 跟随着上拉或者下拉的距离 自动放大或者缩小  视图里边元素自动平移的效果

思路很简单

根据listView 的滑动距离去计算图片和文字应该平移的距离

例如顶部视图本来高度为500px  我们定义视图收缩到200px为最小高度,那么视图向上滑动的最大距离就为300px

当我们将列表向上滑动300px的时候试图就应该滑到最小高度了   继续上滑,不继续缩小视图高度即可

同理 下拉的时候 下拉300px 此时视图应该从200px高度变为500px高度  继续下拉 不增加试图高度即可

简单来说就是对 触摸事件的处理  根据   (上拉或者下拉的距离)/300px = 视图应该缩小或者放大的比例

上代码:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
> <RelativeLayout
android:id="@+id/rl_head"
android:layout_width="match_parent"
android:layout_height="300px"
android:text="Hello World!"
android:background="#9F79EE"> <ImageView
android:id="@+id/iv_head"
android:layout_marginTop="60px"
android:layout_marginLeft="50px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/ic_launcher_round"
/> <TextView
android:id="@+id/tv_name"
android:layout_marginTop="80px"
android:layout_marginLeft="180px"
android:text="一个名称"
android:textColor="#fff"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_other"
android:text="其他字段"
android:textColor="#fff"
android:layout_marginTop="200px"
android:layout_marginLeft="50px"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> </RelativeLayout> <ListView
android:id="@+id/lv"
android:layout_below="@id/rl_head"
android:listSelector="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/> </RelativeLayout>

MainActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView; import java.util.Arrays;
import java.util.List; public class MainActivity extends Activity { private ListView listView;
private RelativeLayout rl_head;
private ImageView iv_head;
private TextView tv_name,tv_other; private MyAdapter adapter; //*******************************
private int mLastY = 0; //最后的点
private static int mNeedDistance; // 需要滑动的距离
private static int mMinHight; //最小高度
private static int mOrignHight; //原始的高度 private int mCurrentDistance = 0; //当前的距离
private float mRate = 0; //距离与目标距离的变化率 mRate=mCurrentDistance/mNeedDistance
private int mPhotoOriginHeight; //图片的原始高度
private int mPhotoOriginWidth; //图片的原始宽度
private int mPhotoLeft; //图片距左边的距离
private int mPhotoTop; //图片距离上边的距离
private int mPhotoNeedMoveDistanceX; // 图片需要移动的X距离
private int mPhotoNeedMoveDistanceY; // 图片需要移动的Y距离
//需要移动的文字
private int mTextLeft; //文字距左边的距离
private int mTextTop; //文字距离上边的距离
private int mTextNeedMoveDistanceX; // 文字需要移动的X距离
private int mTextNeedMoveDistanceY; //文字需要移动的Y距离
//********************************************* @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
initDistance();
} private void initView() {
listView= (ListView) findViewById(R.id.lv);
rl_head= (RelativeLayout) findViewById(R.id.rl_head);
iv_head= (ImageView) findViewById(R.id.iv_head);
tv_name= (TextView) findViewById(R.id.tv_name);
tv_other= (TextView) findViewById(R.id.tv_other); String []strs={"北京","上海","天津","北京","上海","天津","北京","上海","天津","北京","上海","天津","北京","上海","天津","北京","上海","天津","北京","上海","天津"};
List<String> data= Arrays.asList(strs); adapter=new MyAdapter(this,data);
listView.setAdapter(adapter);
} /**
* 初始化需要滚动的距离
*/
private void initDistance() {
mOrignHight = rl_head.getLayoutParams().height;
mMinHight =100; //设置最小的高度为这么多
mNeedDistance = mOrignHight - mMinHight;
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) iv_head.getLayoutParams();
mPhotoOriginHeight = params.height;
mPhotoOriginWidth = params.width;
mPhotoLeft = params.leftMargin;
mPhotoTop = params.topMargin;
mPhotoNeedMoveDistanceX = getWindowManager().getDefaultDisplay().getWidth() / 2 - mPhotoLeft - mMinHight;
mPhotoNeedMoveDistanceY = mPhotoTop - 20;
/*******************移动的文字初始化***************************/
RelativeLayout.LayoutParams textParams = (RelativeLayout.LayoutParams) tv_name.getLayoutParams();
mTextLeft = textParams.leftMargin;
mTextTop = textParams.topMargin;
mTextNeedMoveDistanceX = getWindowManager().getDefaultDisplay().getWidth() / 2 - mTextLeft + 10;
mTextNeedMoveDistanceY = mTextTop - 20; //这里计算有点误差,正确的应该是剪去获取textview高度的一半
} @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastY = (int) ev.getY();
// LogUtils.d(TAG, "ACTION_MOVE==mCurrentDistance" + mCurrentDistance);
return super.dispatchTouchEvent(ev); //传递事件 例如可以用来子view的点击事件等
case MotionEvent.ACTION_MOVE:
int y = (int) ev.getY();
int dy = mLastY - y;
// LogUtils.d(TAG, "ACTION_MOVE==mCurrentDistance" + mCurrentDistance);
if (mCurrentDistance >= mNeedDistance && dy > 0) {
return super.dispatchTouchEvent(ev); //传递事件
}
if (mCurrentDistance <= 0 && dy < 0) {
return super.dispatchTouchEvent(ev); //把事件传递进去
}
//改变布局
changeTheLayout(dy);
mLastY = y;
break;
case MotionEvent.ACTION_UP:
checkTheHeight();
// LogUtils.d(TAG, "ACTION_MOVE==mCurrentDistance" + mCurrentDistance);
return super.dispatchTouchEvent(ev);
} return false;
} /**
* 通过滑动的偏移量
*
* @param dy
*/
private void changeTheLayout(int dy) {
final ViewGroup.LayoutParams layoutParams = rl_head.getLayoutParams();
layoutParams.height = layoutParams.height - dy;
rl_head.setLayoutParams(layoutParams);
checkTheHeight();
rl_head.requestLayout();
//计算当前移动了多少距离
mCurrentDistance = mOrignHight - rl_head.getLayoutParams().height;
mRate = (float) (mCurrentDistance * 1.0 / mNeedDistance);
changeTheAlphaAndPostion(mRate); //获取偏移率然后改变某些控件的透明度,和位置
} /**
* 根据变化率来改变这些这些控件的变化率位置
*
* @param rate
*/
private void changeTheAlphaAndPostion(float rate) {
//先改变一些控件的透明度
if (rate >= 1) {
tv_other.setVisibility(View.GONE);
} else {
tv_other.setVisibility(View.VISIBLE);
tv_other.setAlpha(1 - rate);
tv_other.setScaleY(1 - rate);
tv_other.setScaleX(1 - rate);
}
//接下来是改变控件的大小和位置了 (这就是关键了)
RelativeLayout.LayoutParams photoParams = (RelativeLayout.LayoutParams) iv_head.getLayoutParams();
// photoParams.width = (int) (mPhotoOriginWidth - (rate * (mPhotoOriginWidth - mMinHight - 10)));
// photoParams.height = (int) (mPhotoOriginWidth - (rate * (mPhotoOriginWidth - mMinHight - 10)));
photoParams.leftMargin = (int) (mPhotoLeft + mPhotoNeedMoveDistanceX * rate);
photoParams.topMargin = (int) (mPhotoTop - mPhotoNeedMoveDistanceY * rate);
iv_head.setLayoutParams(photoParams);
//针对文字
RelativeLayout.LayoutParams textParams = (RelativeLayout.LayoutParams) tv_name.getLayoutParams();
textParams.leftMargin = (int) (mTextLeft + mTextNeedMoveDistanceX * rate);
textParams.topMargin = (int) (mTextTop - mTextNeedMoveDistanceY * rate);
tv_name.setLayoutParams(textParams);
} /**
* 检查上边界和下边界
*/
private void checkTheHeight() {
final ViewGroup.LayoutParams layoutParams = rl_head.getLayoutParams();
if (layoutParams.height < mMinHight) {
layoutParams.height = mMinHight;
rl_head.setLayoutParams(layoutParams);
rl_head.requestLayout();
}
if (layoutParams.height > mOrignHight) {
layoutParams.height = mOrignHight;
rl_head.setLayoutParams(layoutParams);
rl_head.requestLayout();
} } }

根据这个思路  即可实现网上大多数 上拉下拉,收缩放大视图的效果

严禁盗版    

转载请注明出处:https://www.cnblogs.com/bimingcong/p/9029491.html

Android自定义View之上拉、下拉列表 头部元素跟随 缩放、平移效果的实现的更多相关文章

  1. Android自定义View(LimitScrollerView-仿天猫广告栏上下滚动效果)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53303872 本文出自:[openXu的博客] 1分析 2定义组合控件布局 3继承最外层控件 ...

  2. (转)[原] Android 自定义View 密码框 例子

    遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 ...

  3. Android 自定义View合集

    自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...

  4. Android 自定义 view(四)—— onMeasure 方法理解

    前言: 前面我们已经学过<Android 自定义 view(三)-- onDraw 方法理解>,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法 推荐文章: htt ...

  5. Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...

  6. Android 自定义View及其在布局文件中的使用示例(二)

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3530213.html From crash_coder linguowu linguowu0622@gami ...

  7. [原] Android 自定义View步骤

    例子如下:Android 自定义View 密码框 例子 1 良好的自定义View 易用,标准,开放. 一个设计良好的自定义view和其他设计良好的类很像.封装了某个具有易用性接口的功能组合,这些功能能 ...

  8. [原] Android 自定义View 密码框 例子

    遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 ...

  9. Android自定义View

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View ...

随机推荐

  1. socat管理haproxy以及haproxy调优

    Unix套接字命令(Unix Socket commands) socat是一个多功能的网络工具,名字来由是“Socket CAT”,可以看作是netcat的N倍加强版,socat的官方网站:http ...

  2. MongoDB基础知识(二)

    一.基本概念 1:文档(document)是MongoDB中数据的基本单元,非常类似于关系型数据库管理系统中的行 2:集合(collection)可以看做是一个拥有动态模式(dynamic schem ...

  3. 第二章 C#语法基础(2.1C#语言的数据类型二)

    数据类型案例说明 一.数据类型与变量(计算整数10与20的和) namespace ConsoleApp1 { class Program { static void Main(string[] ar ...

  4. centos7启动过程及systemd详细说明

    开机启过程 POST->BOOT SEQUENCE-> BOOTLOADER->KERNEL + INITRAMFS(INITRD)->ROOTFS->/sbin/ini ...

  5. 接口测试工具SoapUI Pro5.1.2基本使用20150920

    soapui是接口测试工具,最近因为要做接口测试,使用了下,现在和大家分享下: 工具安装很简单,就不说了,直接说使用,先什么都不说,照着操作一遍,我们拿天气预报的webserver来实战: 主要包括: ...

  6. Java的Finalizer引发的内存溢出

    本文介绍的是Java里一个内建的概念,Finalizer.你可能对它对数家珍,但也可能从未听闻过,这得看你有没有花时间完整地看过一遍java.lang.Object类了.在java.lang.Obje ...

  7. python http请求及多线程应用

    目录 概述 tomorrow包准备 运行环境遇到的问题 其他尝试未果 概述 今天, 使用python3 模拟下发包, http get 请求, 然后 采用tomorrow 多线程. 代码如下: # c ...

  8. Flume架构

    Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统: Flume 介绍 Flume是由cloudera软件公司产出的高可用.高可靠.分布式的海量日志收集系 ...

  9. Spring整体了解

      1.spring原理 内部最核心的就是IOC了,动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建.调用对象,Spring就是 ...

  10. lvm管理:扩展lv、删除pv、lv等

    从卷组VG里扩展lv.删除pv,并删除物理卷PV 一.扩展LV.缩小LV 1.卸载LV 命令:umount  "挂载目录" 2.扩展LV 命令:lvextend -L +500m  ...