Android getResources().getDrawable() deprecated API 22

本文详细介绍了在Android API 22及以后版本中,如何正确处理getDrawable()方法的弃用问题,提供了使用ContextCompat和ResourcesCompat的方法来替代,确保应用程序在不同主题下正确加载资源。

以下解决方法摘自 stackoverflow , 点击下方链接可跳转

Android getResources().getDrawable() deprecated API 22

No.1

You have some options to handle this deprecation the right (and future proof) way, depending on which kind of drawable you are loading:

  • A) drawables with theme attributes
ContextCompat.getDrawable(getActivity(), R.drawable.name);

You’ll obtain a styled Drawable as your Activity theme instructs. This is probably what you need.

* B) drawables without theme attributes

ResourcesCompat.getDrawable(getResources(), R.drawable.name, null);

You’ll get your unstyled drawable the old way.

EXTRA) drawables with theme attributes from another theme

ResourcesCompat.getDrawable(getResources(), R.drawable.name, anotherTheme);

Explanation:

API 21 (Android 5.0 Lollipop) introduced some new theme attributes such as android:colorAccent that modify the appearance of drawables that hold references to those new theme attributes values.The AppCompat library handles pre and post-Lollipop drawable styling for you.

If you do use the deprecated getDrawable() method to obtain a drawable resource with theme attributes, you will get a partially-styled drawable and a logcat warning.You can see this in API 22 android.content.res.Resources source code:

@Deprecated
@Nullable
public Drawable getDrawable(int id) throws NotFoundException {
    final Drawable d = getDrawable(id, null);
    if (d != null && d.canApplyTheme()) {
        Log.w(TAG, "Drawable " + getResourceName(id) + " has unresolved theme "
                + "attributes! Consider using Resources.getDrawable(int, Theme) or "
                + "Context.getDrawable(int).", new RuntimeException());
    }
    return d;
}

No.2

You should use the following code from the support library instead:

ContextCompat.getDrawable(context, R.drawable.***)

Using this method is equivalent to calling:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    return resources.getDrawable(id, context.getTheme());
} else {
    return resources.getDrawable(id);
}

As of API 21, you should use the getDrawable(int, Theme) method instead of getDrawable(int), as it allows you to fetch a drawable object associated with a particular resource ID for the given screen density/theme. Calling the deprecated getDrawable(int) method is equivalent to calling getDrawable(int, null).

package com.st.base.ui; import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.view.Window; import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.databinding.DataBindingUtil; import androidx.databinding.ViewDataBinding; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public abstract class BaseActivity<V extends ViewDataBinding> extends AppCompatActivity implements IBaseView { protected V binding; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //页面接受的参数方法 initParam(); //隐藏顶部和底部栏 transparentNavBar(getWindow()); //私有的初始化Databinding和ViewModel方法 initViewDataBinding(savedInstanceState); //初始化ui initView(); //私有的ViewModel与View的契约事件回调逻辑 registorUIChangeLiveDataCallBack(); //页面数据初始化方法 initData(); //页面事件监听的方法,一般用于ViewModel层转到View层的事件注册 initViewObservable(); //页面监听回调 initCallback(); } protected abstract void initView(); protected abstract void initCallback(); protected abstract void releaseCallback(); private void initViewDataBinding(Bundle savedInstanceState) { //DataBindingUtil类需要在project的build中配置 dataBinding {enabled true }, 同步后会自动关联android.databinding包 binding = DataBindingUtil.setContentView(this, initContentView(savedInstanceState)); //支持LiveData绑定xml,数据改变,UI自动会更新 binding.setLifecycleOwner(this); initViewDataModel(); } protected void initViewDataModel() { } /** * 初始化根布局 * * @return 布局layout的id */ public abstract int initContentView(Bundle savedInstanceState); protected int initVariableId() { return 0; } protected void registorUIChangeLiveDataCallBack() { } @Override public void initParam() { } @Override public ViewModel initViewModel() { return null; } @Override public void initData() { } @Override public void initViewObservable() { } /** * 跳转页面 * * @param clz 所跳转的目的Activity类 * @param bundle 跳转所携带的信息 */ public void startActivity(Class<?> clz, Bundle bundle) { Intent intent = new Intent(this, clz); if (bundle != null) { intent.putExtras(bundle); } startActivity(intent); } /** * 创建ViewModel * * @param cls * @param <T> * @return */ public <T extends ViewModel> T createViewModel(FragmentActivity activity, Class<T> cls) { return new ViewModelProvider(activity).get(cls); } @Override protected void onDestroy() { super.onDestroy(); if (binding != null) { binding.unbind(); } releaseCallback(); } protected void transparentNavBar(@NonNull final Window window) { window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); //状态栏、导航栏透明 window.setStatusBarColor(Color.TRANSPARENT); window.setNavigationBarContrastEnforced(false); window.setNavigationBarColor(Color.TRANSPARENT); View decorView = window.getDecorView(); int vis = decorView.getSystemUiVisibility(); int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; decorView.setSystemUiVisibility(vis | option); } } package com.st.launcher; import static com.st.launcher.util.Constant.APP_STATE; import static com.st.launcher.util.Constant.IS_FOREGROUND; import static com.st.launcher.util.Constant.PAGER; import android.annotation.SuppressLint; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.LauncherActivityInfo; import android.os.Bundle; import android.os.Handler; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import androidx.annotation.NonNull; import androidx.core.content.res.ResourcesCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.st.base.ui.BaseActivity; import com.st.base.util.ActivityManagerUtils; import com.st.base.util.HandlerUtil; import com.st.base.util.ThreadPool; import com.st.base.util.UIModeManagerHelper; import com.st.launcher.adapter.SimpleItemAdapter; import com.st.launcher.app.Launcher; import com.st.launcher.databinding.ActivityMainBinding; import com.st.launcher.model.LauncherAppManager; import com.st.launcher.observer.BaseObserver; import com.st.launcher.util.Constant; import com.st.launcher.view.ScrollControlLayoutManager; import com.st.launcher.view.TVRecyclerView; import java.util.List; public class MainActivity extends BaseActivity<ActivityMainBinding> { private static final String TAG = "MainActivity"; private SimpleItemAdapter mSimpleItemAdapter; @Deprecated public static boolean isScaleUp = false; private static final String SYSTEM_DIALOG_REASON_KEY = "reason"; private static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; private boolean isHomeBack = false; private boolean isHomeResume; private String mCurrentPackageName; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } public void initView() { getWindow().getDecorView().getViewTreeObserver().addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() { @Override public void onGlobalFocusChanged(View oldFocus, View newFocus) { Log.i(TAG, "onGlobalFocusChanged: oldFocus = " + oldFocus + ", newFocus = " + newFocus); } }); if (Constant.isNormalMode(this)) { if (UIModeManagerHelper.getInstance().getNightMode(MainActivity.this)) { binding.flMainActivity.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.home_select_bg_night, null)); } else { binding.flMainActivity.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.home_select_bg, null)); } } else { binding.flMainActivity.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.bg_child_mode, null)); } } @Override public void initData() { super.initData(); addLauncherCardView(); if (!Constant.isNormalMode(this)) { // 设置 paddingLeft binding.flMainActivity.setPadding(40, // left binding.flMainActivity.getPaddingTop(), // top(保持不变) binding.flMainActivity.getPaddingRight(), // right(保持不变) binding.flMainActivity.getPaddingBottom() // bottom(保持不变) ); } Log.i(TAG, "initData: paddingLeft = " + binding.flMainActivity.getPaddingLeft()); registerContentObserver(); } @SuppressLint("ClickableViewAccessibility") private void addLauncherCardView() { Log.i(TAG, "addLauncherCardView: "); mSimpleItemAdapter = new SimpleItemAdapter(this); List<View> cardViews = LauncherAppManager.getInstance().initHomeAppViews(this); if (Constant.isNormalMode(this)) { ThreadPool.getInstance().exe(() -> { List<LauncherActivityInfo> allApp = LauncherAppManager.getInstance().getAllApp(MainActivity.this); List<LauncherActivityInfo> launcherActivityInfos = allApp.size() >= 4 ? allApp.subList(0, 4) : null; MainActivity.this.runOnUiThread(() -> mSimpleItemAdapter.setAllAppData(launcherActivityInfos)); }); } mSimpleItemAdapter.setData(cardViews); binding.rvCard.setLayoutManager(new ScrollControlLayoutManager(Launcher.getInstance().getApplicationContext(), LinearLayoutManager.HORIZONTAL, false)); binding.rvCard.setAdapter(mSimpleItemAdapter); binding.rvCard.setFocusableInTouchMode(true);//设置可在touch模式获得焦点 setFocus(false); Log.i(TAG, "addLauncherCardView: rvCard.hashCode() = " + binding.rvCard.hashCode()); binding.rvCard.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); } @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); Log.i(TAG, "onScrollStateChanged: newState = " + newState); } }); binding.rvCard.setOnFocusChangeListener((v, hasFocus) -> Log.i(TAG, "onFocusChange: rvCard: hasFocus = " + hasFocus)); binding.rvCard.setOnItemScaleListener(new TVRecyclerView.OnItemScaleListener() { @Override public void onScaleUp() { Log.i(TAG, "onScaleUp: "); isScaleUp = true; Settings.Global.putInt(getContentResolver(), "home_animation_scale_up", 1); } @Override public void onScaleDown() { Log.i(TAG, "onScaleDown: "); isScaleUp = false; Settings.Global.putInt(getContentResolver(), "home_animation_scale_up", 0); } @Override public void onFirstItemFocused(boolean hasFocus, int left) { Log.i(TAG, "onFirstItemFocused: " + hasFocus); // 获取 RecyclerView 当前的 LayoutParams ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) binding.rvCard.getLayoutParams(); if (hasFocus) { // 设置新的左边距值 params.leftMargin = left * 2; } else { // 恢复默认的左边距值 params.leftMargin = 0; // 或者设置为你在 XML 中定义的原始值 } // 应用修改后的 LayoutParams 到 RecyclerView binding.rvCard.setLayoutParams(params); } }); } private void registerContentObserver() { Log.i(TAG, "registerContentObserver: "); ContentResolver contentResolver = getApplicationContext().getContentResolver(); BaseObserver baseObserver = new BaseObserver(null, getApplicationContext()); contentResolver.registerContentObserver(Settings.System.getUriFor(Constant.USER_MODE), true, baseObserver); baseObserver.setOnUserModeListener(mode -> { Log.i(TAG, "onUserModeChange: mode = " + mode); HandlerUtil.getInstance().runMainThread(this::recreate); }); } @Override protected void initCallback() { UIModeManagerHelper.getInstance().registerNightModeChangeListener(mOnNightModeChangeListener); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Constant.RIGHT_GET_FOCUS); intentFilter.addAction(Constant.DOWN_GET_FOCUS); intentFilter.addAction(Constant.START_APP_LIST); intentFilter.addAction(Constant.SYSTEMUI_STACK_TOP_APP_CHANGE); registerReceiver(mBroadcastFocusReceiver, intentFilter); registerHomeKeyReceiver(this); } private HomeWatcherReceiver mHomeKeyReceiver = null; private void registerHomeKeyReceiver(Context context) { Log.i(TAG, "registerHomeKeyReceiver"); mHomeKeyReceiver = new HomeWatcherReceiver(); final IntentFilter homeFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); context.registerReceiver(mHomeKeyReceiver, homeFilter); } private void unregisterHomeKeyReceiver(Context context) { Log.i(TAG, "unregisterHomeKeyReceiver"); if (null != mHomeKeyReceiver) { context.unregisterReceiver(mHomeKeyReceiver); } } class HomeWatcherReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.i(TAG, "onReceive: action: " + action); if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY); Log.i(TAG, "reason: " + reason); if (SYSTEM_DIALOG_REASON_HOME_KEY.equals(reason)) { // 短按Home键 Log.i(TAG, "homekey"); View focusedChild = binding.rvCard.getFocusedChild(); if (focusedChild != null) { binding.rvCard.scrollToPosition(0); binding.rvCard.scaleDown(focusedChild); } binding.rvCard.setShowAnimationFocus(false); isHomeBack = true; } } } } private void setFocus(boolean status) { if (Constant.isNormalMode(this)) { binding.flMainActivity.setFocusable(status); //设置可获得焦点 binding.rvCard.setFocusable(status); //设置可获得焦点 binding.rvCard.setHasFixedSize(status); boolean requestFocus = binding.rvCard.requestFocus(); Log.i(TAG, "setFocus: requestFocus = " + requestFocus); } } UIModeManagerHelper.OnNightModeChangeListener mOnNightModeChangeListener = new UIModeManagerHelper.OnNightModeChangeListener() { @Override public void onNightModeChange(boolean isNightMode) { if (!Constant.isNormalMode(MainActivity.this)) { return; } if (isNightMode) { binding.flMainActivity.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.home_select_bg_night, null)); } else { binding.flMainActivity.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.home_select_bg, null)); } Log.i(TAG, "onNightModeChange: isNightMode = " + isNightMode); if (mSimpleItemAdapter != null) { mSimpleItemAdapter.notifyDataSetChanged(); } } @Override public void onLanguageChange(boolean isChinese) { Log.i(TAG, "onLanguageChange: isChinese = " + isChinese); if (mSimpleItemAdapter != null) { List<View> cardViews = LauncherAppManager.getInstance().initHomeAppViews(MainActivity.this); mSimpleItemAdapter.setData(cardViews); } } @Override public void onTextSizeChange(float size) { } }; BroadcastReceiver mBroadcastFocusReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.i(TAG, "onReceive: action = " + action); if (TextUtils.equals(action, Constant.RIGHT_GET_FOCUS) && ActivityManagerUtils.getAppManager().isForeground(MainActivity.this, MainActivity.class.getName())) { Log.i(TAG, "onReceive: RIGHT_GET_FOCUS: rvCard.hasFocus() = " + binding.rvCard.hasFocus() + ", currentState = " + getLifecycle().getCurrentState()); setFocus(true); binding.rvCard.setShowAnimationFocus(true); binding.rvCard.requestFocus(); // 获取当前获得焦点的子项并调用 scaleDown View focusedChild = binding.rvCard.getFocusedChild(); if (focusedChild != null) { binding.rvCard.scaleUp(focusedChild); } Log.i(TAG, "onReceive: RIGHT_GET_FOCUS: rvCard.hasFocus() = " + binding.rvCard.hasFocus() + ", flMainActivity.hasFocus() = " + binding.flMainActivity.hasFocus()); } else if (TextUtils.equals(action, Constant.DOWN_GET_FOCUS) && ActivityManagerUtils.getAppManager().isForeground(MainActivity.this, MainActivity.class.getName())) { Log.i(TAG, "onReceive: DOWN_GET_FOCUS: rvCard.hasFocus() = " + binding.rvCard.hasFocus() + ", currentState = " + getLifecycle().getCurrentState()); setFocus(true); binding.rvCard.setShowAnimationFocus(true); // 获取当前获得焦点的子项并调用 scaleDown View focusedChild = binding.rvCard.getFocusedChild(); if (focusedChild != null) { binding.rvCard.scaleUp(focusedChild); } } else if (TextUtils.equals(action, Constant.START_APP_LIST)) { Log.i(TAG, "onReceive: START_APP_LIST"); UIModeManagerHelper.getInstance().showAppListBox(false); startActivity(new Intent(MainActivity.this, AppListActivity.class)); } else if (TextUtils.equals(action, Constant.SYSTEMUI_STACK_TOP_APP_CHANGE)) { String packageName = intent.getStringExtra("packageName"); Log.i(TAG, "onReceive: SYSTEMUI_STACK_TOP_APP_CHANGE: packageName = " + packageName); mSimpleItemAdapter.setTopPackageName(packageName); if (Constant.LAUNCHER_PKG_NAME.equals(packageName) && Constant.WEMEET_PKG_NAME.equals(mCurrentPackageName)) { Log.i(TAG, "onReceive: SYSTEMUI_STACK_TOP_APP_CHANGE: isResume = " + isHomeResume); if (isHomeResume) { sendFocusRequestBroadCast(0); } } mCurrentPackageName = packageName; } } }; @Override protected void releaseCallback() { UIModeManagerHelper.getInstance().unregisterNightModeChangeListener(mOnNightModeChangeListener); unregisterReceiver(mBroadcastFocusReceiver); unregisterHomeKeyReceiver(this); } @Override public int initContentView(Bundle savedInstanceState) { return R.layout.activity_main; } private void sendSelectBroadcast() { Log.i(TAG, "sendSelectBroadcast: "); Intent intent = new Intent(APP_STATE); intent.putExtra(Constant.ORDER, APP_STATE); intent.putExtra(IS_FOREGROUND, true); intent.putExtra(PAGER, 0); sendBroadcast(intent); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.i(TAG, "onNewIntent: "); } @Override protected void onResume() { super.onResume(); Log.i(TAG, "onResume: "); isHomeResume = true; new Handler().postDelayed(() -> isHomeResume = false, 500); sendSelectBroadcast(); if (Constant.isNormalMode(this)) { if (!isHomeBack) { binding.rvCard.setShowAnimationFocus(true); View focusedChild = binding.rvCard.getFocusedChild(); if (focusedChild != null) { binding.rvCard.scaleUp(focusedChild); } } } } public void sendFocusRequestBroadCast(int direction) { Log.i(TAG, "sendFocusRequestBroadCast: direction = " + direction); Intent intent = new Intent(Constant.ACTION_FOCUS_CHANGE); intent.putExtra(Constant.DIRECTION, direction); sendBroadcast(intent); } @Override protected void onStop() { super.onStop(); Log.i(TAG, "onStop: "); isHomeBack = false; if (Constant.isNormalMode(this)) { View focusedChild = binding.rvCard.getFocusedChild(); if (focusedChild != null) { binding.rvCard.scaleDown(focusedChild); } binding.rvCard.setShowAnimationFocus(false); } } @Override protected void onDestroy() { super.onDestroy(); Log.i(TAG, "onDestroy: "); } } @Test public void testScaleUpWhenFocusedChildNotNull() { ActivityScenario<MainActivity> scenario = ActivityScenario.launch(MainActivity.class); scenario.onActivity(activity -> { try { // 使用反射获取 binding 字段 Field bindingField = MainActivity.class.getDeclaredField("binding"); bindingField.setAccessible(true); ActivityMainBinding binding = (ActivityMainBinding) bindingField.get(activity); // 获取 rvCard 并调用 scaleUp com.st.launcher.view.TVRecyclerView rvCard = binding.rvCard; View focusedChild = mock(View.class); // 请求焦点(可选) rvCard.requestFocus(); // 调用 scaleUp 方法 rvCard.scaleUp(focusedChild); } catch (Exception e) { e.printStackTrace(); fail("反射获取 binding 失败"); } }); } java.lang.NoSuchFieldException: binding at java.base/java.lang.Class.getDeclaredField(Class.java:2411) at com.st.launcher.MainActivityTest.lambda$testScaleUpWhenFocusedChildNotNull$1(MainActivityTest.java:63) at androidx.test.core.app.ActivityScenario.lambda$onActivity$2$androidx-test-core-app-ActivityScenario(ActivityScenario.java:789) at androidx.test.core.app.ActivityScenario$$ExternalSyntheticLambda2.run(D8$$SyntheticClass) at androidx.test.core.app.ActivityScenario.onActivity(ActivityScenario.java:799) at com.st.launcher.MainActivityTest.testScaleUpWhenFocusedChildNotNull(MainActivityTest.java:60
07-31
Android 开发中,`getResources().getDrawable()` 方法已经被标记为过时,尤其是在 API 21Android 5.0)及以上版本中。为了替代这一方法并保持良好的兼容性与最佳实践,推荐使用 `ContextCompat.getDrawable()` 或直接通过 `Context` 获取资源。 ### 使用 `ContextCompat.getDrawable()` 这是最推荐的方式,因为它可以兼容不同版本的 Android 系统,并自动处理不同 API 级别的差异: ```java Drawable drawable = ContextCompat.getDrawable(context, R.drawable.your_drawable); ``` 此方法内部会根据当前设备的 API 版本选择合适的实现方式,确保 drawable 资源能够正确加载[^1]。 ### 使用 `getResources().getDrawable(int id, Theme theme)` 如果需要指定主题来加载资源,可以在 API 21 及以上使用以下方式: ```java Drawable drawable = getResources().getDrawable(R.drawable.your_drawable, context.getTheme()); ``` 这种方式允许你传入一个 `Theme` 参数,使得某些依赖主题属性的资源(如矢量图或颜色状态列表)能正确解析[^1]。 ### 使用 `Resources.getDrawable()` 的注意事项 对于仅面向高版本 Android 的应用(API ≥ 21),可以直接通过 `Resources` 对象调用带有 `Theme` 参数的 `getDrawable()` 方法。但若目标设备包含旧版本系统,则应优先考虑使用 `ContextCompat` 来避免运行时异常。 --- ### 示例代码 ```java TextView textView = findViewById(R.id.my_text_view); Drawable drawable = ContextCompat.getDrawable(this, R.drawable.ic_end_icon); if (drawable != null) { drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); textView.setCompoundDrawables(null, null, drawable, null); } ``` 上述代码展示了如何安全地设置 `TextView` 的 `drawableEnd` 属性,同时避免使用已废弃的 API。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值