[英]How can I dynamically create a list of all Android ui components programmatically? e.g. TextView, ImageView etc
I'm creating a program, and within which I need to create a list of all the different Android components but rather than figuring out and typing the List by hand. 我正在创建一个程序,我需要在其中创建所有不同Android组件的列表,而不是手工识别和键入List 。 I'd like to figure out programmatically whether I could accomplish this to be added to String Arrays like the below?
我想以编程方式弄清楚我是否可以完成此操作以添加到String Arrays中,如下所示?
Components[] = {"TextView", "ImageView", "RelativeLayout", "LinearLayout", "Random", "DecimalFormat ...
Similarly I would like to programatically create a List of all the different Data-Types eg Int, String, ArrayList etc. to be added to String Arrays like the below 类似地,我想以编程方式创建一个包含所有不同数据类型的List ,例如Int,String,ArrayList等,以添加到String Arrays中,如下所示
DataTypes[] = {"Int", "String", "Object", "Double", "Char", "Boolean ...
What I have been able to do so far , is above. 到目前为止我能够做到的就是上面。 So far I've been physically typing them out as above.
到目前为止,我一直在打字,如上所述。
How can I accomplish this? 我怎么能做到这一点? Thanks
谢谢
Clarification 澄清
By data types: I mean variables types declared to holds data eg Int, String, object, boolean, double, arrays, arraylists etc. 按数据类型:我的意思是声明为保存数据的变量类型,例如Int,String,object,boolean,double,arrays,arraylists等。
By Components: I mean any visual component which can be added to an Android's xml eg ImageView, TextView, LinearLayout, RelativeLayout etc. 按组件:我的意思是任何可以添加到Android的xml的可视组件,例如ImageView,TextView,LinearLayout,RelativeLayout等。
Yes, I know the number of these components can be infinite (determined by the APIs in use), for which i would like to generate them dynamically 是的,我知道这些组件的数量可以是无限的(由使用的API决定),我想为它动态生成它们
Preferably without using someone else's library 最好不要使用别人的图书馆
You don't have to use any third-party libraries , since Java
has reflections . 您不必使用任何第三方库 ,因为
Java
有反射 。 This method will do everything for you and make the UI
without problems: 此方法将为您完成所有操作并使
UI
无问题:
for(String s : arrayWithNames){
View view = createViewInstance(0, s);
if(view instance of View){
//handle if it is view
}else{
//this is viewgroup
}
}
And createViewInstance()
: 和
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;
}
That's it. 而已。 You have everything to handle any kind of
View
. 你有一切可以处理任何类型的
View
。 I've tested the code above and used in project. 我测试了上面的代码并在项目中使用。 It works just fine.
它工作得很好。 Exactly same situation with other
Object
s. 与其他
Object
完全相同的情况。 You cannot create int
with reflection, but you can create Integer
, so what basically is same. 你不能用反射创建
int
,但你可以创建Integer
,所以基本上是相同的。
One problem with it there are much more types than just View
and ViewGroup
. 它的一个问题是,除了
View
和ViewGroup
之外,还有更多的类型。 But it also depends on how many kinds of Object
s you want to create... In given example let's say I'll do char
, String
, int
, Object
and then you can easily extend it. 但它还取决于你想要创建多少种
Object
...在给定的例子中,假设我将执行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);
}
}
Since all those data type are in the same package it makes much more easier for us. 由于所有这些数据类型都在同一个包中,因此对我们来说更容易。 Method
createVarInstance()
: 方法
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;
}
If it will be desired it is possible to make the one method for different packages. 如果需要,可以为不同的包制作一种方法。 If in future you want to create more and different types of variables, which are in different packages, so you will have to check names or do similar operations as in example with
View
s. 如果将来您想要创建更多不同类型的变量(这些变量位于不同的包中),那么您必须检查名称或执行类似于
View
的示例操作。
You can list UI components all the classes into the android.view
package or the android.view.View
sub-classes using The Reflection Library : 您可以使用反射库将所有类的UI组件列入
android.view
包或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);
To create a list of all the data-type you could do the same above using th Object class, but first, I'd personally ask myself what's the point doing this. 要创建所有数据类型的列表,您可以使用Object类执行相同的操作,但首先,我个人会问自己,这样做的重点是什么。
Reflections is an awesome library for Java. Reflections是一个很棒的Java库。 I'm not sure if it works on Android too.
我不确定它是否适用于Android。 Someone opened an issue , it got closed soon after with no explanation.
有人打开了一个问题 ,很快就关闭了,没有任何解释。
If you can get it to work in Android, you can use this code to get all Components: 如果您可以在Android中使用它,则可以使用此代码获取所有组件:
Reflections reflections = new Reflection("android.widget") //specifiy the package (TextView etc. are in here)
Set<Class<? extends View>> components = reflections.getSubTypesOf(View.class);
If you want, you can repeat this procedure with the android.view
package, where some other classes such as ViewGroup are located. 如果需要,可以使用
android.view
包重复此过程,其中包含ViewGroup等其他类。
Also, if you really want a String Array, get the names of the classes: 此外,如果您真的想要一个字符串数组,请获取类的名称:
List<String> componentNames = new ArrayList<String>();
for (Class<? extends View> c: components) {
componentNames.add(c.getName());
}
String[] allComponents = componentNames.toArray();
how about use a Factory to create Component like this: 如何使用Factory来创建这样的组件:
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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.