先看效果:
Android 11在app中修改屏幕亮度 展示视频
可以看到,这是一个非常简单的功能,拖动进度条,屏幕亮度随即变化,界面上也实时更新亮度值
实现部分:
一、布局文件
1.activity_brightness.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="viewModel"
type="com.example.mvvmdemo.ui.brightness.BrightnessViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.brightness.BrightnessActivity">
<Button
android:id="@+id/btn_config"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="调节亮度"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_brightness"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.2" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
2.popup_window_brightness.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- PopupWindow布局,包含一个进度条 -->
<SeekBar
android:id="@+id/sb_popup_brightness"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="50" />
</LinearLayout>
二、ViewModel层代码
/**
* 亮度视图模型类,用于管理应用程序中的亮度设置和权限状态。
*/
public class BrightnessViewModel extends ViewModel {
// 亮度值的LiveData对象,初始值为50
private MutableLiveData<Integer> brightnessValue = new MutableLiveData<>(50);
/**
* 设置亮度值。
*
* @param value 要设置的亮度值。
*/
public void setBrightness(int value) {
brightnessValue.setValue(value);
}
/**
* 获取当前的亮度值。
*
* @return LiveData对象,包含当前的亮度值。
*/
public LiveData<Integer> getBrightness() {
return brightnessValue;
}
}
ViewModel层代码主要是定义了一个可观测的参数:亮度值
三 、Activity代码
/**
* 该活动类用于控制和显示屏幕亮度。
*/
public class BrightnessActivity extends AppCompatActivity {
private ActivityBrightnessBinding binding; // 数据绑定实例
private BrightnessViewModel viewModel; // 亮度视图模型
private PopupWindow popupWindow; // 弹出窗口实例
/**
* 活动创建时调用。
* 初始化界面、设置监听器、获取视图模型并绑定数据。
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this); // 启用边缘到边缘的UI
binding = DataBindingUtil.setContentView(this, R.layout.activity_brightness); // 设置布局
// 设置视图的内边距,以适应系统边框
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
viewModel = new ViewModelProvider(this).get(BrightnessViewModel.class); // 获取视图模型实例
binding.setViewModel(viewModel); // 绑定视图模型
initObserver(); // 初始化观察者
binding.btnConfig.setOnClickListener(v -> {
showPopup(); // 显示设置弹窗
});
}
/**
* 初始化亮度值的观察者。
*/
private void initObserver(){
viewModel.getBrightness().observe(this, brightness -> {
binding.tvBrightness.setText(String.valueOf(brightness)); // 更新界面显示的亮度值
});
}
/**
* 显示亮度设置的弹出窗口。
*/
private void showPopup() {
// 加载弹窗布局
View popupView = LayoutInflater.from(this).inflate(R.layout.popup_window_brightness, null);
SeekBar sbPopupBrightness = popupView.findViewById(R.id.sb_popup_brightness);
// 创建并显示弹窗
popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
popupWindow.showAtLocation(findViewById(android.R.id.content), Gravity.BOTTOM, 0, 40);
// 设置弹窗中的亮度条进度,并监听进度改变事件
sbPopupBrightness.setProgress(viewModel.getBrightness().getValue());
sbPopupBrightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
viewModel.setBrightness(progress); // 更新视图模型中的亮度值
// 动态设置当前窗口的亮度
Window window = getWindow();
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.screenBrightness = getBrightness(progress); // 转换进度为亮度值
window.setAttributes(layoutParams);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// 触摸开始时的操作
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// 触摸结束时的操作
}
});
}
/**
* 根据进度值获取相应的亮度值。
*
* @param progress 亮度条的进度值
* @return 转换后的亮度值(0.01f到1.0f之间)
*/
private float getBrightness(int progress) {
if (progress == 0) {
return 0.01f; // 避免除以0
}
return progress / 100f; // 将进度值转换为0.0f到1.0f之间的亮度值
}
}
整体的功能实现到此就结束了
四、写在最后
1.测试发现,当亮度值为0.0f的时候,屏幕并不会黑屏。这可能是系统对屏幕亮度最小值有限制,以避免用户无法操作或查看屏幕内容,所以,我这里进行了一些处理
if (progress == 0) {
return 0.01f; // 避免除以0
}
2.以上对于屏幕亮度的操作,均是对于app而言的,如果想要调节系统亮度,还需要申请运行时权限:
<uses-permission android:name="android.permission.WRITE_SETTINGS" />