2015-05-26 20 views
24

Tworzę program, w którym muszę utworzyć listę wszystkich różnych składników systemu Android, ale zamiast ręcznie wymyślać i wpisywać listę List. Chciałbym programowo dowiedzieć się, czy mógłbym to zrobić, aby dodać String Arrays, jak poniżej?Jak mogę programowo utworzyć listę wszystkich składników interfejsu użytkownika systemu Android? na przykład TextView, ImageView itd.

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

Podobnie chciałbym programowo utworzyć Lista wszystkich różnych typów danych np Int, String, ArrayList itd. Należy doliczyć do tablic Smyczkowych jak poniżej

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

Co udało się zrobić do tej pory, to powyżej. Do tej pory pisałem je fizycznie jak powyżej.

Jak mogę to zrobić? Dzięki

Wyjaśnienie

Przez typów danych: mam na myśli typy zmienne zadeklarowane przechowuje dane np Int, String, Object, logiczna, dwu-, tablic, arraylists itp

przez składniki: Mam na myśli każdy element wizualny, który można dodać do xml Androida, np. ImageView, TextView, LinearLayout, RelativeLayout itp

Tak, wiem, że wiele z tych składników może być nieskończona (określony przez API w użyciu), dla których chciałbym aby wygenerować je dynamicznie

Korzystnie bez używając cudzego bibliotekę

+0

Chcesz listę wszystkich tych elementów, które istnieją we wszystkich Androida, albo tylko elementy i typy danych wykorzystywanych w aplikacji? –

+0

Programowo, wszystkie istniejące w systemie Android –

+0

Czy chcesz utworzyć listę składników interfejsu użytkownika bez użycia ListView? –

Odpowiedz

1

można listy składników interfejsu użytkownika wszystkie klasy w pakiecie android.view lub podklasy android.view.View pomocą The Reflection Library:

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

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

Aby utworzyć listę wszystkich typów danych, które można wykonać powyżej, używając klasy Object, ale najpierw osobiście zadałbym sobie pytanie, o co w tym chodzi.

1

Reflections to świetna biblioteka dla Javy. Nie jestem pewien, czy to też działa na Androidzie. Ktoś opened an issue, wkrótce potem został zamknięty bez wyjaśnienia.

Jeśli można zmusić go do pracy w systemie Android, możesz użyć tego kodu, aby uzyskać wszystkie składniki:

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

Jeśli chcesz, możesz powtórzyć tę procedurę z pakietem android.view, gdzie niektóre inne klasy, takie jako ViewGroup znajdują się.

Ponadto, jeśli naprawdę chcesz tablicę ciągów, uzyskać nazwy klas:

List<String> componentNames = new ArrayList<String>(); 
for (Class<? extends View> c: components) { 
    componentNames.add(c.getName()); 
} 
String[] allComponents = componentNames.toArray(); 


Jeśli powyższe rozwiązanie nie działa dla Ciebie, spróbuj się zajęcia z oficjalnej strony internetowej.Klasy są wymienione w pakietach android.view i android.widget. Po prostu skopiuj odpowiednie nazwiska i wklej je w kodzie źródłowym. To nie byłoby dynamiczne, ale działa.

9

Nie trzeba używać żadnych zewnętrznych bibliotek, ponieważ Java ma reflections. Metoda ta zrobi wszystko dla ciebie i sprawiają, że bez problemów 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():

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

to wszystko. Masz wszystko do obsłużenia każdego rodzaju View. Przetestowałem powyższy kod i użyłem go w projekcie. Działa dobrze. Dokładnie taka sama sytuacja z innymi Object s. Nie możesz utworzyć int z odbiciem, ale możesz utworzyć Integer, więc to, co w zasadzie jest takie samo.

Jednym z problemów jest znacznie więcej typów niż tylko View i ViewGroup. Ale zależy to również od tego, ile rodzajów Object chcesz utworzyć ... W danym przykładzie powiedzmy, że zrobię char, String, int, , a następnie możesz łatwo go rozszerzyć.

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

Ponieważ wszystkie te typy danych znajdują się w tym samym pakiecie, jest dla nas o wiele łatwiejsze. Metoda 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; 
} 

Jeśli zostanie ona pożądana jest możliwe, aby jeden sposób dla różnych pakietach. Jeśli w przyszłości chcesz tworzyć więcej i różne typy zmiennych, które znajdują się w różnych pakietach, musisz sprawdzić nazwy lub wykonać podobne operacje, jak w przykładzie z View s.

0

jak o użyciu fabryki, aby utworzyć komponent takiego:

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