Android手写自定义修改TabLayout的选中文字大小,以及动画缩放工具。

我们先搞一下动画工具,如果你看我的文章,直接复制往代码里面,也可以试着理解代码的意思,不过不懂也可以照样用。有详尽的注释

缩放工具的功能,可以实现view,dialog,popup,tabLayout文字的缩放动画。

第一步新建接口文件 ScaleViewAnim.java
public interface ScaleViewAnim {

    ScaleViewAnim setScaleForPushInAnim(float scaleX, float scaleY);

    ScaleViewAnim setScaleForPopOutAnim(float scaleX, float scaleY);

    ScaleViewAnim setPushInAnimDuration(int timeInMillis);

    ScaleViewAnim setPopOutAnimDuration(int timeInMillis);

    ScaleViewAnim setInterpolatorPushIn(AccelerateDecelerateInterpolator interpolatorPushIn);

    ScaleViewAnim setInterpolatorPopOut(AccelerateDecelerateInterpolator interpolatorPopOut);

}

第二步继承。ScaleView.java, 注释很详细,如果不看过程,可以直接复制使用。
public class ScaleView implements ScaleViewAnim {

    // 属性的初始化
    public static final float PUSH_IN_SCALE_X = 0.9f;
    public static final float PUSH_IN_SCALE_Y = 0.9f;
    public static final float POP_OUT_SCALE_X = 1.1f;
    public static final float POP_OUT_SCALE_Y = 1.1f;
    public static final int PUSH_IN_ANIM_DURATION = 100;
    public static final int POP_OUT_ANIM_DURATION = 100;
    public static final AccelerateDecelerateInterpolator DEFAULT_INTERPOLATOR
            = new AccelerateDecelerateInterpolator();

    private WeakReference<View> view;
    private WeakReference<Dialog> dialog;
    private WeakReference<PopupWindow> popup;
    private WeakReference<TabLayout> tabLayout;
    private boolean isTouchInsideView = true;
    private float pushInScaleX = PUSH_IN_SCALE_X;
    private float pushInScaleY = PUSH_IN_SCALE_Y;
    private float popOutScaleX = POP_OUT_SCALE_X;
    private float popOutScaleY = POP_OUT_SCALE_Y;
    private int pushInAnimDuration = PUSH_IN_ANIM_DURATION;
    private int popOutAnimDuration = POP_OUT_ANIM_DURATION;
    private AccelerateDecelerateInterpolator pushInInterpolator = DEFAULT_INTERPOLATOR;
    private AccelerateDecelerateInterpolator popOutInterpolator = DEFAULT_INTERPOLATOR;



    // 这里是执行
    private ScaleView(View view) {
        this.view = new WeakReference<View>(view);
        if (this.view.get() != null) {
            //指定点击事件,需要先判断view的
            if(!this.view.get().hasOnClickListeners()) {
                this.view.get().setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                    }
                });
            }
        }
    }


    // dialog 初始化
    private ScaleView(Dialog dialog) {
        this.dialog = new WeakReference<Dialog>(dialog);
    }
    // popup 初始化
    private ScaleView(PopupWindow popup) {
        this.popup = new WeakReference<PopupWindow>(popup);
    }
    // tabLayout 初始化
    private ScaleView(TabLayout tabLayout) {
        this.tabLayout = new WeakReference<TabLayout>(tabLayout);
    }

    // 设置view的动画
    public static ScaleView addAnimTo(View view) {
        ScaleView bounceAnim = new ScaleView(view);
        bounceAnim.setAnimToView();
        return bounceAnim;
    }

    // 给dialog添加动画
    public static void addAnimTo(Dialog dialog) {
        ScaleView bounceAnim = new ScaleView(dialog);
        bounceAnim.setAnimToDialog();
    }

    // 给Popup添加动画
    public static void addAnimTo(PopupWindow popupWindow) {
        ScaleView bounceAnim = new ScaleView(popupWindow);
        bounceAnim.setAnimToPopup();
    }

    // 给tabLayout添加动画
    public static ScaleView addAnimTo(TabLayout tabLayout) {
        ScaleView bounceAnim = new ScaleView(tabLayout);
        bounceAnim.setAnimToTabLayout();
        return bounceAnim;
    }


    //设置缩放属性
    @Override
    public ScaleViewAnim setScaleForPushInAnim(float scaleX, float scaleY) {
        this.pushInScaleX = scaleX;
        this.pushInScaleY = scaleY;
        return this;
    }

    //设置缩放属性
    @Override
    public ScaleViewAnim setScaleForPopOutAnim(float scaleX, float scaleY) {
        this.popOutScaleX = scaleX;
        this.popOutScaleY = scaleY;
        return this;
    }

    //初始化设置缩放时间
    @Override
    public ScaleViewAnim setPushInAnimDuration(int timeInMillis) {
        this.pushInAnimDuration = timeInMillis;
        return this;
    }

    //初始化设置缩放时间
    @Override
    public ScaleViewAnim setPopOutAnimDuration(int timeInMillis) {
        this.popOutAnimDuration = timeInMillis;
        return this;
    }

    //初始化设置缩放加速器
    @Override
    public ScaleViewAnim setInterpolatorPushIn(AccelerateDecelerateInterpolator interpolatorPushIn) {
        this.pushInInterpolator = interpolatorPushIn;
        return this;
    }

    //初始化设置缩放加速器
    @Override
    public ScaleViewAnim setInterpolatorPopOut(AccelerateDecelerateInterpolator interpolatorPopOut) {
        this.popOutInterpolator = interpolatorPopOut;
        return this;
    }


    // 给view是设置动画
    private void setAnimToView() {
        if (view != null) {

            //设置view的触摸监听
            view.get().setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(final View v, MotionEvent motionEvent) {


                    int action = motionEvent.getAction();

                    //按下会执行一个缩放到0.9的动画。
                    if (action == MotionEvent.ACTION_DOWN) {
                        isTouchInsideView = true;

                        startAnimScale(v, pushInScaleX, pushInScaleY, pushInAnimDuration, pushInInterpolator, 0);

                        //抬起执行两个动画,缩放,放大
                    } else if (action == MotionEvent.ACTION_UP) {
                        if (isTouchInsideView) {
                            v.animate().cancel();

                            startAnimScale(v, popOutScaleX, popOutScaleY, popOutAnimDuration, popOutInterpolator, 0);

                            startAnimScale(v, 1f, 1f, popOutAnimDuration, popOutInterpolator, popOutAnimDuration + 1);

                            return false;
                        }
                        //触摸取消,执行放大动画
                    } else if (action == MotionEvent.ACTION_CANCEL) {
                        if (isTouchInsideView) {
                            v.animate().cancel();

                            startAnimScale(v, 1f, 1f, popOutAnimDuration, DEFAULT_INTERPOLATOR, 0);

                        }

                        return true;

                        //移动到view外面执行放大
                    } else if (action == MotionEvent.ACTION_MOVE) {
                        if (isTouchInsideView) {
                            float currentX = motionEvent.getX();
                            float currentY = motionEvent.getY();
                            float currentPosX = currentX + v.getLeft();
                            float currentPosY = currentY + v.getTop();
                            float viewLeft = v.getLeft();
                            float viewTop = v.getTop();
                            float viewRight = v.getRight();
                            float viewBottom = v.getBottom();
                            if (!(currentPosX > viewLeft && currentPosX < viewRight
                                    && currentPosY > viewTop && currentPosY < viewBottom)) {
                                isTouchInsideView = false;
                                v.animate().cancel();

                                startAnimScale(v, 1f, 1f, popOutAnimDuration, DEFAULT_INTERPOLATOR, 0);
                            }

                            return true;
                        }
                    }

                    return false;
                }
            });
        }
    }


    //这里执行动画。
    private void startAnimScale(View view, float scaleX, float scaleY,
                                int animDuration,
                                AccelerateDecelerateInterpolator interpolator,
                                int startDelay) {

        // 设置动画属性x,y
        ObjectAnimator animX = ObjectAnimator.ofFloat(view, "scaleX", scaleX);
        ObjectAnimator animY = ObjectAnimator.ofFloat(view, "scaleY", scaleY);

        //animatorSet 执行。
        AnimatorSet animatorSet = new AnimatorSet();
        animX.setDuration(animDuration);  //设置时间
        animX.setInterpolator(interpolator); // 默认的加速器
        animY.setDuration(animDuration);  //设置动画持续的时间
        animY.setInterpolator(interpolator); // 默认的加速器

        animatorSet.playTogether(animX, animY); // 一起执行动画
        animatorSet.setStartDelay(startDelay); //延时开始动画
        animatorSet.start();  //开始动画
    }


    //给Dialog设置动画
    private void setAnimToDialog() {
        if (dialog.get() != null) {
            Window dialogWindow = dialog.get().getWindow();
            dialogWindow.setWindowAnimations(R.style.CustomDialogAnimation);
        }
    }

    //给Popup设置动画
    private void setAnimToPopup() {
        if (popup.get() != null) {
            popup.get().setAnimationStyle(R.style.CustomDialogAnimation);
        }
    }

    //给TabLayout设置动画
    private void setAnimToTabLayout() {
        if (tabLayout.get() != null) {


            //给tab里面的view设置动画
            for(int i = 0; i < tabLayout.get().getTabCount(); i++) {

                final TabLayout.Tab tab = tabLayout.get().getTabAt(i);
                View tabView = ((ViewGroup) tabLayout.get().getChildAt(0)).getChildAt(i);

                tabView.setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent motionEvent) {

                        int action = motionEvent.getAction();

                        if (action == MotionEvent.ACTION_DOWN) {
                            isTouchInsideView = true;

                            startAnimScale(v, pushInScaleX, pushInScaleY, pushInAnimDuration, pushInInterpolator, 0);

                            return true;

                        } else if (action == MotionEvent.ACTION_UP) {
                            if (isTouchInsideView) {
                                v.animate().cancel();

                                startAnimScale(v, popOutScaleX, popOutScaleY, popOutAnimDuration, popOutInterpolator, 0);

                                startAnimScale(v, 1f, 1f, popOutAnimDuration, popOutInterpolator, popOutAnimDuration + 1);

                                tab.select();

                                return false;
                            }
                        } else if (action == MotionEvent.ACTION_CANCEL) {
                            if (isTouchInsideView) {
                                v.animate().cancel();

                                startAnimScale(v, 1f, 1f, popOutAnimDuration, DEFAULT_INTERPOLATOR, 0);

                            }

                            return true;
                        } else if (action == MotionEvent.ACTION_MOVE) {
                            if (isTouchInsideView) {
                                float currentX = motionEvent.getX();
                                float currentY = motionEvent.getY();
                                float currentPosX = currentX + v.getLeft();
                                float currentPosY = currentY + v.getTop();
                                float viewLeft = v.getLeft();
                                float viewTop = v.getTop();
                                float viewRight = v.getRight();
                                float viewBottom = v.getBottom();
                                if (!(currentPosX > viewLeft && currentPosX < viewRight
                                        && currentPosY > viewTop && currentPosY < viewBottom)) {
                                    isTouchInsideView = false;
                                    v.animate().cancel();

                                    startAnimScale(v, 1f, 1f, popOutAnimDuration, DEFAULT_INTERPOLATOR, 0);
                                }

                                return true;
                            }
                        }

                        return false;
                    }
                });
            }
        }
    }
}

dialog,和popupwindow 需要用布局文件的方式,所以我额外定义一个文件,用来处理这方面的问题。路径是 res/anim/scale_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator">

    <scale
        android:duration="75"
        android:fromXScale="1"
        android:fromYScale="1"
        android:toXScale="1.1"
        android:toYScale="1.1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:fillAfter="true"/>

    <scale
        android:duration="75"
        android:fromXScale="1.1"
        android:fromYScale="1.1"
        android:startOffset="75"
        android:toXScale="0.9803"
        android:toYScale="0.9803"
        android:pivotX="50%"
        android:pivotY="50%"/>
</set>

####然后在style.xml ,定义一个属性

    <style name="CustomDialogAnimation">
        <item name="android:windowEnterAnimation">@anim/bounce_anim</item>
    </style>

第三步开始使用。什么方法,什么作用,代码里面有注释。

普通的View,是这样用的

        ScaleView.addAnimTo(holder.listItem)
            .setPopOutAnimDuration(150)
            .setScaleForPushInAnim(.95f,.9f)
            .setScaleForPopOutAnim(1.05f,1.1f);

AlertDialog,是这样的

DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                getActivity().finish();
                break;

            case DialogInterface.BUTTON_NEGATIVE:
                dialog.dismiss();
                break;
        }
    }
};

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Alert Dialog")
        .setMessage("Do you want to exit?")
        .setPositiveButton("Yes", dialogClickListener)
        .setNegativeButton("No", dialogClickListener);
AlertDialog dialog = builder.create();

//Add animation to alert dialog
ScaleView.addAnimTo(dialog);        //Call before showing the dialog

dialog.show();

CustomDialog 是这样的实现的。

首先自定义一个 CustomDialog
public class CustomDialog extends Dialog implements
        View.OnClickListener {

    public Activity c;
    public Dialog d;
    public Button yes, no;

    public CustomDialog(Activity a) {
        super(a);
        this.c = a;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.custom_dialog);
        yes = (Button) findViewById(R.id.btn_yes);
        no = (Button) findViewById(R.id.btn_no);

        ScaleView.addAnimTo(yes);
        ScaleView.addAnimTo(no);

        yes.setOnClickListener(this);
        no.setOnClickListener(this);

        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.dimAmount = 0.0F;
        getWindow().setAttributes(lp);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_yes:
                c.finish();
                break;
            case R.id.btn_no:
                dismiss();
                break;
            default:
                break;
        }
        dismiss();
    }
}
布局文件 custom_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="300dp"
    android:layout_height="230dp"
    android:background="#5a7374"
    android:padding="8dp"
    android:layout_gravity="center">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="Custom Dialog"
        android:textAlignment="center"
        android:textColor="#ffffff"
        android:textStyle="bold"/>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#bde9f4"
        android:layout_marginTop="30dp">

        <TextView
            android:id="@+id/txt_dia"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="10dp"
            android:text="Do you realy want to exit ?"
            android:textSize="15dp"
            android:textStyle="bold"
            android:layout_centerHorizontal="true"
            android:paddingTop="45dp"/>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:orientation="horizontal"
            android:gravity="bottom"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:paddingBottom="20dp">

            <Button
                android:id="@+id/btn_no"
                android:layout_width="80dp"
                android:layout_height="30dp"
                android:background="#d21e1e"
                android:clickable="true"
                android:text="Cancel"
                android:textColor="#ffffff"
                android:textAllCaps="false"/>

            <Button
                android:id="@+id/btn_yes"
                android:layout_width="80dp"
                android:layout_height="30dp"
                android:layout_marginLeft="40dp"
                android:background="#00bcff"
                android:text="Yes"
                android:textColor="#ffffff"
                android:textAllCaps="false"/>
        </LinearLayout>

    </RelativeLayout>

</RelativeLayout>
使用
CustomDialog customDialog = new CustomDialog(getActivity());

//Add animation to custom dialog
ScaleView.addAnimTo(customDialog);        //Call before showing the dialog

customDialog.show();

PopupWindow 是这样使用的。

首先定义一个 布局文件 custom_popup.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="250dp"
    android:layout_height="85dp"
    android:background="#5a7374"
    android:padding="8dp">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="Popup window "
        android:textAlignment="center"
        android:textColor="#ffffff"
        android:textStyle="bold"/>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#bde9f4"
        android:layout_marginTop="30dp">

        <TextView
            android:id="@+id/txt_dia"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:text="Lorem Ipsum "
            android:textSize="15dp"
            android:textStyle="bold"
            android:layout_centerHorizontal="true"/>

    </RelativeLayout>

</RelativeLayout>
使用
PopupWindow popupWindow;
View menuView = getLayoutInflater().inflate(R.layout.custom_popup, null);
popupWindow = new PopupWindow(menuView, LinearLayout.LayoutParams.WRAP_CONTENT,
       LinearLayout.LayoutParams.WRAP_CONTENT, false);
int[] location = new int[2];
view.getLocationOnScreen(location);
popupWindow.setBackgroundDrawable(new BitmapDrawable());
popupWindow.setOutsideTouchable(true);


ScaleView.addAnimTo(popupWindow);       

popupWindow.showAtLocation(view, Gravity.CENTER,
       0, 0);

TabLayout是这样使用的

        //初始化tablayout
        final TabLayout tabLayout = findViewById(R.id.tabs);

        //给tabLayout添加动画
        ScaleView.addAnimTo(tabLayout);

接下来的是,自定义修改TabLayout的选中文字大小

        for (int i = 0; i < tabLayout.getTabCount(); i++) {

            final TabLayout.Tab tab = tabLayout.getTabAt(i);
            View tabView = ((ViewGroup) tabLayout.getChildAt(0)).getChildAt(i);

            TextView tabTabText = (TextView) LayoutInflater.from(this).inflate(R.layout.tab_layout, null);
            tabTabText.setText("Tab " + (i + 1));
//            tabTabText.setCompoundDrawablesWithIntrinsicBounds(0, iconsList[i], 0, 0);
            tabLayout.getTabAt(i).setCustomView(tabTabText);

            if (tab.isSelected()) {

                tabTabText.setTextSize(25.0f);
                tabView.setBackgroundColor(Color.parseColor("#404e4e"));
            } else {
                tabTabText.setTextSize(12.0f);
                tabView.setBackgroundColor(Color.parseColor("#5a7374"));
            }
        }


        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                View tabView = ((ViewGroup) tabLayout.getChildAt(0)).getChildAt(tab.getPosition());
                tabView.setBackgroundColor(Color.parseColor("#404e4e"));

                TextView customView = (TextView) tabLayout.getTabAt(tab.getPosition()).getCustomView();
                customView.setTextSize(25.0f);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                View tabView = ((ViewGroup) tabLayout.getChildAt(0)).getChildAt(tab.getPosition());
                tabView.setBackgroundColor(Color.parseColor("#5a7374"));

                TextView customView = (TextView) tabLayout.getTabAt(tab.getPosition()).getCustomView();
                customView.setTextSize(12.0f);
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

最后结语:如果你想实现腾讯视频顶部切换的话,文字背景是透明的,更改TabLayout的背景,只是做个参考。选中一个切换文字大小,背景大小,背景图片等等

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值