gpt4 book ai didi

android - 如何覆盖 android 样式的私有(private)属性

转载 作者:行者123 更新时间:2023-11-29 01:17:10 27 4
gpt4 key购买 nike

我正在尝试找到一种方法来覆盖 android 样式的非公共(public)属性,更具体地说是 Widget.FragmentBreadCrumbs 样式的名为 itemColor 的属性。当首选项 fragment 显示在大屏幕的右 Pane 中时,此样式会影响 PreferenceActivity 中面包屑的文本颜色。它被类(class)使用 FragmentBreadCrumbs .

我的应用程序使用扩展 Theme.Holo.Light 的自定义主题,并且该主题在 API 23 上中断,因此我正在尝试寻找解决方法。

上述样式将默认值设置为 @nullitemColor,这在 Holo 主题中未被覆盖,例如它被设置为 Material 的有效值主题。结果面包屑的标题不可见(参见 screenshot for API 19screenshot for API 23 )

我想我想做的是找到一种可以更改主题的私有(private)值的方法,类似于使用反射修改类的私有(private)字段值的方法。或者 ContextThemeWrapper似乎很有前途,但我只是不知道如何使用它,甚至不知道它是否适用于我的情况。

我需要的是,在 FragmentBreadCrumbs 类在 mTextColor 属性下执行其构造函数后,它不是 @null(我猜是0) 由 Android 主题配置设置,但具有有效的颜色值。

你认为这可能吗?

public FragmentBreadCrumbs(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);

final TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.FragmentBreadCrumbs, defStyleAttr, defStyleRes);

mGravity = a.getInt(com.android.internal.R.styleable.FragmentBreadCrumbs_gravity,
DEFAULT_GRAVITY);

mLayoutResId = a.getResourceId(
com.android.internal.R.styleable.FragmentBreadCrumbs_itemLayout,
com.android.internal.R.layout.fragment_bread_crumb_item);

/* This is the value needed to be overridden */
mTextColor = a.getColor(
com.android.internal.R.styleable.FragmentBreadCrumbs_itemColor,
0);

a.recycle();
}

最佳答案

不幸的是,如果您尝试使用 android:itemColor 工具链将报告错误,因为这不对应于公共(public)属性名称,因此您甚至无法使用该属性创建样式。

我唯一能想到的就是在 View 构建(/膨胀)后通过反射更改文本颜色。您可能希望在 updateCrumbs() 第一次在 FragmentBreadCrumbs 内部运行之前尽早执行此操作。也许您可以覆盖 PreferenceActivityonCreate()PreferenceFragmentonCreateView()(以此处适用的为准)和做这样的事情:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

FragmentBreadCrumbs fbc = (FragmentBreadCrumbs) findViewById(...);
int color = ...;
FragmentBreadCrumbsUtils.setTextColor(fbc, color);
}


public class FragmentBreadCrumbsUtils {

private static final Field FRAGMENT_BREAD_CRUMBS_TEXT_COLOR = findField();
private static Field findField() {
try {
Field f = FragmentBreadCrumbs.class.getDeclaredField("mTextColor");
f.setAccessible(true);
return f;
} catch (Throwable t) {
// don't fail for any reason, just log it
Log.e("FragmentBreadCrumbsUtils",
"Couldn't find mTextColor field in FragmentBreadCrumbs",
t);
}
return null;
}

public static void setTextColor(FragmentBreadCrumbs fbc, int color) {
if (FRAGMENT_BREAD_CRUMBS_TEXT_COLOR == null) {
return; // can't do anything, we don't have the field
}

try {
FRAGMENT_BREAD_CRUMBS_TEXT_COLOR.set(fbc, color);
} catch (Throwable t) {
// don't fail for any reason, just log it
Log.e("FragmentBreadCrumbsUtils",
"Couldn't set mTextColor field in FragmentBreadCrumbs",
t);
}
}
}

关于android - 如何覆盖 android 样式的私有(private)属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38834180/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com