Kodar-"test"

Discussion in 'Frågor, support och diskussion' started by Adevade, Sep 22, 2010.

  1. Adevade

    Adevade Youth Droid Medlem

    Joined:
    Apr 14, 2010
    Messages:
    135
    Likes Received:
    2

    MINA ENHETER

    Tjena!
    Har nyss börjat koda lite till Android själv och tycker det verkar roligt!

    Tänkte att kodare här på forumet kan ta en titt på ett exempel på en väldigt enkel app och sedan skriva koden som ni skulle gjort det, och se hur många olika sätt det finns och ifall något är bättre/snabbare. Kan vara kul och nyttigt (iaf för nybörjare) att se samma sak kodad på olika sätt.

    Blev lite rörig beskrivning, men tycker bara det skulle vara en kul grej! :)
    Här kommer exempelappen jag hade tänkt mig:

    [​IMG]

    Man räknar alltså saker. Simple as that :P

    Code:
    package com.adevade.counter;
    
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.DialogInterface;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class Counter extends Activity {
    	
    	Button buttonAdd1, buttonAdd2, buttonAdd5, buttonAdd10, buttonReset;
    	TextView counter;
    	AlertDialog.Builder builder;
    	AlertDialog dialogReset;
    	int count = 0;
    	
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            
            counter = (TextView)findViewById(R.id.counter);
            
            buttonAdd1 = (Button)findViewById(R.id.buttonAdd1);
            buttonAdd2 = (Button)findViewById(R.id.buttonAdd2);
            buttonAdd5 = (Button)findViewById(R.id.buttonAdd5);
            buttonAdd10 = (Button)findViewById(R.id.buttonAdd10);
            buttonReset = (Button)findViewById(R.id.buttonReset);
            
            builder = new AlertDialog.Builder(this);
            builder.setCancelable(false);
            builder.setMessage("Do you really want to reset?");
            builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
    			@Override
    			public void onClick(DialogInterface dialog, int which) {
    				count = 0;
    				counter.setText(String.valueOf(count));
    				
    				Toast.makeText(getApplicationContext(), "Done", Toast.LENGTH_SHORT).show();
    			}
    		});
            builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
    			@Override
    			public void onClick(DialogInterface dialog, int which) {
    				dialog.cancel();
    			}
    		});
            
            dialogReset = builder.create();
            
            counter.setText(String.valueOf(count));
            
            buttonAdd1.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				count ++;
    				counter.setText(String.valueOf(count));
    			}
            	
            });
            
            buttonAdd2.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				count ++;
    				count ++;
    				counter.setText(String.valueOf(count));
    			}
            	
            });
            
            buttonAdd5.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				count ++;
    				count ++;
    				count ++;
    				count ++;
    				count ++;
    				counter.setText(String.valueOf(count));
    			}
            	
            });
            
            buttonAdd10.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				count ++;
    				count ++;
    				count ++;
    				count ++;
    				count ++;
    				count ++;
    				count ++;
    				count ++;
    				count ++;
    				count ++;
    				counter.setText(String.valueOf(count));
    			}
            	
            });
            
            buttonReset.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				dialogReset.show();
    			}
            	
            });
        }
    }
    
     
  2. afzkl

    afzkl Youth Droid Medlem

    Joined:
    Aug 27, 2009
    Messages:
    184
    Likes Received:
    6

    MINA ENHETER

    Hade väll gjort på ungefär samma vis, det jag absolut skulle gjort annorlunda är följande:

    Ersatt:
    Code:
    count ++;
    count ++;
    count ++;
    count ++;
    count ++;
    count ++;
    count ++;
    count ++;
    count ++;
    count ++;
    counter.setText(String.valueOf(count));
    
    etc.

    Med:
    Code:
    count += 10;
    counter.setText(String.valueOf(count));
    
     
  3. yrara

    yrara Teen Droid Medlem

    Joined:
    Sep 30, 2009
    Messages:
    428
    Likes Received:
    8

    MINA ENHETER

    Det kan ju dessutom refaktoriseras till en metod som kan användas av alla knapparna:

    Code:
    private void addCount(int value) {
       count += value;
       counter.setText(String.valueOf(count));
    }
    
    Code:
            buttonAdd10.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
                                addCount(10);
    			}
            });
    
    Man kan tänka sig att man sätter värdet som en tag på knappen också, så kan man använda samma listener till alla knappar:

    Code:
        private OnClickListener buttonAddClick = new OnClickListener() {
           public void onClick(View v) { addCount((int) v.getTag()); }
        };
    
    Code:
    buttonAdd1.setTag(1);
    buttonAdd2.setTag(2);
    buttonAdd5.setTag(5);
    buttonAdd10.setTag(10);
    
    buttonAdd1.setOnClickListener(buttonAddClick);
    buttonAdd2.setOnClickListener(buttonAddClick);
    buttonAdd5.setOnClickListener(buttonAddClick);
    buttonAdd10.setOnClickListener(buttonAddClick);
    
     
  4. yrara

    yrara Teen Droid Medlem

    Joined:
    Sep 30, 2009
    Messages:
    428
    Likes Received:
    8

    MINA ENHETER

    OK. Jag är allergisk mot långa metoder. Långa onCreate i synnerhet, och där har du för tillfället precis all din programkod :)

    Jag vill inte påtvinga någon annan min programmeringsstil, men eftersom du frågar, så postar jag det ändå här. Jag tycker att det blir mer semantiskt, lättare att följa flödet, lättare att hitta de delar av koden man letar efter, lättare att hitta ett fel ur en stack trace, ifall man delar upp det lite:

    Code:
    package com.adevade.counter;
    
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.DialogInterface;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class Counter extends Activity {
    	
        AlertDialog dialogReset = null;
        int count = 0;
    	
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
    
            setupContent(R.layout.main);
    
            setCount(0);
            
        }
    
        private void setCount(int value) {
            count = value;
            counter.setText(String.valueOf(count));
        }
    
        private OnClickListener buttonAddClick = new OnClickListener() {
           public void onClick(View v) { 
               int add = (int) v.getTag();
               setCount(count + add);
           }
        };
    
        private OnClickListener buttonResetClick = new OnClickListener() {
           public void onClick(View v) {
    
               if(dialogReset == null) {
                   dialogReset = new AlertDialog.Builder(this)
                                         .setCancelable(false)
                                         .setMessage("Do you really want to reset?")
                                         .setPositiveButton("Yes", resetYesClick)
                                         .setNegativeButton("No", resetNoClick)
                                         .create();
               }
    
               dialogReset.show();
           }
        };
    
        private OnClickListener resetYesClick = new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
    
    	    setCount(0);
                Toast.makeText(getApplicationContext(), "Done", Toast.LENGTH_SHORT).show();
    
            }
        }
    
        private OnClickListener resetNoClick = new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        }
    
        Button buttonAdd1, buttonAdd2, buttonAdd5, buttonAdd10, buttonReset;
        TextView counter;
    
        private void setupContent(int layoutResID) {
    
            setContentView(layoutResID);
            
            counter = (TextView)findViewById(R.id.counter);
            
            buttonAdd1 = (Button)findViewById(R.id.buttonAdd1);
            buttonAdd2 = (Button)findViewById(R.id.buttonAdd2);
            buttonAdd5 = (Button)findViewById(R.id.buttonAdd5);
            buttonAdd10 = (Button)findViewById(R.id.buttonAdd10);
            buttonReset = (Button)findViewById(R.id.buttonReset);
    
            buttonAdd1.setTag(1);
            buttonAdd2.setTag(2);
            buttonAdd5.setTag(5);
            buttonAdd10.setTag(10);
    
            buttonAdd1.setOnClickListener(btnAddClick);
            buttonAdd2.setOnClickListener(btnAddClick);
            buttonAdd5.setOnClickListener(btnAddClick);
            buttonAdd10.setOnClickListener(btnAddClick);
            buttonAddReset.setOnClickListener(btnResetClick);
    
        }
    }
    
    Jag hackade ihop allt i notepad, så något slarvfel kan finnas :) Men sådär skulle jag ha gjort den.

    Jag brukar alltid ha en setupContent längst ner som helt enkelt ser till att alla fält från XML-filen finns tillgängliga. Det handlar inte om att exakt det här sättet är det bästa, utan helt enkelt att man måste hitta ett sätt, som man kan följa, så att man inte behöver scrolla förbi hundra deklarationer, utan helt enkelt kan se att "OK, när activityn startas laddas alla fält in från R.layout.main, och därefter anropas setCount."

    Det är det som görs när activityn skapas, så det är det jag tycker ska stå där. Vad olika knappar gör när de blir klickade är inte intressant när man ska titta på vad som händer i just onCreate.

    Mina 2 öre :)

    EDIT: För övrigt är väl dialog.cancel(); standardbeteende vilken knapp man än väljer? Dvs. man behöver inte spec.a att den ska stänga dialogen när man klickar på en knapp, för det gör den ändå (det är t.ex. därför du inte har med den koden i Yes-knappen). Därav skulle du inte behöva någon kod alls i onClick på nej-knappen (den behöver fortfarande en handler, men den kan vara tom!) För mig är det ett så vanligt scenario, att jag brukar ha en Utilities-klass med en handler för det, som jag alltid kan anropa:

    Code:
    .setNegativeButton("No", Utilities.dialogInterface_noAction)
    
     
    Last edited: Sep 23, 2010
  5. Adevade

    Adevade Youth Droid Medlem

    Joined:
    Apr 14, 2010
    Messages:
    135
    Likes Received:
    2

    MINA ENHETER

    Kul att se några olika exempel! :) Ska kolla närmre på din kod imorgon, yrara!

    Jag har som sagt bara nyss börjat kolla lite på Java och Android-programmering, så mitt första exempel är vad jag lyckades lista ut på egen hand :P
    Skulle vara roligt att se mer avancerad kod och hur ni programmerare skulle skrivit den. Känns som att man kan lära en hel del. Främst som nybörjare, men kanske även ett och annat knep från en annan gammal programmerar-räv! ;)
     
  6. PatrikS

    PatrikS Senior Droid Medlem

    Joined:
    Jun 29, 2009
    Messages:
    1 123
    Likes Received:
    65

    MINA ENHETER

    En fråga om tycke och smak men jag har börjat använda
    Code:
    android:onClick="myMethod"
    
    och sedan i kod motsvarande metod :
    Code:
    public void myMethod(View target) {
          target.getTag();
          int add = (int) v.getTag();
          setCount(count + add);
    }
    
    givetvis finns även android:tag="5" att sätta i xml:en också.

    Detta medför att man slipper plocka fram objekten och sätta pekare på dom ö.h taget..


    dvs man kan sopa :
    Code:
    buttonAdd1 = (Button)findViewById(R.id.buttonAdd1);
            buttonAdd2 = (Button)findViewById(R.id.buttonAdd2);
            buttonAdd5 = (Button)findViewById(R.id.buttonAdd5);
            buttonAdd10 = (Button)findViewById(R.id.buttonAdd10);
            buttonReset = (Button)findViewById(R.id.buttonReset);
    
            buttonAdd1.setTag(1);
            buttonAdd2.setTag(2);
            buttonAdd5.setTag(5);
            buttonAdd10.setTag(10);
    
            buttonAdd1.setOnClickListener(btnAddClick);
            buttonAdd2.setOnClickListener(btnAddClick);
            buttonAdd5.setOnClickListener(btnAddClick);
            buttonAdd10.setOnClickListener(btnAddClick);
            buttonAddReset.setOnClickListener(btnResetClick);
    
    
    däremot vet jag inte om det blir någon prestandamässig skillnad men det blir renare i din activity-klass.
     
  7. PatrikS

    PatrikS Senior Droid Medlem

    Joined:
    Jun 29, 2009
    Messages:
    1 123
    Likes Received:
    65

    MINA ENHETER

    apropå positive och negative-buttons så tycker jag det var trist att det inte är lika bra/enkelt som i .net-världen.
    Eftersom man ändå "låser" UI så returnerar man utslaget i det programmspråket.
    Dvs man får tillbaka ett "Type: System.Windows.Forms.DialogResult" som anger vad användaren valt.
    Finns andra saker man saknar också som events&delegates...
    fast det går att lösa med anonyma klasser istället :)
     
  8. yrara

    yrara Teen Droid Medlem

    Joined:
    Sep 30, 2009
    Messages:
    428
    Likes Received:
    8

    MINA ENHETER

    Dock låser man ju inte UI:t i den bemärkelsen, eftersom man kan sätta en egen vy, som kan interagera med UI:t. Man kan inte förlita sig på att användaren ska klicka på en av knapparna för att UI-tråden ska fortsätta.
     
  9. Zooklubba

    Zooklubba Android Medlem

    Joined:
    Jul 10, 2010
    Messages:
    6 448
    Likes Received:
    2 199

    MINA ENHETER

    Inte orkat läsa igenom alla idéer osv.
    Jag skulle dock kört en setOnClickListener(this) på alla knappar. Låta klassen implementera den och därefter ha onClickfunktionen där man kör en switch view.getId om jag minns rätt...