如何以编程方式动态创建所有 Android ui 组件的列表?例如文本视图、图像视图等

Posted

技术标签:

【中文标题】如何以编程方式动态创建所有 Android ui 组件的列表?例如文本视图、图像视图等【英文标题】:How can I dynamically create a list of all Android ui components programmatically? e.g. TextView, ImageView etc 【发布时间】:2015-08-07 14:09:17 【问题描述】:

我正在创建一个程序,我需要在其中创建一个包含所有不同 android 组件的列表,而不是手动找出并键入 List。我想以编程方式弄清楚是否可以将其添加到字符串数组中,如下所示?

Components[] = "TextView", "ImageView", "RelativeLayout", "LinearLayout", "Random", "DecimalFormat ...

同样,我想以编程方式创建所有不同数据类型的 List,例如Int、String、ArrayList 等要添加到字符串数组中,如下所示

DataTypes[] = "Int", "String", "Object", "Double", "Char", "Boolean ...

到目前为止我能做的事情,如上。到目前为止,我一直在按上述方式将它们实际输入。

我怎样才能做到这一点?谢谢

澄清

数据类型:我指的是声明为保存数据的变量类型,例如 Int、String、object、boolean、double、a​​rrays、arraylists 等。

组件:我指的是可以添加到 Android xml 中的任何可视组件,例如ImageView、TextView、LinearLayout、RelativeLayout等

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

最好不要使用别人的库

【问题讨论】:

您想要一份所有 Android 中存在的所有这些组件的列表,或者只是您的应用程序中使用的组件和数据类型? 以编程方式,全部存在于Android中 你想在不使用 ListView 的情况下制作 UI 组件列表吗?? 发布你目前能做的事情。 你能定义什么使一个类成为“组件”以及什么使它成为“数据类型”吗? 【参考方案1】:

您不必使用任何第三方库,因为Java 具有reflections。 此方法将为您完成所有工作,并使UI 没有问题:

for(String s : arrayWithNames)
    View view = createViewInstance(0, s);
    if(view instance of View)
        //handle if it is view
    else
        //this is viewgroup
    

还有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;

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

它的一个问题是,除了ViewViewGroup 之外,还有更多类型。但这也取决于您要创建多少种Objects...在给定的示例中,假设我会做charStringintObject,然后您可以轻松扩展它。

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);
    

由于所有这些数据类型都在同一个包中,这对我们来说更容易。方法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;

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

【讨论】:

【参考方案2】:

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

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

Set<Class<? extends Object>> allClasses = reflections.getSubTypesOf(Object.class);

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

【讨论】:

【参考方案3】:

Reflections 是一个很棒的 Java 库。我不确定它是否也适用于Android。有人opened an issue,没多久就关门了。

如果你可以让它在 Android 中工作,你可以使用这个代码来获取所有组件:

Reflections reflections = new Reflection("android.widget") //specifiy the package (TextView etc. are in here)
Set<Class<? extends View>> components = reflections.getSubTypesOf(View.class);

如果需要,您可以使用 android.view 包重复此过程,其中一些其他类(例如 ViewGroup)位于该包中。

另外,如果你真的想要一个字符串数组,请获取类的名称:

List<String> componentNames = new ArrayList<String>();
for (Class<? extends View> c: components) 
    componentNames.add(c.getName());

String[] allComponents = componentNames.toArray();


如果上述解决方案对您不起作用,请尝试从官方网站获取课程。这些类在包android.view 和android.widget 中列出。只需复制相关名称并将它们粘贴到您的源代码中即可。这不会是动态的,但它有效。

【讨论】:

【参考方案4】:

如何使用工厂来创建这样的组件:

public class ComponentFactory 
    private HashMap<String, View> mMap;
    public ComponentFactory(Context context) 
        mMap = new HashMap<String, View>();
        mMap.put("TextView", new TextView(context));
        ...
        ...
    

    public View getComponent(String name) 
        View v = mMap.get(name);
        if (v == null) 
            throw new IlllegalArgumentException();
        
        return v;
    

【讨论】:

我们如何为创建的元素提供操作,例如,如果我想从编辑文本中获取文本或从 Spinner 获取选定项目?如果你有样品,请在这里分享

以上是关于如何以编程方式动态创建所有 Android ui 组件的列表?例如文本视图、图像视图等的主要内容,如果未能解决你的问题,请参考以下文章

Android:创建 UI 组件并以编程方式重用它

以编程方式将片段添加到android中的框架布局

如何以编程方式(iOS)创建 Firebase 动态链接?

如何在android中以编程方式在片段之间导航?

我可以以编程方式创建 WKInterfaceButton 吗?

有没有办法以编程方式检测 Android 应用程序的 UI 组件?