Android-Apps: Krims-Krams für den Hausgebrauch

Diskutiere Android-Apps: Krims-Krams für den Hausgebrauch im Codeschnipsel u. Projekte Forum; Prinzipiell solltest du aber eigentlich in der Lage sein auf die ImageViews zuzugreifen. Die Meldung die dir AS da gibt ist ja nur eine Warnung /...

  1. Robat
    Robat Bekanntes Mitglied
    Prinzipiell solltest du aber eigentlich in der Lage sein auf die ImageViews zuzugreifen.
    Die Meldung die dir AS da gibt ist ja nur eine Warnung / ein Hinweis an dich das du Variablen anlegst, die du aber nie benutzt.
    Spätestens nachdem hinzufügen des OnClickListeners sollte die Meldung eigentlich verschwunden sein. Hier noch mal an einem kleinen Beispiel.
    Code (Java):

    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
        private Button button;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            button = findViewById(R.id.button);
            button.setOnClickListener(this); // wenn du diese + die button.setText(..) Zeile auskommentierst sollte die Warnung wieder da sein.
        }

        @Override
        public void onClick(View view) {
             switch(view.getId()) {
                 case R.id.button: button.setText("Foo"); break;
              }
         }
    }
     
    Manchmal ist die Warnung auch ein Zeichen an dem man erkennen kann, dass man die Komponente nur in einer Methode braucht und sie so zu einer lokalen Variable machen kann.
     
  2. Javinner
    Javinner Aktives Mitglied
    @Robat
    Habe dein Vorschlag jetzt umgesetzt und was soll ich schreiben?! Ich schreibe AMAZING!, Vielen Dank!
    Nun werde ich versuchen, es beim nächsten Post einzubeziehen!

    ImageViews france und italy
    Das Problem mit den ImageViews:
    Habe jetzt was ausprobiert und es kommen verschiedene Hinweise seitens AS:
    Erstmal wie gehabt: is assigned, but never accessed
    wenn ich prepareImageView einsetze
    Code (Java):
    public class MainActivity extends Activity implements ImageView.OnClickListener
    {

        private final String MSG_TAG = "MainActivity";
        /**
         * if LOGGING is true, you can follow the app in the Logcat.
         * Choose for this "error" as type and "show only selected application" to see it only.
         */

        private final boolean LOGGING = true;

        private ImageView france, italy;
        private View first_color, second_color, third_color;

        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
       
            france = prepareImageView(R.id.iw_flag_france);
            italy = prepareImageView(R.id.iw_flag_italy);

     
    /**
    * prepare an ImageView.
    * ImageView will get an ID and be set to OnClickListener
    * @param id id for ImageView
    * @return prepared ImageView
    */

    private ImageView prepareImageView(int id)
    {
        getInfoLog("prepareImageView");
        ImageView imageView = findViewById(id);
        imageView.setOnClickListener(this);
        return imageView;
    }
     
    Und dann field can be converted to a local variable ohne
    Code (Java):
    public class MainActivity extends Activity implements ImageView.OnClickListener
    {

        private final String MSG_TAG = "MainActivity";
        /**
         * if LOGGING is true, you can follow the app in the Logcat.
         * Choose for this "error" as type and "show only selected application" to see it only.
         */

        private final boolean LOGGING = true;

        private ImageView france, italy;
        private View first_color, second_color, third_color;

        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

       
            france = findViewById(R.id.iw_flag_france);
            france.setOnClickListener(this);

            italy = findViewById(R.id.iw_flag_italy);
            italy.setOnClickListener(this);
     
    So richtig verstehe ich es noch nicht, warum das so ist.
     
    Robat gefällt das.
  3. Robat
    Robat Bekanntes Mitglied
    Das Verhalten ist eigentlich relativ einfach zu erklären.

    is assigned, but never accessed
    Du machst mit deinen ImageViews ja nichts. Das einzige was du machst ist sie zu initialisieren. Deshalb "warnt" dich AS davor "sinnlos" Variablen anzulegen.
    Die onClick-Methode kannst du ja beispielsweise auch über XML festlegen und müsstest die ImageViews so gar nicht referenzieren.
    Code (Java):

    android:onClick="onClick"
     
    field can be converted to a local variable
    Hier weist dich AS nur darauf hin, dass du deine Variable nur an einem Platz nutzt und du sie daher auch zu einer lokalen Variable konvertieren kannst.
    Deinem Programm würde es also ausreichen in der onCreate() Methode jeweils eine lokale Variable für die ImageViews zu haben.
     
  4. thecain
    thecain Aktives Mitglied
    Kann der clicklistener nicht direkt auf dem imageView als lambda oder anonyme klasse definiert werden? So habe ich es gemeint mit if else sparen.
    Mit der android magie kenne ich mich nicht aus.
     
  5. Javinner
    Javinner Aktives Mitglied
    @Robat
    Vielen Dank, jetzt ist es verständlich :)
    @thecain
    Oh, Lambda-Ausdrücke.. Da kenne ich mich leider gar nicht gut aus. Eventuell liest @Flown hier mit ;)
     
  6. Robat
    Robat Bekanntes Mitglied
    Mittlerweile kann man afaik auch Lambdas benutzten. Dennoch finde ich es "unnötig" extra eine Komponente im Java-Code zu referenzieren nur um ihr den onClick-Listener mitzugeben wenn ich das ganze auch über XML machen kann.
     
  7. thecain
    thecain Aktives Mitglied
    Ich sehe den Vorteil in der "Separation of Concerns". Der Switch Case fällt dann weg und die Komponenten könnten einfacher getrennt werden, wenn der Code wächst.
    Aber die ganze XML Magie kannte/kenne ich nicht. Unordentlicher ist es auf keinen Fall so wie es jetzt ist.
     
    Robat gefällt das.
  8. Javinner
    Javinner Aktives Mitglied
    Nach paar Tagen Testzeit läuft die App einwandfrei, aber ich habe festgestellt, dass die Farbe der Würfel oben und unten außerhalb des Würfels zu sehen ist, siehe Bild(DiceGame_Farbe außerhalb Würfel). Dies ist natürlich ein dicker Patzer und soll nun korrigiert werden. Aber nicht nur das, denn wie es sich herausgestellt hat, ist der Code verbesserungswürdig und Dank Forumsmitglieder wie @thecain und @Robat, welche mich darauf aufmerksam machten und durch Beispielcode mir den Weg zur Lösung des Problems ebneten, will ich natürlich den Code überarbeiten und neue Erkenntnisse darin einfliesen lassen. Nicht zuletzt schwebt mir der Gedanke, das Design zu erweitern, in dem ich die jeweilige Landesflagge als Hintergrund einblende und die Würfel ebenso passend einfärbe, siehe Bild(DiceGame_Überlegungen_ErweitertesDesign). Aber ebenso wollte ich die App für die Zukunft wappnen, damit eine mögliche Erweiterung sich so einfach wie möglich realisieren läst. Zudem las ich mich in das Thema "Layouts" ein und war von etwas hell auf begeistert!, so dass ich mich entschied, die neue Erkenntnisse in die App einzubinden.

    Was passiert nun, wenn ein Flaggen-Icon berührt wird? Es soll der Hintergrund in landesfarben und die Würfel passend gefärbt werden. Also braucht man ein extra Bild für den Hintergrund? Aber es ist doch recht umständlich, denn dann brauche ich fürs Erste so ein Bild. Dann muss die Symetrie stimmen und nicht zuletzt, sollten die Würfel exakt die gleiche Farbe Haben, wie der Hintergrund auch. Was mache ich also, wenn ich entscheide, eine Farbe etwas heller zu nehmen? Aber einfach nur ein Bild für jede Flagge zu erstellen erscheint mir nach einer Weile als umständlich. Hier entscheide ich mich, die neu erworbenen Kenntnisse, welche ich @Robat zu vedanken habe, maximal auszuweiten.

    Dann das Design. Nach der Vorgabe soll ja die Flaggen-Bar und die Würfel über der Flagge liegen. Es muss also eine andere Lösung her, denn nur mit einem vertikalen Linearlayout komme ich hier nicht weiter. Hier entscheide ich mich für ein RelativeLayout, weil all seine Kinder auch übereinander Platz nehmen können und eine freie Positionierung erlaubt wird. Also muss die Hierarchie so lauten:

    RealtiveLayout(main)
    • LinearLayout(horizontal) Flaggen-Bar
    • LinearLayout(vertikal) Würfel
    • LinearLayout(horizontal) Hintergrund

    LinearLayout(horizontal) Flaggen-Bar
    Hier bleibt alles wie gehabt, einzig und allein muss ich diesen an das Eltern-Layout kleben.
    Open (open)
    Code (Java):

    android:layout_alignParentEnd="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
     


    LinearLayout(horizontal) Hintergrund
    Hier wird es interessant, den dieses Layout hat weitere drei Layouts inne, im späteren Verlauf werde ich paar Zeilen dazu schreiben. Zunächst klebe ich es ebenso an das Eltern-Layout:
    Open (open)
    Code (Java):

    android:layout_alignParentBottom="true"
    android:layout_alignParentEnd="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
     


    LinearLayout(vertikal) Würfel
    Das Problemmkind Würfel. Die Farbe tritt oben und unten über die Grenzen des Würfel-Icons aus und das sieht nicht schön aus. Ein Blick in die Bibliothek und man liest, dass Android Entwickler an der Stelle empfehlen, ein einzelnes ImageView in ein FrameLayout zu verpacken. Warum verpacke ich es zusätzlich in ein LinearLayout?

    Die jüngste Erkenntnis:
    Man kann die Kinder eines Layouts über das Eltern-Layout ansprechen und dass ein Layout Vorder- und Hintergrund hat. Ebenso kann man den Layout an onClick setzen. Wozu dann überhautp ein ImageView? Ihr ahnt, wohin die Reise geht!

    Nun muss ich nur das LinearLayout-Würfel oben an Flaggen-Bar und in jedem anderen Fall an das Eltern-Layout kleben, zusehen, dass die Würfel(FrameLayout) im Eltern-Layout(LinearLayout-Würfel) an Ort und Stelle sitzen*, wo ich diese haben will und nun sieht mein Display so aus, siehe Bild (RelativeLayout_Surface_Blueprint_Final)

    Das Design steht, also ran an den Code. Welche Variationen habe ich?
    Ich habe eine Flaggen-Bar, die Flaggen unterscheiden sich in der Farbe und Ausrichtung der Flaggenbahnen, also bedarf es geeigneter Bedingungen, sprich horizontal- und vertikal verlaufende Flaggenbahnen. Dann müssen die Würfel ebenso in der Farbe gefärbt werden. Das letzte Mal lernte ich den Weg über die color.xml, nun soll dies genau so erfolgen. Also erstelle ich mir zusätzlich zu dem Hintergrund-Array ein Würfel-Array mit den Farben, in welche die Würfel bei jeweiligen Flaggenwahl passend gefärbt werden sollen und vergebe passenden Namen "dice_"
    Open (open)
    Code (Java):

    <string-array name="background_iw_flag_germany">
        <item>#2A292A</item>
        <item>#C1121C</item>
        <item>#EEC900</item>
    </string-array>
    <string-array name="dice_iw_flag_germany">
        <item>#C1121C</item>
        <item>#EEC900</item>
    </string-array>
     

    Nun zu Bedingungen. Wenn onClick aufgerufen wird, soll geprüft werden, ob es ein Flaggen-Icon war. Wenn dies zutrifft, dann soll der Hintergrund und die Würfel nach der Vorgabe gefärbt werden. Dies passiert in der Methode changeComponentColors. Hier erstelle ich als Erstes die Farb-Arrays für den jeweiligen Zweck. Nun prüfe ich, ob die Flagge vertikal- oder horizontal verlaufende Flaggenbahnen hat. Je nach dem, drehe ich mit setOrientation die Ausrichtung des Hintergrundes und färbe es in Landesfarben ein. Anschliessend färbe ich die Würfel ebenso in Farben, welche ich mir für die jeweilige Flagge ausgesucht habe, ein. Als letztes bringe ich die Flaggen-Bar und die Würfel nach vorn, damit diese nicht vom Hintergrund verdeckt werden.
    Was hier die Sache so einfach macht ist, dass ich mir keine Gedanken machen muss, an welcher Stelle welches Kind sitzt. Ich färbe diese der Reihe nach mit zuvor festgelegten Farben nach festgelegten Muster. Auch über die Teilung muss ich mir keine Gedanken machen, da die Farbstreifen sich den Platz im Eltern-Layout gerecht untereinander teilen. Super bequem!

    Wichtig ist dabei nur eins: in onCreate füllte ich das LinearLayout Würfel, bzw. die Kinder von, mit Standardbilder dice_one und dice_two und diese hinterlegte ich im Vordergrund. Also darf hier dieser nicht überschrieben werden, sonst sieht man keine Würfel mehr.

    Weiter in onClick entschied ich mich, den jeweiligen Würfel von Hand einzugeben, weil hier nur zwei Würfel geben kann und es mir übersichtlicher erschien, als es weiter auszutüfteln und weitere Methoden zu erstellen. An der Vorgehensweise ändert sich dabei nichts.

    Nun die mögliche Erweiterung. Dafür braucht es nur wenige Schritte. Da der diesjährige Gastgeber einer Sportart, welche Milliarden Menschen weltweit verbindet, hier nicht fehlen darf, entscheide ich mich, diesen hinzufügen: Russland.
    Schritt für Schritt:
    • activity_main.xmlFlaggen-Bar bekommt ein neuen Eintrag
    • color.xml bekommt zwei neue Einträge für Hinter- und Würfelgrund
    • vertical_flags oder horizontal_flags bekommt ein zuvor initialisiertes ImageView hinzugewiesen.
    fertig! siehe Bild (Simulator_Startbild_Erweitertes Design_Final)

    Eins bleibt aber noch: an Ort und Stelle sitzen*
    Man kann das Layout mithilfe von XML wesentlich besser gestalten. Im Augenblich sind meine Kenntnisse darüber noch rudimentär, so dass die Frase so verstanden werden soll, dass es für mich und mein Smartphone hier und jetzt funktioniert.

    Nun steht einer weiteren Runde Monopoly nichts mehr im Wege! Erfühlt mit Stolz und leicht in mich hinein grinzend werde ich dies jetzt tun. Mal sehen, welche Ideen mir dabei kommen oder von Forumsteilnehmer eingebracht werden, um die App oder den Code weiter zu optimieren :)

    Nun der aktuelle Code:
    MainActivity (open)
    Code (Java):

    import android.app.Activity;
    import android.content.res.Resources;
    import android.graphics.Color;
    import android.graphics.drawable.Drawable;
    import android.media.MediaPlayer;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import java.util.HashSet;
    import java.util.Set;
    public class MainActivity extends Activity implements ImageView.OnClickListener
    {
        private final String MSG_TAG = "MainActivity";
        /**
         * if LOGGING is true, you can follow the app in the Logcat.
         * Choose for this "error" as type and "show only selected application" to see it only.
         */

        private final boolean LOGGING = true;
        /**
         * All sides of a standard dice, starting by Nr: 1 and ending by Nr: 6
         */

        private final int[] side_of_dice =
                {R.drawable.dice_one, R.drawable.dice_two, R.drawable.dice_three, R.drawable.dice_four, R.drawable.dice_five, R.drawable.dice_six};
        /**
         * Layout, who contains the background. For now only three stripes Flags are supported
         */

        private LinearLayout layout_background;
        /**
         * Layout, who contains all supported Flags
         */

        private LinearLayout layout_flag_bar;
        /**
         * Layout, who contains all the dices
         */

        private LinearLayout layout_parent_dices;
        /**
         * it contains all Flags, who has a vertical Orientation of stripes
         */

        private Set<ImageView> vertical_flags = new HashSet<>();
        /**
         * it contains all Flags, who has a horizontal Orientation of stripes
         */

        private Set<ImageView> horizontal_flags = new HashSet<>();
        /**
         * Media Player only for sound of rolling dice
         */

        private MediaPlayer soundForDice;
        /**
         * Media Player only for sound of doublet
         */

        private MediaPlayer soundForDoublet;
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            getInfoLog("onCreate");
            ImageView germany = prepareImageView(R.id.iw_flag_germany);
            ImageView italy = prepareImageView(R.id.iw_flag_italy);
            ImageView france = prepareImageView(R.id.iw_flag_france);
            ImageView russia = prepareImageView(R.id.iw_flag_russia);
            ImageView yy = prepareImageView(R.id.iw_flag_yy);
            vertical_flags.add(italy);
            vertical_flags.add(france);
            vertical_flags.add(yy);
            horizontal_flags.add(germany);
            horizontal_flags.add(russia);
            layout_background = findViewById(R.id.layout_background);
            layout_flag_bar = findViewById(R.id.layout_flag_bar);
            layout_parent_dices = fillDices(R.id.layout_parent_dices);
            soundForDice = MediaPlayer.create(this, R.raw.roll_the_dice);
            soundForDoublet = MediaPlayer.create(this, R.raw.beep_once);
        }
        /**
         * There could be a lot of variety of clicked views.
         * Because you will put more Flags on {@code layout_flag_bar} the are a special condition for
         * this case, witch calls {@code changeComponentColors} to change the background and color of
         * dices.
         *
         * @param clickedView clicked view
         */

        @Override
        public void onClick(View clickedView)
        {
            getInfoLog("onClick()");
            if (clickedFlagID(clickedView.getId()))
            {
                for (int x = 0; x < layout_flag_bar.getChildCount(); x++)
                {
                    if (clickedView.getId() == layout_flag_bar.getChildAt(x).getId())
                    {
                        changeComponentColors(layout_flag_bar.getChildAt(x).getId());
                        return;
                    }
                }
            } else if (clickedView.getId() == layout_parent_dices.getChildAt(0).getId())
            {
                int first = rollTheDice();
                soundForDice();
                layout_parent_dices.getChildAt(0).setForeground(getForegroundDrawable(first));
            } else if (clickedView.getId() == layout_parent_dices.getChildAt(1).getId())
            {
                int first = rollTheDice();
                int second = rollTheDice();
                soundForDice();
                layout_parent_dices.getChildAt(0).setForeground(getForegroundDrawable(first));
                soundForDice();
                layout_parent_dices.getChildAt(1).setForeground(getForegroundDrawable(second));
                soundForDoublet(first, second);
            }
        }
        /**
         * check, if the clicked view contains by {@code layout_flag_bar}
         *
         * @param id clicked view
         * @return true, if {@code layout_flag_bar} contains clicked view
         */

        private boolean clickedFlagID(int id)
        {
            getInfoLog("clickedFlagID()");
            for (int x = 0; x < layout_flag_bar.getChildCount(); x++)
            {
                if (layout_flag_bar.getChildAt(x).getId() == id)
                {
                    return true;
                }
            }
            return false;
        }
        /**
         * Here the background will be changed by {@code id}
         * There are two things, they can be change: background color and layout orientation
         * (horizontal or vertical stripes of flags)
         * Also dices will be colored here.
         * Note: {@code fill} true for background color, false for dice color.
         *
         * @param id clicked ImageView
         */

        private void changeComponentColors(int id)
        {
            getInfoLog("changeComponentColors()");
            final String[] backgroundColors = fill(id, true);
            final String[] diceColors = fill(id, false);
            ImageView imageView = findViewById(id);
            if (vertical_flags.contains(imageView))
            {
                layout_background.setOrientation(LinearLayout.HORIZONTAL);
                for (int x = 0; x < backgroundColors.length; x++)
                {
                    layout_background.getChildAt(x).setBackgroundColor(Color.parseColor(backgroundColors[x]));
                }
            } else if (horizontal_flags.contains(imageView))
            {
                layout_background.setOrientation(LinearLayout.VERTICAL);
                for (int x = 0; x < layout_background.getChildCount(); x++)
                {
                    layout_background.getChildAt(x).setBackgroundColor(Color.parseColor(backgroundColors[x]));
                }
            }
            for (int y = 0; y < diceColors.length; y++)
            {
                layout_parent_dices.getChildAt(y).setBackgroundColor(Color.parseColor(diceColors[y]));
            }
            layout_flag_bar.bringToFront();
            layout_parent_dices.bringToFront();
        }
        /**
         * fill a color array with set of matching colors by {@code id} and {@code switcher}
         *
         * @param id       clicked view
         * @param switcher background or dices
         * @return filled color array
         */

        private String[] fill(int id, boolean switcher)
        {
            getInfoLog("fill()");
            final String resourceName = getResources().getResourceEntryName(id);
            final int colorArrayID;
            final String[] colors;
            if (switcher)
            {
                colorArrayID = getResources().getIdentifier("background_" + resourceName, "array", getPackageName());
                colors = getResources().getStringArray(colorArrayID);
            } else
            {
                colorArrayID = getResources().getIdentifier("dice_" + resourceName, "array", getPackageName());
                colors = getResources().getStringArray(colorArrayID);
            }
            return colors;
        }
        /**
         * every time, if the eyes of both dices have the same value, {@code mediaPlayerDoubletSound} will play a sound
         *
         * @param first  eyes of first dice
         * @param second eyes of second dice
         */

        private void soundForDoublet(int first, int second)
        {
            getInfoLog("soundForDoublet()");
            if (first == second)
            {
                getInfoLog("soundForDoublet", "doublet");
                soundForDoublet.seekTo(0);
                soundForDoublet.start();
            }
        }
        /**
         * general sound for rolling dice
         */

        private void soundForDice()
        {
            getInfoLog("soundForDice()");
            soundForDice.seekTo(0);
            soundForDice.start();
        }
        /**
         * if the app is on background, both MediaPlayers will be release.
         */

        @Override
        protected void onStop()
        {
            super.onStop();
            getInfoLog("onStop()");
            soundForDice.release();
            soundForDoublet.release();
        }
        /**
         * return a random number of {@code side_of_dice} witch will be displayed next.
         *
         * @return random number to display next
         */

        private int rollTheDice()
        {
            getInfoLog("rollTheDice()");
            return (int) (Math.random() * side_of_dice.length);
        }
        private ImageView prepareImageView(int id)
        {
            getInfoLog("prepareImageView()");
            ImageView imageView = findViewById(id);
            imageView.setOnClickListener(this);
            return imageView;
        }
        /**
         * Initialize {@code layout_parent_dices}, also his children will get the standard ImageView,
         * witch you can see on the start display of the App.
         * Note: you should set the ImageView always to foreground, because background will be used by
         * color!
         *
         * @param id id of layout who should be initialized
         * @return initialized {@code layout_parent_dices}
         */

        private LinearLayout fillDices(int id)
        {
            getInfoLog("fillDices()");
            LinearLayout linearLayout = findViewById(id);
            for (int x = 0; x < linearLayout.getChildCount(); x++)
            {
                linearLayout.getChildAt(x).setForeground(getForegroundDrawable(x));
                linearLayout.getChildAt(x).setOnClickListener(this);
            }
            return linearLayout;
        }
        /**
         * Put a random value of {@code side_of_dice} out and deliver it to the caller or
         * standard value to display it on the start display of the App, for more {@code fillDices(int id)}
         *
         * @param value random or standard number
         * @return contained ImageView by {@code side_of_dice} on place {@code value}
         */

        private Drawable getForegroundDrawable(int value)
        {
            getInfoLog("getForegroundDrawable()");
            Resources res = getResources();
            return res.getDrawable(side_of_dice[value], null);
        }
        /**
         * here you can follow the code of the app, if {@code LOGGING} is true
         * place it at the beginning of method
         *
         * @param method method you will see in Logger
         */

        private void getInfoLog(String method)
        {
            if (LOGGING)
            {
                Log.e(MSG_TAG, method);
            }
        }
        /**
         * here you can follow the code of the app, if {@code LOGGING} is true
         * place it into a step of a method, so you can see the method and step
         * in Logger
         *
         * @param method method you will see in Logger
         * @param place  place in {@code method} you will see in Logger
         */

        private void getInfoLog(String method, String place)
        {
            if (LOGGING)
            {
                Log.e(MSG_TAG, method.concat(", ").concat(place));
            }
        }
    }
     

    activity_main.xml (open)
    Code (Java):

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/layout_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/chrysler_white"
        android:baselineAligned="false"
        android:orientation="vertical"
        tools:context=".MainActivity">
        <LinearLayout
            android:id="@+id/layout_flag_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true"
            android:orientation="horizontal"
            android:padding="@dimen/icon_padding">
            <ImageView
                android:id="@+id/iw_flag_germany"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:src="@drawable/germany" />
            <ImageView
                android:id="@+id/iw_flag_italy"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:src="@drawable/italy" />
            <ImageView
                android:id="@+id/iw_flag_france"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:src="@drawable/france" />
            <ImageView
                android:id="@+id/iw_flag_russia"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:src="@drawable/russia" />
            <ImageView
                android:id="@+id/iw_flag_yy"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:src="@drawable/ying_yang" />
        </LinearLayout>
        <LinearLayout
            android:id="@+id/layout_parent_dices"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentBottom="true"
            android:layout_alignParentEnd="true"
            android:layout_alignParentStart="true"
            android:layout_below="@+id/layout_flag_bar"
            android:orientation="vertical">
            <FrameLayout
                android:id="@+id/layout_first_dice"
                android:layout_width="@dimen/icon_side_length"
                android:layout_height="@dimen/icon_side_length"
                android:layout_gravity="center_horizontal"
                android:layout_marginBottom="@dimen/icon_distance_to_each"
                android:layout_marginTop="@dimen/icon_distance_to_edge"
                android:orientation="vertical">
            </FrameLayout>
            <FrameLayout
                android:id="@+id/layout_second_dice"
                android:layout_width="@dimen/icon_side_length"
                android:layout_height="@dimen/icon_side_length"
                android:layout_gravity="center_horizontal"
                android:layout_marginBottom="@dimen/icon_distance_to_edge"
                android:layout_marginTop="@dimen/icon_distance_to_each"
                android:orientation="vertical">
            </FrameLayout>
        </LinearLayout>
        <LinearLayout
            android:id="@+id/layout_background"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentBottom="true"
            android:layout_alignParentEnd="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true"
            android:baselineAligned="false"
            android:orientation="horizontal">
            <LinearLayout
                android:id="@+id/layout_background_first"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:orientation="vertical">
            </LinearLayout>
            <LinearLayout
                android:id="@+id/layout_background_second"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:orientation="vertical">
            </LinearLayout>
            <LinearLayout
                android:id="@+id/layout_background_third"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:orientation="vertical">
            </LinearLayout>
        </LinearLayout>
    </RelativeLayout>
     

    color.xml (open)
    Code (Java):

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string-array name="background_iw_flag_france">
            <item>#0055A4</item>
            <item>#FFFFFF</item>
            <item>#EF4531</item>
        </string-array>
        <string-array name="background_iw_flag_italy">
            <item>#008763</item>
            <item>#FFFFFF</item>
            <item>#FF3300</item>
        </string-array>
        <string-array name="background_iw_flag_germany">
            <item>#2A292A</item>
            <item>#C1121C</item>
            <item>#EEC900</item>
        </string-array>
        <string-array name="background_iw_flag_russia">
            <item>#FFFFFF</item>
            <item>#0039A6</item>
            <item>#D52B1E</item>
        </string-array>
        <string-array name="background_iw_flag_yy">
            <item>#F0F0F0</item>
            <item>#F0F0F0</item>
            <item>#F0F0F0</item>
        </string-array>
        <string-array name="dice_iw_flag_germany">
            <item>#C1121C</item>
            <item>#EEC900</item>
        </string-array>
        <string-array name="dice_iw_flag_italy">
            <item>#008763</item>
            <item>#FF3300</item>
        </string-array>
        <string-array name="dice_iw_flag_france">
            <item>#0055A4</item>
            <item>#EF4531</item>
        </string-array>
        <string-array name="dice_iw_flag_russia">
            <item>#0039A6</item>
            <item>#D52B1E</item>
        </string-array>
        <string-array name="dice_iw_flag_yy">
            <item>#F0F0F0</item>
            <item>#F0F0F0</item>
        </string-array>
        <color name="white">#FFFFFF</color>
        <color name="italian_red">#FF3300</color>
        <color name="italian_green">#176153</color>
        <color name="france_blue">#0055A4</color>
        <color name="france_red">#EF4531</color>
        <color name="german_red">#C1121C</color>
        <color name="german_gold">#EEC900</color>
        <color name="german_black">#2A292A</color>
        <color name="chrysler_white">#F0F0F0</color>
        <color name="russian_blue">#0039A6</color>
        <color name="russian_red">#D52B1E</color>
    </resources>
     
     

    Anhänge:

    Zuletzt von einem Moderator bearbeitet: 6. Mai 2018
  9. T_T
    T_T Mitglied
    @Javinner Du kommentierst verdammt viel. Es ist ziemlich anstrengend deinen Code zu lesen.

    http://apdevblog.com/comments-in-code/
     
  10. mrBrown
    mrBrown Super-Moderator Mitarbeiter
    Das Logging würde ich btw auch anders lösen, und gänzlich auf den LOGGING_Flag verzichten.

    Log selbst bietet dafür genug Möglichkeiten: einmal das Log-Level (was du aktuell im wesentlichen ignorierst, bei dir ist alles ein Error) und den Tag (üblicherweise der volle Klassenname), damit kann man Logs ziemlich gut filtern, und muss sich nicht Applikationsseitig noch zusätzlich drum kümmern.
     
  11. Hinweis: Du möchtest Java lernen? Vielleicht hilft dir dieser Kurs hier weiter. Sichere dir hier den Zugriff auf umfangreiches Java-Know How und starte richtig durch!
Die Seite wird geladen...

Android-Apps: Krims-Krams für den Hausgebrauch - Ähnliche Themen

Android-Apps entwickeln für Einsteiger, Auflage Nr.7, Ausgabe 2018 mit Android Studio 3
Android-Apps entwickeln für Einsteiger, Auflage Nr.7, Ausgabe 2018 mit Android Studio 3 im Forum Bücher, Tutorials und Links
Voraussetzungen für Android-Apps
Voraussetzungen für Android-Apps im Forum Mobile Geräte
Thema: Android-Apps: Krims-Krams für den Hausgebrauch