簡體   English   中英

如何以編程方式動態創建所有Android ui組件的列表?例如TextView,ImageView等

[英]How can I dynamically create a list of all Android ui components programmatically? e.g. TextView, ImageView etc

我正在創建一個程序,我需要在其中創建所有不同Android組件的列表,而不是手工識別和鍵入List 我想以編程方式弄清楚我是否可以完成此操作以添加到String Arrays中,如下所示?

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

類似地,我想以編程方式創建一個包含所有不同數據類型的List ,例如Int,String,ArrayList等,以添加到String Arrays中,如下所示

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

到目前為止我能夠做到的就是上面。 到目前為止,我一直在打字,如上所述。

我怎么能做到這一點? 謝謝

澄清

按數據類型:我的意思是聲明為保存數據的變量類型,例如Int,String,object,boolean,double,arrays,arraylists等。

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

是的,我知道這些組件的數量可以是無限的(由使用的API決定),我想為它動態生成它們

最好不要使用別人的圖書館

您不必使用任何第三方庫 ,因為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
    }
}

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完全相同的情況。 你不能用反射創建int ,但你可以創建Integer ,所以基本上是相同的。

它的一個問題是,除了ViewViewGroup之外,還有更多的類型。 但它還取決於你想要創建多少種Object ...在給定的例子中,假設我將執行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;
}

如果需要,可以為不同的包制作一種方法。 如果將來您想要創建更多不同類型的變量(這些變量位於不同的包中),那么您必須檢查名稱或執行類似於View的示例操作。

您可以使用反射庫將所有類的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);

要創建所有數據類型的列表,您可以使用Object類執行相同的操作,但首先,我個人會問自己,這樣做的重點是什么。

Reflections是一個很棒的Java庫。 我不確定它是否適用於Android。 有人打開了一個問題 ,很快就關閉了,沒有任何解釋。

如果您可以在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.viewandroid.widget包中。 只需復制相關名稱並將其粘貼到源代碼中即可。 這不是動態的,但它有效。

如何使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM