# Code effizienter machen



## mock789 (10. Okt 2012)

Hallo,

ganz einfache Frage:

Ich habe fogenden Code:


```
private Button pizzabrot;
	private Button pizzabrot_rucola;
	private Button margherita;
	private Button napoli;
	private Button funghi;
	private Button salami;
	private Button prosciutto;
	private Button campania;
	private Button capricciosa;
	private Button contadina;
	private Button romana;
	private Button regina;
	private Button reginella;
	private Button sole_mio;
	private Button tonno_cipolle;
	private Button quattro_stagioni;
	private Button verdure;
	private Button calzone;
	private Button frutti_di_mare;
	private Button alla_casa;
	private Button spinaci;
	private Button speciale;
```
 


Kann ich das irgendwie effizienter machen z.B. mit einer Schleife und einem Array oder irgendwie, dass ich nicht ständig die selbe Zeile schreiben muss??? 


Vielen Dank


----------



## Manello (10. Okt 2012)

Du könntest mal zumindest dass "private button" abkürzen,
indem du einen Name dafür definierst und ihn stattdessen einsetzt. (z.b. pb/prbu)


----------



## noobadix (10. Okt 2012)

Hi,

knapper kannst du das z.B. so formulieren:


```
private Button button1, button2, button3;
```

Etwas pompöser und damit vielleicht weniger effizienter wäre das Speichern in einem Vector oder sogar einer HashMap:


```
String buttonNamen = new String[]{"button1", "button2", "button3"};

Vector<Button> buttons = new Vector<Button>();
for(String name : buttonNamen){
     buttons.add(new Button(name));
}

//oder

HashMap<String, Button> buttonHM = new HashMap<String, Button>();

for(String name : buttonNamen){
     buttonHM.put(name, new Button(name));
}
```

Gruß!


----------



## Marco13 (10. Okt 2012)

:autsch: ???:L

private List<Button> buttons;


----------



## Landei (10. Okt 2012)

Wenn sich all die Buttons ähnlich verhalten, wäre eine Liste wahrscheinlich wirklich das Beste. Die Namen kann man in einem String-Array bereitstellen.


----------



## KranzKrone (10. Okt 2012)

Statt den schicken Buttons könntest du auch ein JList Element oder so nehmen. Dann könntest du eine Auswahl treffen und musst nur auf wenige Event abfragen. Bei den Buttons könnte man dies auch machen, jedoch hast du bei einer Programmerweiterung schreibarbeit ohne Ende. 

So kannst du deine Liste aus einer Datenbank erzeugen lassen und so


----------



## mock789 (11. Okt 2012)

Super... vielen Dank für die Antworten!

Mein Problem geht weiter: Wie kann ich denn dann das effizienter machen???



```
pizzabrot  = (Button) this.findViewById(R.id.pizzabrot);
        pizzabrot.setOnClickListener(this);
        pizzabrot_rucola  = (Button) this.findViewById(R.id.pizzabrot_rucola);
        pizzabrot_rucola.setOnClickListener(this);
        margherita  = (Button) this.findViewById(R.id.margherita);
        margherita.setOnClickListener(this);
        napoli = (Button) this.findViewById(R.id.napoli);
        napoli.setOnClickListener(this);
        funghi= (Button) this.findViewById(R.id.funghi);
        funghi.setOnClickListener(this);
        salami= (Button) this.findViewById(R.id.salami);
        salami.setOnClickListener(this);
        prosciutto= (Button) this.findViewById(R.id.prosciutto);
        prosciutto.setOnClickListener(this);
        campania= (Button) this.findViewById(R.id.campania);
        campania.setOnClickListener(this);
        capricciosa = (Button) this.findViewById(R.id.capricciosa);
        capricciosa.setOnClickListener(this);
        contadina= (Button) this.findViewById(R.id.contadina);
        contadina.setOnClickListener(this);
        romana= (Button) this.findViewById(R.id.romana);
        romana.setOnClickListener(this);
        regina= (Button) this.findViewById(R.id.regina);
        regina.setOnClickListener(this);
        reginella= (Button) this.findViewById(R.id.reginella);
        reginella.setOnClickListener(this);
        sole_mio = (Button) this.findViewById(R.id.sole_mio);
        sole_mio.setOnClickListener(this);
        tonno_cipolle= (Button) this.findViewById(R.id.tonno_cipolle);
        tonno_cipolle.setOnClickListener(this);
        quattro_stagioni = (Button) this.findViewById(R.id.quattro_stagioni);
        quattro_stagioni.setOnClickListener(this);
        verdure = (Button) this.findViewById(R.id.verdure);
        verdure.setOnClickListener(this);
        calzone = (Button) this.findViewById(R.id.calzone);
        calzone.setOnClickListener(this);
        frutti_di_mare = (Button) this.findViewById(R.id.frutti_di_mare);
        frutti_di_mare.setOnClickListener(this);
        alla_casa = (Button) this.findViewById(R.id.alla_casa);
        alla_casa.setOnClickListener(this);
        spinaci = (Button) this.findViewById(R.id.spinaci);
        spinaci.setOnClickListener(this);
        speciale = (Button) this.findViewById(R.id.speciale);
        speciale.setOnClickListener(this);
```


----------



## mock789 (11. Okt 2012)

noobadix hat gesagt.:


> Hi,
> 
> knapper kannst du das z.B. so formulieren:
> 
> ...




Das hier funktioniert leider nicht bei mir???:L


```
String[] buttonNamen = new String[]{"pizzabrot", "pizzabrot_rucola",  "margherita", "napoli", "funghi", 
			"salami", "prosciutto", "campania", "capricciosa", "contadina", "romana", 
			"regina", "reginella", "sole_mio", "tonno_cipolle", "quattro_stagioni",  
			"verdure", "calzone", "frutti_di_mare", "alla_casa", "spinaci", "speciale"
			};
	
	Vector<Button> buttons = new Vector<Button>();
	{
	for(String name : buttonNamen){
	     buttons.add(new Button(name));
	}
```



Bei  buttons.add(new Button(name)); kringelt er mir new Button(name) rot an und sagt der Konstruktor für Button ist nicht definiert. Ich mach da irgendeinen Anfängerfehler :autsch:


----------



## Landei (11. Okt 2012)

Man könnte aus zwei Zeilen eine machen:

```
private void setButtonListener(/*was auch immer dein ID Typ ist*/ id) {
   Button button = (Button) this.findViewById(id);
   button.setOnClickListener(this);
}
...
setButtonListener(R.id.pizzabrot);
setButtonListener(R.id.pizzabrot_rucola);
setButtonListener(R.id.margherita);
```

Oder wenn du bei allen Buttons in einer [c]List[/c] ([c]HashMap[/c] geht ähnlich) den Listener setzen willst:

```
for(Button button : buttonList) {
   button.setOnClickListener(this);
}
```

Noch cleverer wäre, da wo du den Button erzeugst - also schon "in der Hand hältst" - den Listener zu setzen. Mit noobadix' [c]HashMap[/c]-Version kommst du übrigens leichter an die Buttons ran.


Aber vielleicht solltest du auch die vorgeschlagene Variante mit einer Auswahlliste oder ComboBox statt Buttons mal ausprobieren...


----------



## Tomate_Salat (11. Okt 2012)

mock789 hat gesagt.:


> Bei buttons.add(new Button(name)); kringelt er mir new Button(name) rot an und sagt der Konstruktor für Button ist nicht definiert. Ich mach da irgendeinen Anfängerfehle



Auch als Anfänger kann man die Doku lesen ;-)
Button | Android Developers

Es gibt bei Android für Buttons keinen Konstruktor, bei dem der "titel" übergeben wird. Ausschließlich folgende:

```
public Button (Context context)
public Button (Context context, AttributeSet attrs)
public Button (Context context, AttributeSet attrs, int defStyle)
```

Ansonsten Konventionen beachten:
Man nutzt keine [c]_[/c] für Variablennamen in Java:
[c]pizzabrot_rucola[/c] schreibt man besser [c]pizzabrotRucola[/c], also lowerCamelCase


----------



## schlingel (11. Okt 2012)

Euren Enthusiasmus in allen Ehren aber so wie ich das sehe ist der Button sowieso das falsche View für die Aufgabe. Ein jeder Button hier war ein Pizzaname also ist mit an Sicherheit grenzender Wahrscheinlichkeit eine ListView mitsamt einem PizzaAdapter die beste und effizienteste Möglichkeit hier zu Werke zu gehen.

Vorteile:
- Model u. UI getrennt und das von Haus aus.
- Du hast einen zentralen Click-Handler (onItemClick) der den Index mitbekommt. Mit dem kannst du dann adapter.getItem(index) das Model-Objekt auslesen.
- Du hast eine vom System optimierte Anzeige mit Scrolling, View Caching, etc.

Nachteile:
- Du hättest eine Klasse mehr (PizzaAdapter) - aber so sollte es auch sein.


----------



## KranzKrone (24. Okt 2012)

Ich denke, dass in diesem Fall die eine Klasse mehr auch nicht auffällt. An dieser Stelle sollte man die Design Patter einsetzen. Falls du dir eine Kasse programmieren willst und im Reallife betreiben willst, so empfehle ich dir ein Programm zu kaufen, da diese getestet sind und du keine Arbeit mehr reinstecken musst. 

An sich ist der Kauf zwar teuerer aber du hast ein Produkt in der Hand, was viele einsetzten. 

Ansonsten macht natürlich die  Vectorklasse sehr viel sinn, da du hier deine Daten aus einer Datenbank später wieder auslesen kannst.

Nehmen wir zum Beispiel die großen Imbissketten, da bekommt jede Kasse am Morgen ein Update zu den Preisen und Angeboten, weiterhin sind in einer Filialie alle Kassen miteinander vernetzt, so dass wenn ein Produkt alle ist der Kasserierer die Bestellung nicht mehr annehmen kann.
Genial oder? 

Kassensysteme können sehr komplex sein...


----------



## schlingel (24. Okt 2012)

Ein Ratschlag die Software zu kaufen anstatt sie zu programmieren ist einem Programmiererforum wohl fehl am Platze.


----------



## Robokopp (24. Okt 2012)

So, jetzt melde ich mich auchmal zu Wort.

Die effizienteste Lösung die ich kenne ist das auslösen eines Klicks per XML, denn so spart man sich 1. Die Definition des Buttons, 2.Die Zuweisung über findViewById, 3. Das zuweisen eines Listeners(Action,OnTouch,OnClick,...)

Das sieht in etwa so aus:

[XML]<Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        androidnClick="buttonHandler" />[/XML]



```
public void buttonHandler(View v){
if(v.getId()==R.id.button1){
//do something


}
```

allerdings brauchst du dennoch die Zuweisung, falls du etwas anderes als das Klickevent des Buttons abzufragen möchtest, etwa Text ändern,disable/enable


----------



## schlingel (24. Okt 2012)

Das ist trotzdem nicht effizienter als die Lösung per ListView, da du so n Buttons im Layout hast die ja alle einzeln in die jeweilige GroupView instanziert werden müssen.

Außerdem musst du dann noch manuell eine ScrollView darum herum packen. 

Das ist nur für kleine n performanter!

Abgesehen davon, dass der Code schon für n >= 5 grauslich wird in dem Button-Handler. 

Wobei deine Technik nicht schlecht ist! Ich mach das auch immer so in dem ich die Activity als ClickHandler für die Buttons verwende wenn ich 4 oder weniger Buttons habe.


----------



## Robokopp (24. Okt 2012)

schlingel hat gesagt.:


> Das ist trotzdem nicht effizienter als die Lösung per ListView, da du so n Buttons im Layout hast die ja alle einzeln in die jeweilige GroupView instanziert werden müssen.
> 
> Außerdem musst du dann noch manuell eine ScrollView darum herum packen.
> 
> ...



Hä?Ging es nicht darum den Code des Threaderstellers zu vereinfachen?Ich weiß gerade nicht was das mit einem ListView zutun hat.Die Buttons existieren doch so oder so im Layout.Und was für ein ScrollView?kann man ja machen, aber hat doch ansich nichts mit den Buttons zutun.

für n>=5 wird er weniger grauslich als auf herkömmliche Art und weise, da immer nur die eine Methode erweitert werden muss.Und logischerweise muss hier mindestens mal geprüft werden, von welchem Button die Methode aufgerufen wird


----------



## schlingel (25. Okt 2012)

> Hä?Ging es nicht darum den Code des Threaderstellers zu vereinfachen?


Ja. Ich hab's jetzt zwar auf die Laufzeit-Performance bezogen aber es geht trotzdem mit der ListView auch LOC ökonomischer in einer ListView.

Aus folgenden Gründen:
1. Du hast eine saubere Trennung zwischen Model und UI. Dadurch kannst du die Anzahl der Pizzen vollkommen losgelöst von den Buttons bestimmen. Noch besser: Du fügst einfach eine Pizza hinzu - per Webservice oder ähnlichem - und musst die UI gar nicht angreifen um diese verfügbar zu machen.
2. Du hast weiterhin einen einzigen Click-Handler OnItemClickHandler um genau zu sein. Dieser wird gefeuert, wenn ein Item in der ListView angeklickt wird. In diesem Handler bekommst du den Index des geklickten Elements mit. Der reicht auch schon aus, um das Model-Objekt an der Stelle vom Adapter zu bekommen. 
3. Du musst weniger in die UI eingreifen, da du selbst nicht für's Scrollen sorgen musst.



> Die Buttons existieren doch so oder so im Layout.


Ja und das ist schlecht.  
Für dich als Programmierer weil du sie manuell erweitern musst und für die Laufzeit, da eine GroupView nicht so effizient verwaltet wird vom System wie eine ListView. Übrigens, das Zeug mit der besseren Verwaltung in einer ListView stammt nicht von mir, sondern von Google.



> für n>=5 wird er weniger grauslich als auf herkömmliche Art und weise, da immer nur die eine Methode erweitert werden muss.


Nein, dadurch wird der Code immer scheußlicher da du eine Methode angreifen musst! Das fällt vollkommen weg mit einer ListView. Du hast also keinen ClickHandler mit einem ewig langen Switch oder n IFs, sondern eine Methode die für alle verschiedenen Pizzi gleich ist.


----------

