当前位置:网站首页>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 .

Android The screen

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 .
 Insert picture description here

To sum up :

  1. scrollBy Mobile is View Of content, If you want to move View, obtain ViewGroup, call scrollBy;
  2. 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);
  3. 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 .
Scroller Schematic diagram
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

原网站

版权声明
本文为[Anemone]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140535430277.html