Android 护眼模式的简单实现

此方法不涉及申请浮窗权限(用悬浮窗实现护眼模式,会涉及到优先级,然而高于系统弹框,部分机型系统弹框点击事件无效)

* Activity:获取content根布局,在上面添加一层浮层,默认透明,开启护眼模式设置护眼色值。

* Dialog:设置自定义布局,在其根布局,在上面添加一层浮层,默认透明,开启护眼模式设置护眼色值。

实现效果:

               eye-care gif

 

#1 对于BaseActivity:

public abstract class BaseActivity extends AppCompatActivity {

    private FrameLayout eyeCareView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final int view = getLayoutId();
        if (view != 0) {
            setContentView(view);
        }
        ButterKnife.bind(this);

        //添加一层浮层(初始化)
        initEye();

        initView();
    }

    public abstract int getLayoutId();

    protected void initView(){}

    @Override
    protected void onRestart() {
        super.onRestart();
        //onRestart中用来返回到已存在页面时,刷新护眼蒙层色值
        if (Constant.IS_EYE_CARE_OPEN){
            openEye();
        }else {
            closeEye();
        }
    }

    /**
     * 添加护眼模式浮层
     */
    private void initEye() {
        eyeCareView = new FrameLayout(this);
        if (Constant.IS_EYE_CARE_OPEN){
            openEye();
        }else {
            closeEye();
        }
        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
        params.width = WindowManager.LayoutParams.MATCH_PARENT;
        params.height = WindowManager.LayoutParams.MATCH_PARENT;
        getWindow().addContentView(eyeCareView, params);
    }

    /**
     * 开启护眼模式
     */
    public void openEye() {
        if (eyeCareView != null) {
            eyeCareView.setBackgroundColor(EyeCareColorUtil.getFilterColor(30));
        }
    }

    /**
     * 关闭护眼模式
     */
    public void closeEye() {
        if (eyeCareView != null) {
            eyeCareView.setBackgroundColor(Color.TRANSPARENT);
        }
    }
}

#2 设置护眼色值:

public class EyeCareColorUtil {
    /**
     * 过滤蓝光
     *
     * @param blueFilterPercent 蓝光过滤比例[10-30-80]
     */
    public static int getFilterColor(int blueFilterPercent) {
        int realFilter = blueFilterPercent;
        if (realFilter < 10) {
            realFilter = 10;
        } else if (realFilter > 80) {
            realFilter = 80;
        }
        int a = (int) (realFilter / 80f * 180);
        int r = (int) (200 - (realFilter / 80f) * 190);
        int g = (int) (180 - (realFilter / 80f) * 170);
        int b = (int) (60 - realFilter / 80f * 60);
        return Color.argb(a, r, g, b);
    }
}

#3 在Activity中开启或关闭护眼模式:

switch_eye_care.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // 每次 setChecked 时会触发onCheckedChanged 监听回调,而有时我们在设置setChecked后不想去自动触发 onCheckedChanged 里的具体操作,加上此判断
                if (buttonView.isPressed()) {
                    if (isChecked){
                        openEye();
                    }else {
                        closeEye();
                    }
                    Constant.IS_EYE_CARE_OPEN = isChecked;//保存状态
                }
            }
        });

以上完成了所有页面的护眼模式;但如果出现dialog时,因为dialog的弹出是在覆盖蒙层之上,所以我们还要对Dialog做护眼处理;

即护眼模式-适配Dialog:
#4 弹出Dialog:(根据具体项目需要去设置弹出弹框)

public static void showAlert(Context context, String message) {
        if (context == null || message.isEmpty()) {
            return;
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(context);

        LayoutInflater inflater = LayoutInflater.from(context);
        View layout = inflater.inflate(R.layout.dialog_custom_layout, null);
        FrameLayout eye_content = layout.findViewById(R.id.eye_content);
        TextView tv_title = layout.findViewById(R.id.tv_title);
        TextView tv_message = layout.findViewById(R.id.tv_message);
        TextView tv_ok = layout.findViewById(R.id.tv_ok);
        //设置护眼模式蒙层色值
        if (Constant.IS_EYE_CARE_OPEN) {
            eye_content.setBackgroundColor(EyeCareColorUtil.getFilterColor(30));
        } else {
            eye_content.setBackgroundColor(Color.TRANSPARENT);
        }

        tv_message.setText(message);
        builder.setView(layout);
        final AlertDialog mAlertDialog = builder.create();

        tv_ok.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mAlertDialog != null && mAlertDialog.isShowing())
                    mAlertDialog.dismiss();
            }
        });

        mAlertDialog.show();
    }

#5 自定义Dialog布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout android:id="@+id/dialog_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="50dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <TextView android:id="@+id/tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="标题测试"
            android:textSize="20sp" />

        <TextView android:id="@+id/tv_message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="内容测试"
            android:textSize="15sp" />

        <LinearLayout android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:orientation="vertical">

            <TextView android:id="@+id/tv_ok"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:background="@color/colorPrimary"
                android:padding="5dp"
                android:text="知道了"
                android:textColor="#FFFFFF"
                android:textSize="15sp" />
        </LinearLayout>
    </LinearLayout>

    <FrameLayout
        android:id="@+id/eye_content"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="@+id/dialog_content"
        app:layout_constraintEnd_toEndOf="@+id/dialog_content"
        app:layout_constraintStart_toStartOf="@+id/dialog_content"
        app:layout_constraintTop_toTopOf="@+id/dialog_content" />
</androidx.constraintlayout.widget.ConstraintLayout>


Git项目地址:EyeCareDemo

CSDN资源:源码下载


参考原文链接,感谢!!!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值