滑动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. Python shutil 模块

    高级的文件.文件夹.压缩包 处理模块 http://www.cnblogs.com/wupeiqi/articles/4963027.html

  2. Maven项目中在properties 中使用 ${} 来引用pom文件中的属性

    比如在pom文件中定义了属性如下: <jdbc.host.global>127.0.0.1</jdbc.host.global> <jdbc.databasename.g ...

  3. bootstrap之navbar

    container:固定960px宽度,(如果又引入了响应式样式,则会适当调整,例如1600*900,它会显示1200px) container-fluid:自适应屏幕宽度,即满屏显示. row和co ...

  4. Excel函数之rank应用

    该函数的功能就是对现有数据指标进行排名 示例:对产品进行销售总额的排名 首先要知道排名需要用到rank函数 number参数就是你要进行排名的数据 ref参数就是该指标需要在哪个区域内进行比较定位排名 ...

  5. 手动卸载CAD 删除残留文件 清理遗留的文件

    手动卸载基于 AutoCAD 产品的文件,从而删除所有残留文件. 清理安装失败所遗留的文件. 一.解决方案: 通过"控制面板"卸载该程序. 删除以下位置残留的 AutoCAD 文件 ...

  6. 冷知识点:COLLATE 关键字是什么意思?

    mysql 数据库表: CREATE TABLE `book_order_test` ( `order_id` varchar(50) COLLATE utf8_bin DEFAULT NULL CO ...

  7. CRM 2016 Get IOrganizationService

    得到域认证下的IOrganizationService private IOrganizationService GetOrgService() { Uri orgServiceUri = new U ...

  8. 配置iis支持json解析,配置ssi

    配置json解析: 添加mime:*.json  类型 text/json 安装iis应用程序开发中的asp功能 添加处理程序映射: 添加脚本映射 请求路径:*.json 可执行文件:C:\Windo ...

  9. JavaWeb——tomcat manager 403 Access Denied .You are not authorized to view this page.

    403 Access Denied You are not authorized to view this page. If you have already configured the Manag ...

  10. expect login ssh

    #!/usr/bin/expect -f set pwffd [lindex $argv 0] spawn ssh cmesvr2i expect "*password:" sen ...