1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Android自定义View之上拉 下拉列表 头部元素跟随 缩放 平移效果的实现

Android自定义View之上拉 下拉列表 头部元素跟随 缩放 平移效果的实现

时间:2022-03-09 07:05:26

相关推荐

Android自定义View之上拉 下拉列表 头部元素跟随 缩放 平移效果的实现

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

思路很简单

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

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

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

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

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

上代码:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayoutxmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#fff"><RelativeLayoutandroid:id="@+id/rl_head"android:layout_width="match_parent"android:layout_height="300px"android:text="Hello World!"android:background="#9F79EE"><ImageViewandroid: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"/><TextViewandroid: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" /><TextViewandroid: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><ListViewandroid: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/mNeedDistanceprivate 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距离//*********************************************@Overrideprotected 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高度的一半 }@Overridepublic 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();}}}

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

严禁盗版

转载请注明出处:/bimingcong/p/9029491.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。