当前位置:网站首页>Alternative implementation of Scrollview pull-down header amplification
Alternative implementation of Scrollview pull-down header amplification
2022-06-29 10:01:00 【Mr beast no beast】
1 Preface
Two days ago, I received a request to enlarge the header when the list was pulled down , This is the effect :

2 Ideas
Checked the data , This effect is usually achieved through customization ScrollView To achieve , But I always think it's troublesome , Need to modify the original XML file , And it has great limitations , The control to be scaled must be placed first , After reading other people's ideas ( Customize scrollView Achieve the top picture pull-down zoom ) after , Decide to use a tool class to achieve this effect .
In the above elder's article, he customized a View Inherited from ScrollView, Then implement onTouchListener Interface , rewrite onTouch() Method , stay onTouch() Method is making scaling judgment , So the most important logic is actually in onTouch() In the method . In that case , In fact, we only need to get those that need to monitor the rolling ScrollView, Then set it up with onTouchListener that will do , Why customize one ScrollView And modify the original layout file .
3 Code implementation
/**
* Description: Tool class for scrolling and zooming
* Created by Mr. beast
* Created on 2018/10/22
*/
public class ScrollZoomUtil {
// Control original height
private static int sZoomViewOriginWidth = 0;
// Control original width
private static int sZoomViewOriginHeight = 0;
// The ordinate of the scrollable control being monitored when it is pressed
private static float sLastY = 0;
// Flag bit of whether to start scaling
private static boolean sStartZoom = false;
public static void scrollZoom(final View scrollView, final View zoomView) {
zoomView.post(new Runnable() {
@Override
public void run() {
// Record the original width and height of the control
sZoomViewOriginWidth = zoomView.getMeasuredWidth();
sZoomViewOriginHeight = zoomView.getMeasuredHeight();
}
});
scrollView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// You can only zoom when the scrollable control being monitored has scrolled to the top , Set the flag to true, Record the pressed ordinate
if (scrollView.getScrollY() == 0) {
sStartZoom = true;
sLastY = event.getY();
return true;
}
break;
case MotionEvent.ACTION_MOVE:
if (sStartZoom) {
// Calculate the sliding distance
float distanceY = event.getY() - sLastY;
if (distanceY > 0) {
// When the sliding distance is greater than 0 When, it means drop-down operation , Zoom in on the control to be scaled
zoom(zoomView, distanceY);
} else {
// When the sliding distance is less than 0 When, it indicates the pull-up operation , Determine the current width and height of the control to be scaled , If it is larger than the original width, scale to the original width and height first
if (zoomView.getMeasuredWidth() > sZoomViewOriginWidth) {
zoom(zoomView, distanceY);
} else {
// Pull up when the current width and height of the control to be scaled are equal to the original width and height , Normal scrolling operation is performed
break;
}
}
return true;
}
case MotionEvent.ACTION_UP:
// When the finger is lifted up, it will return to its original state
sLastY = 0;
sStartZoom = false;
restore(zoomView);
break;
}
return false;
}
});
}
/**
* Description: The zoom
* Date:2018/10/22
*/
private static void zoom(View zoomView, float distanceY) {
if (sZoomViewOriginWidth <= 0 || sZoomViewOriginHeight <= 0) {
return;
}
ViewGroup.LayoutParams layoutParams = zoomView.getLayoutParams();
// The control height is the original height plus the sliding distance multiplied by a factor ( And sliding distance 1:1 The change is too big )
layoutParams.height = (int) (sZoomViewOriginHeight + distanceY * 0.4);
// Control width changes proportionally
layoutParams.width = (int) ((sZoomViewOriginWidth * (sZoomViewOriginHeight + distanceY * 0.4)) / sZoomViewOriginHeight);
zoomView.setLayoutParams(layoutParams);
}
/**
* Description: Return to the original state
* Date:2018/10/22
*/
private static void restore(final View zoomView) {
// Restore the original width and height with attribute animation , Make it have a transition effect
ValueAnimator widthValueAnimator = ObjectAnimator.ofInt(zoomView.getMeasuredWidth(), sZoomViewOriginWidth);
ValueAnimator heightValueAnimator = ObjectAnimator.ofInt(zoomView.getMeasuredHeight(), sZoomViewOriginHeight);
widthValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
ViewGroup.LayoutParams layoutParams = zoomView.getLayoutParams();
layoutParams.width = (int) animation.getAnimatedValue();
zoomView.setLayoutParams(layoutParams);
}
});
heightValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
ViewGroup.LayoutParams layoutParams = zoomView.getLayoutParams();
layoutParams.height = (int) animation.getAnimatedValue();
zoomView.setLayoutParams(layoutParams);
}
});
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(widthValueAnimator).with(heightValueAnimator);
// This animation duration is the duration of each animation, not the total duration
animatorSet.setDuration(300);
animatorSet.start();
}
}I am rough when calculating the width and height changes of the control that needs to be scaled , The change in height is the sliding distance multiplied by a factor , Then the width changes proportionally , But the effect looks ok . There is no need to change the layout file when using :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_zoom"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_gravity="center_horizontal"
android:scaleType="fitXY"
android:src="@drawable/img_1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="15dp"
android:text=" I am a TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="15dp"
android:text=" I am a TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="15dp"
android:text=" I am a TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="15dp"
android:text=" I am a TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="15dp"
android:text=" I am a TextView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="15dp"
android:text=" I am a TextView" />
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_gravity="center_horizontal"
android:scaleType="fitXY"
android:src="@drawable/img_2" />
</LinearLayout>
</ScrollView>
Only need Activity You can call the tool class to pass in the control that needs to be detected and scaled :
ScrollView scrollView = findViewById(R.id.scroll_view);
ImageView ivZoom = findViewById(R.id.iv_zoom);
ScrollZoomUtil.scrollZoom(scrollView, ivZoom);The effect is the effect at the beginning .
4 summary
The need for this pull-down scaling , I prefer to use an external method instead of customization ScrollView The way , The changes are small . All roads lead to Rome , Think more about everything , Now, what are the requirements for software development , There may already be an answer on the Internet , But the most important thing is to understand other people's thoughts , Otherwise, if there is a small change in the demand next time, I still can't make it .
边栏推荐
- leetcode MYSQL数据库题目180
- 另类实现 ScrollView 下拉头部放大
- Fabrication d'une calculatrice d'addition simple basée sur pyqt5 et Qt Designer
- 券商经理给的开户二维码办理股票开户安全吗?我想开个户
- 367. effective complete square dichotomy
- 力扣94二叉树的中序遍历
- Middle order traversal of Li Kou 94 binary tree
- es报错NoNodeAvailableException[None of the configured nodes are available:[.127.0.0.1}{127.0.0.1:9300]
- 数据库常见面试题(附答案)
- Idea auto completion
猜你喜欢

1424. 对角线遍历 II

Student增删gaih

A comparison of methods for fully automatic segmentation of tumors and involved nodes in PET/CT of h

FreeRTOS(九)——队列

Deep Learning-based Automated Delineation of Head and Neck Malignant Lesions from PET Images

Flutter 基础组件之 Image

遍历vector容器中的对象的方式

Fabrication d'une calculatrice d'addition simple basée sur pyqt5 et Qt Designer

阿里云防火墙配置,多种设置方式(iptables和fireward)

Flutter 基础组件之 ListView
随机推荐
Slider validation code
分布式和集群分不清,我们讲讲两个厨子炒菜的故事
float 与 int 相乘产生的令人崩溃的“ 2.3 * 10 = 22 ”
Data governance: Metadata Management (Part 2)
JVM之方法的绑定机制
聊聊你理解的线程与并发
JVM之TLAB
2020-09-25 boost库的noncopyable,用于单例模式
监控数据源连接池使用情况
Fabrication d'une calculatrice d'addition simple basée sur pyqt5 et Qt Designer
力扣85题最大矩形
2020-09-17 gateway业务流程 两个任务:referer认证和非商品模板化
微信小程序实现store功能
Lc236. nearest common ancestor of binary tree
自定义mvc框架实现
通用分页框架
mysql修改自动递增初始值
1424. 对角线遍历 II
2020-9-14 广告系统入门
另类实现 ScrollView 下拉头部放大