栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android 进阶 View体系和自定义View

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android 进阶 View体系和自定义View

3.View体系和自定义View 3.2坐标系 3.2.1 Android 坐标系

3.2.2 View坐标系

View的坐标系与Android的坐标系并不冲突,它们是共同存在的,它可以用来更好的控制View

1.View获取自身的宽高

算出View的宽和高的方法

  int width = button.getRight() - button.getLeft();
  int height = button.getBottom() - button.getTop();

View源码中的 getHight 方法和 getWidth 方法如下:

public final int getHeight(){
			return mBottom - mTop;
}

public final int getWidth(){
			return mRight - mLeft;
}

2.View自身的坐标

  • getTop() : 获取View顶部到父布局顶距离

  • getLeft() : 获取View左部到父布局左距离

  • getRight() : 获取View右部到父布局左距离

  • getBottom() : 获取View底部到父布局底距离

3.MotionEvent是为我们触摸点提供的方法

  • getX():点击事件距离控件左边的距离

  • getY():点击事件距离控件顶边的距离

  • getRawX():点击事件距离父布局左边的距离

  • getRawY():点击事件距离父布局顶边的距离

3.3View的滑动 3.3.1 自定义View 实现移动效果

CustomView

package com.study.c331viewmove;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import androidx.annotation.Nullable;

public class CustomView extends View {
    private int lastX;
    private int lastY;

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = x;
                lastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int offsetX = x - lastX;
                int offsetY = y - lastY;
                // 方法 1:调用 layout 方法来重新放置它的位置
//                layout(getLeft() + offsetX, getTop() + offsetY,
//                        getRight() + offsetX, getBottom() + offsetY);

                // 方法 2: offsetLeftAndRight() 和 offsetTopAndBottom()
//                offsetLeftAndRight(offsetX);
//                offsetTopAndBottom(offsetY);

                // 方法3: LayoutParams
                //  (1)父控件是 LinearLayout,用 LinearLayout.LayoutParams
                LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
                //  (2)如果父控件是RelativeLayout,用 RelativeLayout.LayoutParams
//                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
                //  (3)除了使用布局的 LayoutParams 外, 还可以使用 ViewGroup.MarginLayoutParams
//                ViewGroup.MarginLayoutParams layoutParams =  (ViewGroup.MarginLayoutParams) getLayoutParams();
//                layoutParams.leftMargin = getLeft() + offsetX;
//                layoutParams.topMargin = getTop() + offsetY;
//                setLayoutParams(layoutParams);

                // 方法4:scrollBy
                ((View) getParent()).scrollBy(-offsetX, -offsetY);
                break;
        }
        return true;

    }
}

ScrollerCustomView

package com.study.c331viewmove;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Scroller;

import androidx.annotation.Nullable;

public class ScrollerCustomView extends View {
    private Scroller mScroller;

    public ScrollerCustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mScroller = new Scroller(context);
    }

    public ScrollerCustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            ((View) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate(); // 重绘
        }
    }

    public void smoothScrollTo(int destX, int destY) {
        int scrollX = getScrollX();
        int delta = destX - scrollX;
        mScroller.startScroll(scrollX, 0, delta, 0, 2000);
        invalidate();// 重绘
    }
}

activity_main.xml




    

    

translate.xml



    
    

MainActivity.java

package com.study.c331viewmove;

import androidx.appcompat.app.AppCompatActivity;

import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.view.animation.AnimationUtils;

import com.study.c331viewmove.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding mBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(mBinding.getRoot());
        // 设置动画
        // 1.通过 xml 设置动画
//        mBinding.svCustomview.setAnimation(AnimationUtils.loadAnimation(this, R.anim.translate));
        // 2.通过 ObjectAnimator 设置动画
//        ObjectAnimator.ofFloat(mBinding.svCustomview, "translationX",0 , 300).setDuration(1000).start();
        // 3.通过 scrollBy设置位置。
//        mBinding.customview.scrollBy(-50, -50);
        // 4. ScrollerCustomView 通过 Scroller 设置动画
        mBinding.scvCustomview.smoothScrollTo(-400, 0);
    }
}
3.5 属性动画

由于 View 的动画发生后,其相应的位置依然在动画进行前的地方。所以谷歌推出了新的动画框架——AnimatorSet 和 ObjectAnimator。

1.ObjectAnimator

ObjectAnimator animator  =  ObjectAnimator.ofFloat(view, "translationX", 200);
animator.setDuration(300);
animator.start();

属性动画的属性值:

  • translationX 和 translationY:用来沿着 X 轴和 Y 轴进行平移。

  • rotation、rotationX 和 rotationY:用来围绕 View 的支点进行旋转。

  • PrivotX 和 PrivotY:控制 View 对象的支点位置,围绕这个支点进行旋转和缩放变换处理。默认位置是 View 对象的中心位置。

  • alpha:透明度,默认值是1(不透明),0 代表完全透明。

  • x 和 y :描述 View 对象在其容器中的最终位置。

MyView
package com.study.c34animation;

import android.view.View;

public class MyView {
    private View mTarget;

    public MyView(View targer) {
        super();
        mTarget = targer;
    }

    public int getWidth() {
        return mTarget.getLayoutParams().width;
    }

    public void setWidth(int width) {
        mTarget.getLayoutParams().width = width;
        mTarget.requestLayout();
    }
}
MainActivity.java
package com.study.c34animation;

import androidx.appcompat.app.AppCompatActivity;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.graphics.Path;
import android.os.Bundle;
import android.util.Log;

import com.study.c34animation.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding mBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(mBinding.getRoot());
        // 1.ObjectAnimator 实现变大显示
        MyView myViewOfSize = new MyView(mBinding.btnSize);
        ObjectAnimator.ofInt(myViewOfSize, "width", 500).setDuration(500).start();
        // 2.ValueAnimator 实现值的变化
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 100);
        valueAnimator.setTarget(mBinding.btnValue);
        valueAnimator.setDuration(5000).start();
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                Float num = (Float) valueAnimator.getAnimatedValue();
                mBinding.btnValue.setText(num.toString());
            }
        });
        // 3.实现透明度变化,并添加监听
        ObjectAnimator animator = ObjectAnimator.ofFloat(mBinding.btnAlpha, "alpha", 0, 1.5f);
        animator.setDuration(5000).start();
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {

            }

            @Override
            public void onAnimationEnd(Animator animator) {

            }

            @Override
            public void onAnimationCancel(Animator animator) {

            }

            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        });
        // 大部分比较关心 onAnimationEnd 事件
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }
        });
        // 4.组合动画
        // X轴移动
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(mBinding.btnAnimatorSet, "translationX", 0.0f, 200.0f, 200.0f);
        // Y轴移动
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(mBinding.btnAnimatorSet, "translationY", 0.0f, 200.0f, 200.0f);
        // 围绕X 来回转90°
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(mBinding.btnAnimatorSet, "rotationX", 0.0f, 90.0f, 0.0f);
        // 按x轴方向比例放大2倍
        ObjectAnimator animator4 = ObjectAnimator.ofFloat(mBinding.btnAnimatorSet, "scaleX", 1.0f, 2.0f);
        // 按Y轴方向比例放大2倍
        ObjectAnimator animator5 = ObjectAnimator.ofFloat(mBinding.btnAnimatorSet, "scaleY", 1.0f, 2.0f);
        AnimatorSet set = new AnimatorSet();
        set.setDuration(1000);
        // 现在的动画是 animator1,先播放 animator3 ,animator1 和 animator2 同时播放,之后在一起播放 animator5
        set.play(animator1).with(animator2).after(animator3).before(animator4);
        set.playTogether(animator4, animator5);// 也可以使用 playTogether 一起播放
        set.start();

        // 5.组合动画2 PropertyValuesHolder 的使用,只能做到多个动画一起执行
        PropertyValuesHolder valuesHolder1 = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 1.5f);
        PropertyValuesHolder valuesHolder2 = PropertyValuesHolder.ofFloat("rotationX", 0.0f, 90.0f, 0.0f);
        PropertyValuesHolder valuesHolder3 = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.3f, 1.0f);
        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(mBinding.btnPropertyValuesHolder,
                valuesHolder1, valuesHolder2, valuesHolder3);
        objectAnimator.setDuration(2000).start();

        // 6.使用 xml objectAnimator 实现动画
        Animator animatorXml = AnimatorInflater.loadAnimator(this, R.animator.scale);
        animatorXml.setTarget(mBinding.btnXml);
        animatorXml.start();
    }
}
scale.xml


END
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/693104.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号