当前位置:网站首页>View Slide
View Slide
2022-07-05 09:53:00 【Anemone】
To study the Android The coordinate system of , Next , I will explain how to achieve Android Of View slide , And common implementations view Sliding method and comparison , Finally, explain each method .
How to achieve Android Of View slide ?
Realization View There are many ways to slide , But everything is the same , The idea of implementation is always the same or similar . When touched View when , Record the coordinates of the current touch point ; When the fingers move , Record the coordinates of the moving touch point ; How to calculate the offset equivalent to the previous coordinate , And modify by offset View Coordinates of .
Common implementations View Methods
- layout
- offsetLeftAndRight + offsetTopAndBottom
- setLayoutParams modify View Of LayoutParams
- scrollBy / scrollTo
- Scroller + ((View)getParent()).scrollTo
- Animation
- ViewDragHelper
among View The sliding of can be instantaneous , It can also be non instantaneous , Classified by instantaneous and non instantaneous
- Instantaneous sliding
- layout
- offsetLeftAndRight + offsetTopAndBottom
- setLayoutParams
- scrollBy / scrollTo
- Non instantaneous slip ,
- Scroller + ((View)getParent()).scrollTo
- Animation
- ViewDragHelper
Method explanation and use
1. layout
principle : When View When drawing , Would call onLayout() Method to set its display position . We call layout Rearrange yourself , Its internal implementation calls onLayout, Where to reach View The movement of the .layout Part of the code implemented if :
if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
onLayout(changed, l, t, r, b); // layout Internal calls onLayout
}
Key code :
First of all, every touch , Get the coordinates of the touch point , The code is as follows :
int rawX = (int) event.getRawX();
int rawY = (int) event.getRawY();
And then ACTION_DOWN
Record the coordinates of the touch point , The code is as follows :
case MotionEvent.ACTION_DOWN:
// Record the coordinates of the touch point
mLastX = rawX;
mLastY = rawY;
break;
Last in ACTION_MOVE
Calculate the offset in , And apply the offset to layout
In the method , The code is as follows :
case MotionEvent.ACTION_MOVE:
// Calculate the offset
int offsetX = rawX - mLastX;
int offsetY = rawY - mLastY;
// In the current left、top、right、bottom Add an offset based on
layout(getLeft() + offsetX, getTop() + offsetY,
getRight() + offsetX, getBottom() + offsetY);
// Reset the initial coordinates
mLastX = rawX;
mLastY = rawY;
break;
Be careful : In the above code we use getRawX()、getRawY() Obtain absolute coordinates to calculate the offset , Of course we can use getX()、getY() Obtain equivalent coordinates to calculate the offset .
2. offsetLeftAndRight + offsetTopAndBottom
offsetLeftAndRight 、offsetTopAndBottom The system encapsulates the right View about 、 The method of moving up and down . The code to use them is as follows :
offsetLeftAndRight(offsetX);
offsetTopAndBottom(offsetY);
3. modify View Of LayoutParams
LayoutParams Save the View The layout parameters of , So by modifying LayoutParams Achieve change View The effect of location . The key codes are as follows :
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) getLayoutParams();
params.leftMargin = getLeft() + offsetX;
params.topMargin = getTop() + offsetY;
setLayoutParams(params);
Be careful : Depending on the type of parent layout , It needs to be used differently according to the situation LayoutParams, Such as LinearLayout.LayoutParams、RelativeLayout.LayoutParams. So we use ViewGroup.MarginLayoutParams, Because it is ViewGroup Of LayoutParams A subclass of , It is of other layouts LayoutParams Parent class of . It does not need to consider the type of parent layout .
4. scrollBy / scrollTo
scrollBy and scrollTo The difference is well understood , Understand according to the name .
- scrollTo(x, y) It means moving a specific coordinate point (x, y)
- scrollBy(dx, dy) Indicates that the increment of movement is dx, dy
After obtaining the offset , We use scrollBy Mobile View. The code is as follows :
scrollBy(offsetX, offsetY)
You'll find that View Not moving .scrollBy and scrollTo Moving is View Of content, Moving is View The content of . stay ViewGroup Use in scrollBy 、scrollTo, Movement is all children View; stay View Use in scrollBy 、scrollTo, Move to make View The content of , for example TextView Of content It's the text 、ImageView Of content It's its drawable object .
So we should be in ViewGroup Use in scrollBy To move its son View,scrollBy Call in code scrollTo Realized . The code is as follows :
((View)getParent()).scrollBy(offsetX, offsetY);
however , When dragging View when , You'll find that View Although it moved , But it's moving . Now I will explain to you view Mobile knowledge .
This is shown in the following figure ,UI Visible area , For the screen , That is, the red matrix range . The green area is View,content Is its content , canvas . Canvases can be large , It can be very small , What we can't see View, Doesn't mean it doesn't exist , For example, in the following figure , There is only one visible area Button(20, 10), One more Button We can't see .
and scrollBy Mobile is the screen , When calling scrollBy(20, 10), Screen in X Affirmative direction ( On the right ) translation 20, stay Y The axis is in the opposite direction ( Send out ) translation 10, The results are as follows . Can be regional button coordinate , Turned into (0, 0).scrollBy(20, 10) Screen edge X Affirmative direction ,Y The axis moves in the positive direction , however button Equivalent to the screen, but to X Axis negative direction ,Y The axis moves in the negative direction . Because the choice of reference system is different .
To sum up :
- scrollBy Mobile is View Of content, If you want to move View, obtain ViewGroup, call scrollBy;
- scrollBy Mobile is screen ,(dx, dy) Is the direction the screen moves , Because of the different reference systems , In fact, for View Of content Speaking of mobile is (-dx, -dy);
- scrollBy Is based on scrollTo Realized ;
in summary , Modify the above code . We can achieve the desired results , The code is as follows :
((View)getParent()).scrollBy(-offsetX, -offsetY);
5. Scroller
Use Scroller Class implements non instantaneous sliding , That is, the effect of smooth movement .Scroller The schematic diagram of the implementation is as follows .
Use Scroller There are three steps .
- initialization Scroller
mScroller = new Scroller(getContext());
- rewrite View Of computeScroll() Method .
rewrite computeScroll(), It's using Scroller At the heart of , System drawing View When , Will be in draw() Method , Call the method . This method is actually using scrollTo, Finish right View The movement of the . Moving coordinate point , adopt Scroller object , get .
@Override
public void computeScroll() {
super.computeScroll();
if (mScroller.computeScrollOffset()){ // Judge whether the drawing is completed
((View)getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();
}
}
computeScrollOffset() Judge whether the whole sliding is completed ,getCurrX(),getCurrY() Get the coordinates of the current slide . computeScroll Can't call directly , We go through invalidate()→draw()→computeScroll() The way , Indirect invocation .
- startScroll Start the sliding process .
You can usually use getScrollX(),getScrollY() Method to get content Coordinates of the point you slide to , The positive and negative of this value are scrollBy、scrollTo It's the same thing .
public void startScroll(int startX, int startY, int dx, int dy)
public void startScroll(int startX, int startY, int dx, int dy, int duration)
Example : Modify example 4 Code for , When the mobile phone leaves the screen , Let the child View Move smoothly to the initial position . Monitor fingers to leave , It needs to be monitored ACTION_UP
Events are all right , The key codes are as follows :
case MotionEvent.ACTION_UP:
View view = (View)getParent();
mScroller.startScroll(view.getScrollX(), view.getScrollY(),
-view.getScrollX(), -view.getScrollY());
invalidate();// notice View To redraw , To call computeScroll
break;
Scroller Add :Scroller Simple explanation of the principle .
- Scroller You can set different Interpolator Interpolator , Our last example is uniform sliding , We can set the interpolator to accelerate 、 Reduce , The effect of accelerating first and then reducing , There are countless functions between two points , All the effects we want to achieve are infinite .
- Scroller It cannot slide View, slide View Yes. scrollTo Method .
- startScroll Just initialize the attribute value .
- computeScrollOffset Used to judge whether the sliding is completed , It mainly works according to the interpolator and the time of occurrence , Update the current sliding coordinates (mCurrX, mCurrY).
6. Animation
Animation here is a simple explanation , The following chapters will explain animation in detail
- View animation ,xml Realization View Move
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:duration="3000"
android:toXDelta="500"
android:toYDelta="500"
/>
</set>
this.setAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.translate));
- View animation ,Java Realization View Move
TranslateAnimation animation = new TranslateAnimation( 0, 500, 0, 500);
this.setAnimation(animation);
animation.setDuration(3000);
animation.setFillAfter(true);
animation.startNow();
- Attribute animation
ObjectAnimator animatorX = ObjectAnimator.ofFloat(this, "translationX", 0, 500);
ObjectAnimator animatorY = ObjectAnimator.ofFloat(this, "translationY", 0, 500);
AnimatorSet animationSet = new AnimatorSet();
animationSet.setDuration(3000);
animationSet.playTogether(animatorX, animatorY);
animationSet.start();
7. ViewDragHelper
Later on
Reference blog
https://www.jianshu.com/p/543b88fa609c
https://blog.csdn.net/guolin_blog/article/details/48719871
边栏推荐
- Node の MongoDB Driver
- TDengine 已经支持工业英特尔 边缘洞见软件包
- Flutter development: a way to solve the problem of blank space on the top of listview
- 【OpenCV 例程200篇】219. 添加数字水印(盲水印)
- How to implement complex SQL such as distributed database sub query and join?
- Mobile heterogeneous computing technology GPU OpenCL programming (Advanced)
- [how to disable El table]
- Gradientdrawable get a single color
- Tutorial on building a framework for middle office business system
- [two objects merged into one object]
猜你喜欢
代码语言的魅力
Roll up, break through 35 year old anxiety, and animate the CPU to record the function call process
What are the advantages of the live teaching system to improve learning quickly?
How to improve the operation efficiency of intra city distribution
Tongweb set gzip
TDengine可通过数据同步工具 DataX读写
Lepton 无损压缩原理及性能分析
Community group buying has triggered heated discussion. How does this model work?
一文读懂TDengine的窗口查询功能
Analysis on the wallet system architecture of Baidu trading platform
随机推荐
Charm of code language
TDengine 离线升级流程
mysql80服务不启动
解决idea调试过程中liquibase – Waiting for changelog lock….导致数据库死锁问题
The comparison of every() and some() in JS uses a power storage plan
Unity skframework framework (XXIII), minimap small map tool
Tdengine connector goes online Google Data Studio app store
Thermometer based on STM32 single chip microcomputer (with face detection)
Idea debugs com intellij. rt.debugger. agent. Captureagent, which makes debugging impossible
[sourcetree configure SSH and use]
Analysis on the wallet system architecture of Baidu trading platform
[technical live broadcast] how to rewrite tdengine code from 0 to 1 with vscode
TDengine × Intel edge insight software package accelerates the digital transformation of traditional industries
【C语言】动态内存开辟的使用『malloc』
Fluent development: setting method of left and right alignment of child controls in row
90%的人都不懂的泛型,泛型的缺陷和应用场景
【el-table如何禁用】
Flutter development: a way to solve the problem of blank space on the top of listview
【技术直播】如何用 VSCode 从 0 到 1 改写 TDengine 代码
Why don't you recommend using products like mongodb to replace time series databases?