FloatingView.java 10.7 KB
package com.wd.common.floatingview;


import android.animation.ValueAnimator;
import android.app.Activity;
import android.app.Application;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.constraintlayout.widget.Group;
import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;


import com.hjq.shape.builder.ShapeDrawableBuilder;
import com.hjq.shape.layout.ShapeConstraintLayout;
import com.wd.foundation.wdkit.base.BaseApplication;
import com.wd.common.widget.ForbidDragSeekBar;
import com.wd.common.widget.MarqueeNormalTextView;
import com.wd.fastcoding.base.R;
import com.wd.foundation.wdkit.utils.SpUtils;
import com.wd.foundation.wdkit.utils.UiUtils;
import com.wd.foundation.wdkitcore.tools.AppContext;
import com.wd.foundation.wdkitcore.tools.ArrayUtils;
import com.wd.foundation.wdkitcore.tools.ResUtils;

import java.lang.ref.WeakReference;
import java.util.List;

/**
 * 音频悬浮窗布局文件:关联功能音频频道页、音频专题页、音频详情页
 * @Author :张泽昊
 * @Email :1064771680@qq.com
 * @Date :$ $
 * @Description :
 */
public class FloatingView implements IFloatingView, FloatLifecycle.Callback {
    // 是否是第一次展示悬浮 ;
    private  boolean isFirst = true;
    private Application mApplication;
    private final DkFloatingView dkFloatingView;
    private final Class<? extends Activity>[] mFilterActivities;

    private WeakReference<FrameLayout> mContainer;

    /**
     * 音频悬浮是否展示
     */
    private boolean isShow = false;
    public boolean colseed = true;

    private boolean  isAudioFloatingIsShow = false;
    // 根布局
    private ShapeConstraintLayout clRoot;
    // 收起的视图集合
    private Group gPackUp;

    // 展开的视图集合
    private Group gUnfold;

    // 标题
    private MarqueeNormalTextView mtvTitle;

    // 当前时间和总时间
    private TextView tvTime;

    // 进度条
    private ForbidDragSeekBar seekBar;

    FloatingView(FloatWindow.Builder builder) {
        mApplication = builder.mContext;
        mFilterActivities = builder.mFilterActivities;
        dkFloatingView = new DkFloatingView(mApplication, builder.mLayoutId, builder.mLayoutParam);
        builder.mFloatLifecycle.listener(this);
        clRoot = dkFloatingView.findViewById(R.id.clRoot);
        gPackUp = dkFloatingView.findViewById(R.id.gPackUp);
        gUnfold = dkFloatingView.findViewById(R.id.gUnfold);
        mtvTitle = dkFloatingView.findViewById(R.id.mtvTitle);
        tvTime = dkFloatingView.findViewById(R.id.tvTime);
        seekBar = dkFloatingView.findViewById(R.id.seekBar);
    }
    @Override
    public void setAudioFloatingIsShow(boolean audioFloatingIsShow) {
        isAudioFloatingIsShow = audioFloatingIsShow;
    }

    @Override
    public boolean getAudioFloatingIsShow() {
        return isAudioFloatingIsShow;
    }

    @Override
    public boolean isFirst() {
        return isFirst;
    }

    @Override
    public boolean isShow() {
        return isShow;
    }

    @Override
    public void setFirst(boolean first) {
        isFirst = first;
    }

    @Override
    public void show(){
        if (!isAudioFloatingIsShow){
            hide();
            return;
        }
        isShow = true;
        addViewToWindow();

    }

    @Override
    public void forceShow(Activity activity) {
        if(FloatWindow.get() == null) {
            return;
        }
        FloatWindow.get().setAudioFloatingIsShow(true);
        activityAttach(activity);
        show();
    }

    @Override
    public void setColseed(boolean colseed) {
        this.colseed = colseed;
    }

    @Override
    public boolean getColseed() {
        return colseed;
    }

    @Override
    public void setExpand(boolean expand) {
        if(dkFloatingView != null){
            dkFloatingView.setExpand(expand);
        }
    }

    @Override
    public boolean isExpand() {
        if(dkFloatingView != null){
            return dkFloatingView.isExpand();
        }
        return false;
    }

    @Override
    public void packUpAnimation() {

        // 展示收起布局
        gPackUp.setVisibility(View.VISIBLE);
        gUnfold.setVisibility(View.GONE);

        // 根布局宽设为 60dp
        int viewWidth = (int) ResUtils.getResources().getDimension(R.dimen.rmrb_dp84);
        // 屏幕宽度
        float realWidth = (int) ResUtils.getResources().getDimension(R.dimen.rmrb_dp267);
        // 宽度动画,通过属性动画,模拟0-150毫秒
        ValueAnimator widthAnimator = ValueAnimator.ofFloat(realWidth, viewWidth);
        widthAnimator.setDuration(150);
        widthAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                // 动画值
                float animatedValue = (float) valueAnimator.getAnimatedValue();
                // 根布局宽度
                UiUtils.setWH(clRoot, (int) animatedValue, viewWidth);

            }
        });
        widthAnimator.start();
        if (FloatWindow.get() != null) {
            FloatWindow.get().setExpand(false);
        }
    }

    @Override
    public void hide(){
        isShow = false;
        detach(getContainer());
    }

    @Override
    public View getView() {
        return dkFloatingView.getView();
    }

    @Override
    public void setOnClickListener(DkFloatingView.ViewClickListener listener) {
        dkFloatingView.setOnClickListener(listener);
    }

    @Override
    public void activityAttach(Activity activity) {
        if (!isFilterActivity(activity)){
            List<Activity> activityList = BaseApplication.getInstance().getLifecycleCallbacks().getActivityList();
            if(ArrayUtils.isNotEmpty(activityList) && activityList.size() > 2 &&
                    (activity != BaseApplication.getInstance().getLifecycleCallbacks().current() &&
                            activity != BaseApplication.getInstance().getLifecycleCallbacks().before())){
                //解决二级activity语音播报控件不展示问题
                return;
            }
            attach(getActivityRoot(activity));
        }
    }

    @Override
    public void activityDetach(Activity activity) {
        if (!isFilterActivity(activity)) {
            List<Activity> activityList = BaseApplication.getInstance().getLifecycleCallbacks().getActivityList();
            if(ArrayUtils.isNotEmpty(activityList) && activityList.size() > 2 &&
                    (activity != BaseApplication.getInstance().getLifecycleCallbacks().current() &&
                            activity != BaseApplication.getInstance().getLifecycleCallbacks().before())){
                //解决二级activity语音播报控件不展示问题
                return;
            }
            detach(getActivityRoot(activity));
        }
    }

    private boolean isFilterActivity(Activity activity){
        if(mFilterActivities == null){
            return false;
        }
        for (Class<? extends Activity> mFilterActivity : mFilterActivities) {
            if (mFilterActivity.getName().equals(activity.getClass().getName())){
                return true;
            }
        }
        return false;
    }

    private void addViewToWindow() {
        if (getContainer() == null) {
            return;
        }
        if (dkFloatingView.getParent() != null) {
            ((ViewGroup) dkFloatingView.getParent()).removeView(dkFloatingView);
        }
        // 音频悬浮展示
        if (isShow && !ViewCompat.isAttachedToWindow(dkFloatingView) && isAudioFloatingIsShow) {
            refreshNightMode();
           //fixme 关闭语音播报悬浮窗VoiceEasyFloat.INSTANCE.dismiss(this);
            getContainer().addView(dkFloatingView);
        }
    }

    private void refreshNightMode(){
        ShapeDrawableBuilder shapeDrawableBuilder = clRoot.getShapeDrawableBuilder();
        // 页面适配夜间模式
        if (SpUtils.isNightMode()) { // 夜间
            // 根布局
            shapeDrawableBuilder.setSolidColor(ContextCompat.getColor(AppContext.getContext(),
                    R.color.res_color_general_262626));
            // 标题
            mtvTitle.setTextColor(ContextCompat.getColor(AppContext.getContext(), R.color.res_color_general_DDDDDD));
            // 时间
            tvTime.setTextColor(ContextCompat.getColor(AppContext.getContext(), R.color.res_color_common_C2_keep));
            Drawable mThumbDragDrawable = ContextCompat.getDrawable(AppContext.getContext(), R.drawable.mglayoutnew_mini_audio_seekbar_night);
            seekBar.setProgressDrawable(mThumbDragDrawable);
        }else {
            //日间
            shapeDrawableBuilder.setSolidColor(ContextCompat.getColor(AppContext.getContext(),
                    R.color.res_color_common_C8_keep));
            // 标题
            mtvTitle.setTextColor(ContextCompat.getColor(AppContext.getContext(), R.color.res_color_common_C1_keep));
            // 时间
            tvTime.setTextColor(ContextCompat.getColor(AppContext.getContext(), R.color.res_color_common_C3_keep));
            Drawable mThumbDragDrawable = ContextCompat.getDrawable(AppContext.getContext(),
                    R.drawable.mglayoutnew_mini_audio_seekbar_keep);
            seekBar.setProgressDrawable(mThumbDragDrawable);
        }
        shapeDrawableBuilder.intoBackground();
    }

    private FrameLayout getContainer() {
        if (mContainer == null) {
            return null;
        }
        return mContainer.get();
    }

    private FrameLayout getActivityRoot(Activity activity) {
        if (activity == null) {
            return null;
        }
        try {
            return (FrameLayout) activity.getWindow().getDecorView().findViewById(android.R.id.content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private void attach(FrameLayout container) {
        if (getContainer() != null) {
            mContainer.clear();
        }
        mContainer = new WeakReference<>(container);
        if (!isAudioFloatingIsShow){
            hide();
            return;
        }
        addViewToWindow();
    }
    private void detach(FrameLayout container) {
//        setFirst(true);
        ViewParent parent = dkFloatingView.getParent();
        if(parent != null){
            String name = parent.getClass().getSimpleName();
            if(name != null){

            }
        }
        if (container != null && dkFloatingView.getParent() == container){
            container.removeView(dkFloatingView);
        }
        if (getContainer() != null && getContainer() == container) {
            mContainer.clear();
            mContainer = null;
        }
    }

}