getResources().getDrawable(int id) 替代

在Android开发中,由于getDrawable()方法在5.1及以上版本被弃用,需使用ContextCompat类进行替代。本文介绍了如何使用ContextCompat来适配不同版本的系统,提供兼容性解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前段时间在开发过程中用到了getDrawable方法,但是发现该方法被屏蔽掉了,
该方法已经不推荐了

替代方法

查看代码和在官网查询后发现为了适配5.1以上系统,官方新提供了这么一个ContextCompat类来进行之前操作
这里写图片描述

查看代码发现api在版本21也就是 5.0时给出了新的方法 但是为了支持之前的方法所以进行了整理
代码奉上

/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.support.v4.content;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Process;
import android.support.annotation.NonNull;
import android.support.v4.os.EnvironmentCompat;
import android.util.Log;

import java.io.File;

/**
 * Helper for accessing features in {@link android.content.Context}
 * introduced after API level 4 in a backwards compatible fashion.
 */
public class ContextCompat {
    private static final String TAG = "ContextCompat";

    private static final String DIR_ANDROID = "Android";
    private static final String DIR_DATA = "data";
    private static final String DIR_OBB = "obb";
    private static final String DIR_FILES = "files";
    private static final String DIR_CACHE = "cache";

    /**
     * Start a set of activities as a synthesized task stack, if able.
     *
     * <p>In API level 11 (Android 3.0/Honeycomb) the recommended conventions for
     * app navigation using the back key changed. The back key's behavior is local
     * to the current task and does not capture navigation across different tasks.
     * Navigating across tasks and easily reaching the previous task is accomplished
     * through the "recents" UI, accessible through the software-provided Recents key
     * on the navigation or system bar. On devices with the older hardware button configuration
     * the recents UI can be accessed with a long press on the Home key.</p>
     *
     * <p>When crossing from one task stack to another post-Android 3.0,
     * the application should synthesize a back stack/history for the new task so that
     * the user may navigate out of the new task and back to the Launcher by repeated
     * presses of the back key. Back key presses should not navigate across task stacks.</p>
     *
     * <p>startActivities provides a mechanism for constructing a synthetic task stack of
     * multiple activities. If the underlying API is not available on the system this method
     * will return false.</p>
     *
     * @param context Start activities using this activity as the starting context
     * @param intents Array of intents defining the activities that will be started. The element
     *                length-1 will correspond to the top activity on the resulting task stack.
     * @return true if the underlying API was available and the call was successful, false otherwise
     */
    public static boolean startActivities(Context context, Intent[] intents) {
        return startActivities(context, intents, null);
    }

    /**
     * Start a set of activities as a synthesized task stack, if able.
     *
     * <p>In API level 11 (Android 3.0/Honeycomb) the recommended conventions for
     * app navigation using the back key changed. The back key's behavior is local
     * to the current task and does not capture navigation across different tasks.
     * Navigating across tasks and easily reaching the previous task is accomplished
     * thr
package com.example.suyzeko.fragment; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.viewpager2.widget.ViewPager2; import android.os.Handler; import android.os.IBinder; import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.widget.Button; import android.widget.ImageButton; import android.widget.PopupWindow; import android.widget.TextView; import android.widget.Toast; import com.example.suyzeko.MainActivity; import com.example.suyzeko.activitys.ledPanel.sixRoads.DeviceDetailsActivity; import com.example.suyzeko.activitys.ledPanel.twoRoads.PhototherapyBoardTwoActivity; import com.example.suyzeko.R; import com.example.suyzeko.SelectDeviceActivity; import com.example.suyzeko.activitys.therapyHelmet.fourZones.TherapyHelmetFourActivity; import com.example.suyzeko.activitys.therapyHelmet.nineteenZones.TherapyHelmetNineteenActivity; import com.example.suyzeko.entity.Device; import com.example.suyzeko.entity.DeviceClass; import com.example.suyzeko.service.BluetoothService; import com.example.suyzeko.utils.BannerAdapter; import com.example.suyzeko.utils.DeviceUtils; import com.example.suyzeko.utils.RetrofitAPI; import com.example.suyzeko.utils.RetrofitClient; import com.google.android.flexbox.FlexboxLayout; import java.util.Arrays; import java.util.List; import java.util.Objects; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public class DashboardFragment extends Fragment{ private ViewPager2 viewPager; private FlexboxLayout flexboxContainer; private int buttonCount = 0; private View maskView; // 遮罩层视图 private PopupWindow popupWindow; private final Handler autoScrollHandler = new Handler(); private ImageButton btnAdd; private TextView textView; private BluetoothService bluetoothService; // 蓝牙后台服务实例 private final Runnable autoScrollRunnable = new Runnable() { @Override public void run() { if (viewPager != null) { int currentItem = viewPager.getCurrentItem(); viewPager.setCurrentItem(currentItem + 1, true); autoScrollHandler.postDelayed(this, 3000); // 3秒切换一次 } } }; private boolean isBound = false; private float flexBasisPercent = 0.4f; private int buttonHeight = 90; /** * 服务连接回调 */ private final ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { try { BluetoothService.LocalBinder binder = (BluetoothService.LocalBinder) service; bluetoothService = binder.getService(); isBound = true; registerReceivers(); // 注册广播接收器 } catch (SecurityException e) { throw new RuntimeException(e); } } @Override public void onServiceDisconnected(ComponentName name) { isBound = false; } }; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_dashboard, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (DeviceUtils.isTablet(requireActivity())) { flexBasisPercent = 0.22f; buttonHeight = 110; } else { // 手机设备 } viewPager = view.findViewById(R.id.viewPager); textView = view.findViewById(R.id.device_num); // 示例图片列表 List<Integer> images = Arrays.asList( R.drawable.ontc, R.drawable.offtc ); // 绑定服务 if (bluetoothService != null){ Intent intentBlue = new Intent(getActivity(), BluetoothService.class); bluetoothService.bindService(intentBlue, connection, Context.BIND_AUTO_CREATE); } // 初始化适配器并绑定 BannerAdapter adapter = new BannerAdapter(images); viewPager.setAdapter(adapter); // 设置初始位置(从中间开始,支持向左滑动) viewPager.setCurrentItem(Integer.MAX_VALUE / 2, false); // 自动轮播 autoScrollHandler.postDelayed(autoScrollRunnable, 3000); // 页面切换监听(可选) viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { // 可以在此处理指示器逻辑 } }); flexboxContainer = view.findViewById(R.id.flexbox_container); // 初始化检查:如果没有按钮,显示添加按钮 checkAndShowAddButton(); // 获取加号按钮 btnAdd = view.findViewById(R.id.add_image_button); // 设置点击事件 btnAdd.setOnClickListener(this::showPopupMenu); } @Override public void onAttach(@NonNull Context context) { super.onAttach(context); if (context instanceof OnJumpToActivityListener) { onJumpToActivityListener = (OnJumpToActivityListener) context; } else { throw new RuntimeException("宿主 Activity 需实现 OnJumpToActivityListener"); } } @Override public void onResume(){ super.onResume(); loadActivity(); updateConnectionStatus(); } @Override public void onDestroyView() { super.onDestroyView(); autoScrollHandler.removeCallbacks(autoScrollRunnable); // 防止内存泄漏 // 确保 Fragment 销毁时移除遮罩 removeMask(); super.onDestroy(); } /** * 显示/隐藏"添加按钮"的逻辑 */ private void checkAndShowAddButton() { if (buttonCount == 0) { // 创建"添加按钮" Button addButton = new Button(requireContext()); addButton.setTextColor(Color.parseColor("#2A2A2A")); addButton.setBackgroundResource(R.drawable.button_style); // 可自定义样式 addButton.setText(getString(R.string.add)); // 布局参数 FlexboxLayout.LayoutParams params = new FlexboxLayout.LayoutParams( FlexboxLayout.LayoutParams.WRAP_CONTENT, FlexboxLayout.LayoutParams.WRAP_CONTENT ); params.setFlexBasisPercent(flexBasisPercent); params.setHeight(dpToPx(buttonHeight)); params.setMargins(32, 16, 32, 16); // 点击事件:开始添加普通按钮 addButton.setOnClickListener(v -> { onJumpToActivityListener.jumpToActivityAndClose();// 跳转到搜索设备页面 // navigateToNewActivity(); }); buttonCount++; flexboxContainer.addView(addButton, params); } } private List<Device> deviceLists; /** * 添加动态按钮的方法 * @param deviceList */ public void addNewButton(List<Device> deviceList) { for (Device device:deviceList){ int flag = 0; if(deviceLists != null){ for (Device device1:deviceLists){ if (device1.getDeviceMac().equals(device.getDeviceMac())) { flag = 1; break; } } } if (flag == 1){ continue; } buttonCount++; DeviceClass deviceTypeResources = getDeviceTypeResources(device.getDeviceClassCode()); Button newButton = new Button(requireContext()); newButton.setTag(device); newButton.post(() -> { // 获取按钮实际宽高(单位:像素) int buttonWidth = newButton.getWidth(); int buttonHeight = newButton.getHeight(); // 动态计算文字大小(示例:按钮宽度的 1/6) float textSizePx = buttonWidth / 20f; // 转换为 sp 单位(更符合用户习惯) float textSizeSp = pxToSp(textSizePx); // 设置文字大小 newButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeSp); }); // 创建状态图标层叠Drawable Drawable statusIcon = createStatusIcon(device); newButton.setText(device.getDeviceName()); // 获取设备类型对应的图标资源 Drawable icon = ContextCompat.getDrawable(requireContext(), deviceTypeResources.getIconRes()); // 计算按钮实际高度(从布局参数获取) int buttonHeightPx = dpToPx(buttonHeight); // 需与布局中params.setHeight(dpToPx(90))一致 // 设置图标尺寸为按钮高度的60%(按需调整比例) int iconSize = (int) (buttonHeightPx * 0.6); if (icon != null) { // 保持图标宽高比 float aspectRatio = (float) icon.getIntrinsicWidth() / icon.getIntrinsicHeight(); int scaledWidth = (int) (iconSize * aspectRatio); icon.setBounds(0, 0, scaledWidth, iconSize); // 设置绘制区域 } // 设置图标到按钮左侧 newButton.setCompoundDrawables(statusIcon, icon, null, null); newButton.setCompoundDrawablePadding(8); newButton.setBackgroundResource(R.drawable.button_style); newButton.setTextColor(Color.parseColor("#2A2A2A")); // 布局参数(与之前相同) FlexboxLayout.LayoutParams params = new FlexboxLayout.LayoutParams( FlexboxLayout.LayoutParams.WRAP_CONTENT, FlexboxLayout.LayoutParams.WRAP_CONTENT ); params.setFlexBasisPercent(flexBasisPercent); params.setHeight(dpToPx(buttonHeight)); params.setMargins(32, 16, 32, 16); // 点击事件 newButton.setOnClickListener(v -> { if (bluetoothService != null && bluetoothService.getConnectedDevice() != null){ if(device.getDeviceMac().equals(bluetoothService.getMACAddress())){ navigateToNewDeviceDetailsActivity(device); }else { new AlertDialog.Builder(getContext()) .setTitle("Device not connected") .setMessage("Do you want to redirect to the device connection page") // 确认按钮 .setPositiveButton(getString(R.string.OK), (dialog, which) -> { onJumpToActivityListener.jumpToActivityAndClose(); // 跳转到搜索设备页面 }) // 取消按钮 .setNegativeButton(getString(R.string.Cancel), (dialog, which) -> { dialog.dismiss(); }) .show(); } }else { new AlertDialog.Builder(getContext()) .setTitle("Device not connected") .setMessage("Do you want to redirect to the device connection page") // 确认按钮 .setPositiveButton(getString(R.string.OK), (dialog, which) -> { onJumpToActivityListener.jumpToActivityAndClose(); // 跳转到搜索设备页面 }) // 取消按钮 .setNegativeButton(getString(R.string.Cancel), (dialog, which) -> { dialog.dismiss(); }) .show(); } }); // // 长按删除(增加删除后的检查) // newButton.setOnLongClickListener(v -> { // flexboxContainer.removeView(v); // buttonCount--; // checkAndShowAddButton(); // 删除后检查是否需要恢复"添加按钮" // return true; // }); // 将新按钮添加到第一个 flexboxContainer.addView(newButton, 0, params); // --- 关键修改:强制刷新父容器和滚动视图 --- flexboxContainer.post(new Runnable() { @Override public void run() { flexboxContainer.requestLayout(); // 触发 NestedScrollView 重新计算滚动范围 ViewParent parent = flexboxContainer.getParent(); if (parent instanceof ViewGroup) { ((ViewGroup) parent).requestLayout(); } } }); } textView.setText(String.valueOf(buttonCount-1)); } public void updateConnectionStatus() { for (int i = 0; i < flexboxContainer.getChildCount() - 1; i++) { View view = flexboxContainer.getChildAt(i); if (view instanceof Button) { Button btn = (Button) view; Device device = (Device) btn.getTag(); Drawable newStatus = createStatusIcon(device); DeviceClass deviceTypeResources = getDeviceTypeResources(device.getDeviceClassCode()); // 获取设备类型对应的图标资源 Drawable icon = ContextCompat.getDrawable(requireContext(), deviceTypeResources.getIconRes()); // 计算按钮实际高度(从布局参数获取) int buttonHeightPx = dpToPx(buttonHeight); // 设置图标尺寸为按钮高度的60%(按需调整比例) int iconSize = (int) (buttonHeightPx * 0.6); if (icon != null) { // 保持图标宽高比 float aspectRatio = (float) icon.getIntrinsicWidth() / icon.getIntrinsicHeight(); int scaledWidth = (int) (iconSize * aspectRatio); icon.setBounds(0, 0, scaledWidth, iconSize); // 设置绘制区域 } // 设置图标到按钮左侧 btn.setCompoundDrawables(newStatus, icon, null, null); btn.postInvalidate(); // 线程安全刷新 } } } public void updateUnConnectionStatus() { for (int i = 0; i < flexboxContainer.getChildCount() - 1; i++) { View view = flexboxContainer.getChildAt(i); if (view instanceof Button) { Button btn = (Button) view; Device device = (Device) btn.getTag(); if(bluetoothService!= null && device.getDeviceMac().equals(bluetoothService.getMACAddress())){ bluetoothService.disconnect(); Drawable newStatus = createStatusIcon(device); DeviceClass deviceTypeResources = getDeviceTypeResources(device.getDeviceClassCode()); // 获取设备类型对应的图标资源 Drawable icon = ContextCompat.getDrawable(requireContext(), deviceTypeResources.getIconRes()); // 计算按钮实际高度(从布局参数获取) int buttonHeightPx = dpToPx(buttonHeight); // 设置图标尺寸为按钮高度的60%(按需调整比例) int iconSize = (int) (buttonHeightPx * 0.6); if (icon != null) { // 保持图标宽高比 float aspectRatio = (float) icon.getIntrinsicWidth() / icon.getIntrinsicHeight(); int scaledWidth = (int) (iconSize * aspectRatio); icon.setBounds(0, 0, scaledWidth, iconSize); // 设置绘制区域 } // 设置图标到按钮左侧 btn.setCompoundDrawables(newStatus, icon, null, null); btn.postInvalidate(); // 线程安全刷新 } } } } private Drawable createStatusIcon(Device device) { // 获取状态图标资源 int statusRes = isDeviceConnected(device) ? R.drawable.ic_connected_green_round : R.drawable.ic_disconnected_hui_round; // 创建缩放后的状态图标 Drawable statusIcon = ContextCompat.getDrawable(requireContext(), statusRes); int statusSize = dpToPx(12); // 状态图标尺寸 if (statusIcon != null) { statusIcon.setBounds(0, 0, statusSize, statusSize); } return statusIcon; } private boolean isDeviceConnected(Device device) { return bluetoothService != null && bluetoothService.getConnectedDevice() != null && device.getDeviceMac().equals(bluetoothService.getMACAddress()); } /** * 定义类型映射关系 * @param * @return */ private DeviceClass getDeviceTypeResources(String deviceClassCode) { DeviceClass deviceClass; if(deviceClassCode.equals("5A A5 01 01")){ deviceClass = new DeviceClass(0,R.drawable.up_down_black, "ELEVATING WHIRLING LED PANEL"); }else if(deviceClassCode.equals("5A A5 02 02")){ deviceClass = new DeviceClass(1,R.drawable.ontc, "红光床"); }else { deviceClass = new DeviceClass(2,R.drawable.up_down_black, "ELEVATING WHIRLING LED PANEL"); } return deviceClass; } /** * 弹出菜单 * @param anchorView */ public void showPopupMenu(View anchorView) { // 初始化布局 View popupView = LayoutInflater.from(requireContext()).inflate(R.layout.menu_popup_layout, null); // 创建 PopupWindow popupWindow = new PopupWindow( popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true ); // 设置背景和动画 popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); popupWindow.setElevation(8); // 阴影效果 popupWindow.setAnimationStyle(R.style.PopupAnimation); // 自定义动画 // 处理菜单项点击 popupView.findViewById(R.id.menu_item_add).setOnClickListener(v -> { // 处理“添加设备”逻辑 popupWindow.dismiss(); navigateToNewActivity(); }); popupView.findViewById(R.id.menu_item_scan).setOnClickListener(v -> { // 处理“扫一扫”逻辑 popupWindow.dismiss(); }); // 添加遮罩层 addMask(); // 设置 PopupWindow 关闭时移除遮罩 popupWindow.setOnDismissListener(() -> removeMask()); // 显示菜单(相对于锚点视图) popupWindow.showAsDropDown(anchorView, dpToPx(-130), dpToPx(15), Gravity.END); } /** * 将遮罩层添加到 Activity 的根布局 */ private void addMask() { if (getActivity() == null) return; ViewGroup rootView = (ViewGroup) getActivity().getWindow().getDecorView(); maskView = LayoutInflater.from(getContext()).inflate(R.layout.layout_background_mask, null); rootView.addView(maskView); } /** * 移除遮罩层 */ private void removeMask() { if (getActivity() == null || maskView == null) return; ViewGroup rootView = (ViewGroup) getActivity().getWindow().getDecorView(); rootView.removeView(maskView); maskView = null; } /** * 跳转查找设备Activity */ private void navigateToNewActivity() { if (getActivity() == null) return; // 避免 Fragment 未附加到 Activity 时崩溃 Intent intent = new Intent(getActivity(), SelectDeviceActivity.class); startActivity(intent); } /** * 跳转到新 Activity * @param device */ private void navigateToNewDeviceDetailsActivity(Device device) { if (getActivity() == null) return; // 避免 Fragment 未附加到 Activity 时崩溃 if(device.getDeviceClassCode().equals("5A A5 01 02")){ Intent intent = new Intent(getActivity(), PhototherapyBoardTwoActivity.class); intent.putExtra("devices",device); startActivity(intent); }else if(device.getDeviceClassCode().equals("5A A5 01 01")){ Intent intent = new Intent(getActivity(), DeviceDetailsActivity.class); intent.putExtra("devices",device); startActivity(intent); }else if(device.getDeviceClassCode().equals("5A A5 02 01")){ Intent intent = new Intent(getActivity(), TherapyHelmetFourActivity.class); intent.putExtra("devices",device); startActivity(intent); }else if(device.getDeviceClassCode().equals("5A A5 02 05")){ Intent intent = new Intent(getActivity(), TherapyHelmetNineteenActivity.class); intent.putExtra("devices",device); startActivity(intent); } } /** * 像素转 sp * @param px * @return */ private float pxToSp(float px) { return px / getResources().getDisplayMetrics().scaledDensity; } /** * dp 转像素工具方法 */ private int dpToPx(int dp) { float density = getResources().getDisplayMetrics().density; return Math.round(dp * density); } /** * 获取用户设备列表 */ private void loadActivity() { // 创建Retrofit服务实例 RetrofitAPI api = RetrofitClient.getClient(getActivity()).create(RetrofitAPI.class); // 发起异步请求 api.deviceFindAll().enqueue(new Callback<List<Device>>() { @Override public void onResponse(Call<List<Device>> call, Response<List<Device>> response) { if (response.isSuccessful() && response.body() != null) { addNewButton(response.body()); deviceLists = response.body(); } } @Override public void onFailure(Call<List<Device>> call, Throwable t) { if (getActivity() != null) { Toast.makeText(getContext(), "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show(); // // todo 离线 // DevicesRepository devicesRepository = new DevicesRepository(getActivity()); // List<Devices> deviceByUsername = devicesRepository.getDevicesByUserId(1L); // List<Device> list = new ArrayList<>(); // for (Devices devices:deviceByUsername){ // Device device = new Device(); // device.setDeviceMac(devices.getDeviceMac()); // device.setDeviceName(devices.getDeviceName()); // device.setDeviceClassCode(String.valueOf(devices.getDeviceClassId())); // device.setUserId(devices.getUserId()); // list.add(device); // } // addNewButton(list); // deviceLists = list; // // / } } }); } /** * 注册本地广播接收器 * 用于接收来自BluetoothService的事件 */ private void registerReceivers() { IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothService.ACTION_CONNECTION_STATUS); // 连接状态变化 LocalBroadcastManager.getInstance(getActivity()) .registerReceiver(btReceiver, filter); // 注册广播接收器 } /** * 蓝牙事件广播接收器 * 处理三种事件: * 1. 发现新设备 - 更新设备列表 * 2. 连接状态变化 - 更新UI状态 * 3. 接收到数据 - 显示在消息框 */ private final BroadcastReceiver btReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { try { String action = intent.getAction(); if (BluetoothService.ACTION_CONNECTION_STATUS.equals(action)) { // 更新连接状态显示 String status = intent.getStringExtra(BluetoothService.EXTRA_STATUS); if(status.equals("DISCONNECTED")){ updateUnConnectionStatus(); } } } catch (SecurityException e) { throw new RuntimeException(e); } } }; @Override public void onStart() { super.onStart(); Intent intent = new Intent(getActivity(), BluetoothService.class); getActivity().bindService(intent, connection, Context.BIND_AUTO_CREATE); // 绑定服务 } @Override public void onStop() { super.onStop(); if (isBound) { getActivity().unbindService(connection); // 解绑服务‌ isBound = false; } LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(btReceiver); } private OnJumpToActivityListener onJumpToActivityListener; // 在 Fragment 中定义接口 public interface OnJumpToActivityListener { void jumpToActivityAndClose(); } }但设备按钮为4个时 手机版本显示顺序没问题 但平板版本的+add按钮会在第六个按钮的位置 而不是第五个
07-15
08-04 15:13:41.002 5314 5314 W tek.inputmethod: Accessing hidden method Ldalvik/system/VMRuntime;->setHiddenApiExemptions([Ljava/lang/String;)V (blocked,core-platform-api, reflection, denied) 08-04 15:13:41.286 5352 5352 W utmethod.assist: Accessing hidden method Ldalvik/system/VMRuntime;->setHiddenApiExemptions([Ljava/lang/String;)V (blocked,core-platform-api, reflection, denied) 08-04 15:13:47.672 5471 5735 W ngdong.app.mall: Long monitor contention with owner RunnerWrapper_338 (6150) at void java.lang.Runtime.loadLibrary0(java.lang.ClassLoader, java.lang.Class, java.lang.String)(Runtime.java:1084) waiters=0 in void java.lang.Runtime.loadLibrary0(java.lang.ClassLoader, java.lang.Class, java.lang.String) for 220ms 08-04 15:13:57.146 1750 2440 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: binder:1750_9 08-04 15:13:57.146 1750 2440 E AndroidRuntime: java.lang.StackOverflowError: stack size 991KB 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.graphics.drawable.VectorDrawable$VPath.<init>(VectorDrawable.java:1638) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.graphics.drawable.VectorDrawable$VFullPath.<init>(VectorDrawable.java:1898) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.graphics.drawable.VectorDrawable$VGroup.<init>(VectorDrawable.java:1330) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.graphics.drawable.VectorDrawable$VectorDrawableState.<init>(VectorDrawable.java:994) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.graphics.drawable.VectorDrawable.<init>(VectorDrawable.java:364) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.graphics.drawable.VectorDrawable.<init>(Unknown Source:0) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.graphics.drawable.VectorDrawable$VectorDrawableState.newDrawable(VectorDrawable.java:1085) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.graphics.drawable.Drawable$ConstantState.newDrawable(Drawable.java:1532) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.content.res.DrawableCache.getInstance(DrawableCache.java:45) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.content.res.ResourcesImpl.loadDrawable(ResourcesImpl.java:658) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.content.res.Resources.loadDrawable(Resources.java:1004) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.content.res.Resources.getDrawableForDensity(Resources.java:994) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.content.res.Resources.getDrawable(Resources.java:933) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.content.Context.getDrawable(Context.java:948) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityRecord.lambda$updateEnterpriseThumbnailDrawable$0(ActivityRecord.java:645) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityRecord.$r8$lambda$365UxoHaJfIpMBzIwgtkcWR0vGE(ActivityRecord.java:0) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityRecord$$ExternalSyntheticLambda31.get(R8$$SyntheticClass:0) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.app.admin.ParcelableResource.loadDefaultDrawable(ParcelableResource.java:275) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.app.admin.DevicePolicyResourcesManager.getDrawable(DevicePolicyResourcesManager.java:214) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityRecord.updateEnterpriseThumbnailDrawable(ActivityRecord.java:643) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityRecord.<init>(ActivityRecord.java:2301) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityRecord.<init>(ActivityRecord.java:0) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityRecord$Builder.build(ActivityRecord.java:11354) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1431) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:805) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1310) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1261) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1236) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.app.Instrumentation.execStartActivity(Instrumentation.java:1887) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.app.ContextImpl.startActivity(ContextImpl.java:1132) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.SplitScreenHelper.startSplitActivities(SplitScreenHelper.java:73) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1746) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1475) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:805) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1310) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1261) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1236) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.app.Instrumentation.execStartActivity(Instrumentation.java:1887) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.app.ContextImpl.startActivity(ContextImpl.java:1132) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.SplitScreenHelper.startSplitActivities(SplitScreenHelper.java:73) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1746) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1475) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:805) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1310) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1261) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1236) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.app.Instrumentation.execStartActivity(Instrumentation.java:1887) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at android.app.ContextImpl.startActivity(ContextImpl.java:1132) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.SplitScreenHelper.startSplitActivities(SplitScreenHelper.java:73) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1746) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1475) 08-04 15:13:57.146 1750 2440 E AndroidRuntime: at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:805)这段报错的原因,怎么解决,修改为:public void startSplitActivities(Intent primaryIntent, Intent secondaryIntent,ActivityTaskManagerService atmService) { //public void enterSplitScreen(Activity primary, Activity secondary) { // 创建一个WindowContainerTransaction来执行操作 WindowContainerTransaction wct = new WindowContainerTransaction(); // 创建第一个TaskFragment IBinder fragmentToken1 = new Binder(); //TaskFragment taskFragment1 = mOrganizer.createTaskFragment( // wct, null, fragmentToken1, null); TaskFragment taskFragment1 = new TaskFragment(atmService, fragmentToken1, true, true); // 创建第二个TaskFragment IBinder fragmentToken2 = new Binder(); //TaskFragment taskFragment2 = mOrganizer.createTaskFragment( // wct, null, fragmentToken2, null); TaskFragment taskFragment2 = new TaskFragment(atmService, fragmentToken2, true, true); // 关键修复:获取 WindowContainerToken 的正确方式 WindowContainerToken wcToken1 = taskFragment1.mRemoteToken.toWindowContainerToken();//getOrganizerToken(); WindowContainerToken wcToken2 = taskFragment2.mRemoteToken.toWindowContainerToken();//getOrganizerToken(); // 设置两个TaskFragment为相邻关系 wct.setAdjacentTaskFragments(fragmentToken1, fragmentToken2, null); // 获取屏幕尺寸 int displayWidth = mContext.getResources().getDisplayMetrics().widthPixels; int displayHeight = mContext.getResources().getDisplayMetrics().heightPixels; // 设置第一个TaskFragment在左侧,占据屏幕宽度的一半 Rect bounds1 = new Rect(0, 0, displayWidth / 2, displayHeight); wct.setBounds(wcToken1, bounds1); // 设置第二个TaskFragment在右侧,占据屏幕宽度的一半 Rect bounds2 = new Rect(displayWidth / 2, 0, displayWidth, displayHeight); wct.setBounds(wcToken2, bounds2); // 启动第一个Activity到第一个TaskFragment中 ActivityOptions options1 = ActivityOptions.makeBasic(); options1.setLaunchWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW); options1.setLaunchTaskFragmentToken(fragmentToken1); mContext.startActivity(primaryIntent, options1.toBundle()); // 启动第二个Activity到第二个TaskFragment中 ActivityOptions options2 = ActivityOptions.makeBasic(); options2.setLaunchWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW); options2.setLaunchTaskFragmentToken(fragmentToken2); mContext.startActivity(secondaryIntent, options2.toBundle()); // 应用事务 //mOrganizer.applyTransaction(wct); mOrganizer.applyTransaction(wct, TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_OPEN, false); /* // 获取屏幕尺寸 Display display = primary.getDisplay(); int displayWidth = display.getWidth(); int displayHeight = display.getHeight(); // 创建 WindowContainerTransaction WindowContainerTransaction wct = new WindowContainerTransaction(); // 创建两个 TaskFragment IBinder fragmentToken1 = new android.os.Binder(); IBinder fragmentToken2 = new android.os.Binder(); mOrganizer.createTaskFragment(wct, fragmentToken1, primary.getActivityToken()); mOrganizer.createTaskFragment(wct, fragmentToken2, secondary.getActivityToken()); // 设置边界(左右分屏) Rect bounds1 = new Rect(0, 0, displayWidth / 2, displayHeight); Rect bounds2 = new Rect(displayWidth / 2, 0, displayWidth, displayHeight); wct.setBounds(fragmentToken1, bounds1); wct.setBounds(fragmentToken2, bounds2); // 设置启动选项 ActivityOptions options1 = ActivityOptions.makeBasic(); options1.setLaunchWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW); ActivityOptions options2 = ActivityOptions.makeBasic(); options2.setLaunchWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW); // 将 Activity 放入对应的 TaskFragment wct.reparentActivityToTaskFragment(fragmentToken1, primary.getActivityToken()); wct.reparentActivityToTaskFragment(fragmentToken2, secondary.getActivityToken()); // 应用事务 mOrganizer.applyTransaction(wct, TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_OPEN, false); */ }
最新发布
08-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值