如何以编程方式动态创建所有 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、arrays、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
。
我已经测试了上面的代码并在项目中使用。它工作得很好。
与其他Object
s 的情况完全相同。你不能用反射创建int
,但是你可以创建Integer
,所以基本上是一样的。
它的一个问题是,除了View
和ViewGroup
之外,还有更多类型。但这也取决于您要创建多少种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);
由于所有这些数据类型都在同一个包中,这对我们来说更容易。方法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;
如果需要,可以为不同的包创建一种方法。
如果将来您想创建更多不同类型的变量,它们位于不同的包中,那么您将必须检查名称或执行类似的操作,例如View
s。
【讨论】:
【参考方案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 组件的列表?例如文本视图、图像视图等的主要内容,如果未能解决你的问题,请参考以下文章