Android动态添加项目到阵列XML资源

Eli*_*zer 6 android android-xml

有什么办法可以将代码中的项添加到String-Array资源中吗?例如,如果我想创建一个显示用户值的微调器,我想允许用户添加自己的自定义值.

Jox*_*aex 8

不,这是不受支持的,因为资源打包在二进制.apk中,因此无法更改.

不要遵循这种设计模式,改变你的方法.

  • 数据库可能是最容易接口的,所以是的,请使用数据库.这是谷歌所做的保存以前的搜索及其如何将它们列入清单的方法. (2认同)

cep*_*3us 6

可能JoxTraex对 android 框架或他们所说的一无所知

当有人说这无法完成时 - 总会有人不知道这一点并且会去做:)

所以重点是:

Resources是一个开放类,只是 ResourcesImpl 类的包装器

(带有折旧的构造函数 - 但可用)

public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config)
Run Code Online (Sandbox Code Playgroud)

在应用程序中,对它的每次调用都是通过上下文进行的

所以:

1)你总是可以提供你自己的资源实现

2)或(当它足够时)你自己的上下文实现(所以天空是极限)

...我现在感觉眼睛在“上下文实现”上 - 是的,您甚至可以替换 LoadedApk、Activity 等中最重要的上下文。是的,很酷吗?但是什么时候,怎么样?如何:通过反射,何时:优秀的应用程序设计师知道这个地方是(之前)第一次/对此类对象进行任何调用的地方......

但是这里有一个危险的问题——在一种情况下,android 直接将 Context 解包到 ContextImp,然后你需要返回那些 Context 而不是你的——我会为喜欢谜语的人保密的地方在哪里:)

资源中也有

a) 一个隐藏的构造函数(最好的入口点,因为它不制作任何 ReourceImpl(可以通过下面提到的方法设置)

public Resources(@Nullable ClassLoader classLoader) 
Run Code Online (Sandbox Code Playgroud)

b) 隐藏方法

setResImpl(ResourcesImpl) 
Run Code Online (Sandbox Code Playgroud)

总结:

所以通过调用

Resources.getStringArray(**not existing in APK resource id here**);
Run Code Online (Sandbox Code Playgroud)

在我们自己的实现中,我们可以获得想要的东西:)

更好的是我们可以添加到我们的实现中

addResourceById(int,Object)
Run Code Online (Sandbox Code Playgroud)

方法并添加新资源 :) 然后对我们将使用的资源进行分配能力检查,并对我们的实现进行向上转换 :) 以使用我们新添加的方法 :)

顺便说一句:如果有人对你说“你不应该这样做 - blablabla”,这是最好的理由!- 如果法律不允许:)

足够的理论去实践:

示例上下文实现将调用转发到 getString:

    public class MyContext extends Context {
        ....
    // override context get resources method 
    @Override
    public android.content.res.Resources getResources() {
        // get super resources 
        android.content.res.Resources resources = super.getResources();
        // pull assets 
        android.content.res.AssetManager assets = resources.getAssets();
        // pull metrics 
        android.util.DisplayMetrics displayMetrics = resources.getDisplayMetrics();
        // pull configuration 
        android.content.res.Configuration configuration = resources.getConfiguration();
        // construct new anon resource implementation 
        return new android.content.res.Resources(assets, displayMetrics, configuration) {

            // overrride interesting method 
            @android.support.annotation.NonNull
            @Override
            public String getString(int id) throws android.content.res.Resources.NotFoundException {
                return id == pl.ceph3us.base.common.R.string.my_sweet_google
                    ? "fck_you_google";
                    : super.getString(id);
            }
        };
    }

}
Run Code Online (Sandbox Code Playgroud)