如何以编程方式动态创建所有Android ui组件的列表?例如TextView,ImageView等

24 java android android-intent android-layout android-activity

我正在创建一个程序,我需要在其中创建所有不同Android组件的列表,而不是手工识别和键入List.我想以编程方式弄清楚我是否可以完成此操作以添加到String Arrays中,如下所示?

Components[] = {"TextView", "ImageView", "RelativeLayout", "LinearLayout", "Random", "DecimalFormat ...
Run Code Online (Sandbox Code Playgroud)

类似地,我想以编程方式创建一个包含所有不同数据类型的List,例如Int,String,ArrayList等,以添加到String Arrays中,如下所示

DataTypes[] = {"Int", "String", "Object", "Double", "Char", "Boolean ...
Run Code Online (Sandbox Code Playgroud)

到目前为止我能够做到的就是上面.到目前为止,我一直在打字,如上所述.

我怎么能做到这一点?谢谢

澄清

按数据类型:我的意思是声明为保存数据的变量类型,例如Int,String,object,boolean,double,arrays,arraylists等.

按组件:我的意思是任何可以添加到Android的xml的可视组件,例如ImageView,TextView,LinearLayout,RelativeLayout等.

是的,我知道这些组件的数量可以是无限的(由使用的API决定),我想为它动态生成它们

最好不要使用别人的图书馆

Yur*_*ets 10

您不必使用任何第三方库,因为Java反射.这个方法将为您做一切,并且UI没有问题:

for(String s : arrayWithNames){
    View view = createViewInstance(0, s);
    if(view instance of View){
        //handle if it is view
    }else{
        //this is viewgroup
    }
}
Run Code Online (Sandbox Code Playgroud)

而且createViewInstance():

private View createViewInstance(String name){
    View view = null;
    try{
        if(name.equalsIgnoreCase("View"){ // if it is view
            Class viewClass = Class.forName("android.view." + name);
            view = (View) viewClass.getConstructor(Context.class).newInstance(new Object[]{ctx});
        }else{ // if it is widget: ImageView, RelativeLayout etc
            Class viewClass = Class.forName("android.widget." + name);
            view = (View) viewClass.getConstructor(Context.class).newInstance(new Object[]{ctx});
        }
    } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException
            | InstantiationException | IllegalAccessException e) {
        e.printStackTrace();
    }
    return view;
}
Run Code Online (Sandbox Code Playgroud)

而已.你有一切可以处理任何一种View. 我测试了上面的代码并在项目中使用.它工作得很好. 与其他人Object的情况完全相同.你不能int用反射创建,但你可以创建Integer,所以基本上是相同的.

它的一个问题是有更多类型而不仅仅是ViewViewGroup.但它也取决于有多少种Object你想s到创建...在给定的例子,让我们说我会做char,String,int,Object然后你就可以轻松地扩展它.

for(String s : arrayWithNames){
    if(s.equalsIgnoreCase("int")){
        Integer integer = (Integer)createVarInstance(s); //ready to use. Integer, not int!
    }else if(s.equalsIgnoreCase("String"){
        String string = (String)createVarInstance(s);
    }else if(s.equalsIgnoreCase("char"){
        Character character = (Character)createVarInstance(s); //Character, not char!
    }else if(s.equalsIgnoreCase("Object"){
        Object object = (Object)createVarInstance(s);
    }
}
Run Code Online (Sandbox Code Playgroud)

由于所有这些数据类型都在同一个包中,因此对我们来说更容易.方法createVarInstance():

private Object createVarInstance(String name){
    Object obj = null;
    try{
        Class varClass = Class.forName("java.lang." + name);
        object = (Object) varClass.newInstance();
    } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException
            | InstantiationException | IllegalAccessException e) {
        e.printStackTrace();
    }
    return object;
}
Run Code Online (Sandbox Code Playgroud)

如果需要,可以为不同的包制作一种方法.如果您将来想要创建更多不同类型的变量,这些变量位于不同的包中,那么您必须检查名称或执行类似于Views的示例操作.


Mar*_*nci 1

您可以使用Reflection Library列出包中所有类android.viewandroid.view.View子类的UI 组件:

Reflections reflections = new Reflections("android.view");
//Reflections reflections = new Reflections("android.view.View");

Set<Class<? extends Object>> allClasses = reflections.getSubTypesOf(Object.class);
Run Code Online (Sandbox Code Playgroud)

要创建所有数据类型的列表,您可以使用 Object 类执行与上面相同的操作,但首先,我个人会问自己这样做的意义是什么。