1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

Simples 2-Spalten-Layout: Wie geht das?

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von Schranz0r_23, 05.04.2011.

  1. Schranz0r_23, 05.04.2011 #1
    Schranz0r_23

    Schranz0r_23 Threadstarter Neuer Benutzer

    Beiträge:
    14
    Erhaltene Danke:
    0
    Registriert seit:
    20.12.2010
    Mahlzeit die Damen und die Herren da draußen!

    Ich brauch für eine kleine Anwendung ein zwei Spalten Layout. In der linken Spalte die etwa 2/3 des Bildschirmes einnehmen soll, soll später eine Google-Maps-Karte eingebunden werden. Im rechten Bereich soll sich eine kleine Liste befinden.

    Die Liste bekommt die Daten über eine XML Schnittstelle die über HTTP erreichbar ist. Die Daten habe ich nach zwei Tagen endlich zum anzeigen in die Liste bekommen aber jetzt scheitere ich an dem Layout der Anwendung. Ich verstehe noch nicht wirklich das Zusammenspiel der XML-Dateien, die relativen und absoluten Layouts und und und.

    Was cool wäre, wenn mir jemand erklären könnte, wie meine main.xml auszusehen hat, damit ich das oben beschriebene erreichen kann.

    Nebenbei muss ich noch erwähnen, dass Java nach wie vor immer noch Neuland für mich ist. Wo ich z.B. überhaupt noch nicht mit klar komme sind diese ominösen Spitzen Klammern an Datentypen, Klassen. Dann kommen zwischendurch noch Klammern wie () dazu und dann die ganzen Casts...

    Quellcode anbei:

    Code:
    public class ApplicationMain extends ListActivity {
        
        private ArrayList<String> checkList = new ArrayList<String>();
        
        private static String getTagValue(final String sTag, final Element eElement){
            NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
            Node nValue = (Node) nlList.item(0); 
            return nValue.getNodeValue();    
        }
    
        @SuppressWarnings({ "rawtypes", "unchecked" })
        @Override
        public void onCreate(Bundle savedInstanceState) {
    
            Context context = getApplicationContext();
            try {
                
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                
                DocumentBuilder builder = factory.newDocumentBuilder();
                
                Document doc = builder.parse("xxxxxxxxxxx");
                
                doc.getDocumentElement().normalize();
                
                NodeList nList = doc.getElementsByTagName("contact");
    
                for(int temp=0; temp < nList.getLength(); temp++) {
    
                   Node nNode = nList.item(temp);
    
                   if(nNode.getNodeType() == Node.ELEMENT_NODE) {
    
                      Element eElement = (Element)nNode;
                      
                      String id = getTagValue("id",eElement);
                      String pre = getTagValue("pre",eElement);
                      String last = getTagValue("last",eElement);
                      checkList.add(pre + " " + last);
    
                    }
                }
                
                super.onCreate(savedInstanceState);
                
                setContentView(R.layout.main);
                
                ArrayAdapter adapter = new ArrayAdapter(context,R.layout.list_item,
                        checkList);
                
                setListAdapter(adapter);
                
                adapter.notifyDataSetChanged();
                
            } catch (Exception e) {
                CharSequence text = "XML Parsing Exception: " + e.getMessage();
                int duration = Toast.LENGTH_SHORT;
                Toast toast = Toast.makeText(context, text, duration);
                toast.show();
            }
        }
    
    }
    
    main.xml
    HTML:
    <?xml version="1.0" encoding="utf-8"?>
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="vertical"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         >
         <ListView  
             android:id="@android:id/list"
             android:layout_width="fill_parent" 
             android:layout_height="wrap_content" 
             />
         <TextView android:id="@android:id/empty"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:text="Empty set"
             />
     </LinearLayout>
    
     
  2. v Ralle v, 05.04.2011 #2
    v Ralle v

    v Ralle v Android-Lexikon

    Beiträge:
    913
    Erhaltene Danke:
    199
    Registriert seit:
    27.08.2010
    Hallo,

    ich möchte dir nicht die Lösung geben, nur ein paar Tips.

    Wenn du es wirklich ganz simpel haben willst, reicht dir ein Linearlayout aus. Da kannst du einfach die Orientation auf vertikal stellen und anschließend fügst du nur zwei Kinder ein. Bei den Kindern stellst du als layout_width "fill_parent" ein. Und jetzt kommt der coole Teil: dort kannst du ein Wert für "weight" angeben. Dieser liegt zwischen 0 und 1 und die Summe des Weights aller Kinder muss 1 ergeben. So kannst du ganz einfach dein 2/3 Verhältnis einstellen.

    Wirklich professionell würde man dein Vorhaben aber mit Fragments umsetzen. Vielleicht hilft dir der Link da besser: Fragments | Android Developers

    Was ich aber immer wieder klasse finde, wenn Leute von Java fast nichts verstehen und denken "jetzt programmiere ich mal ne App". So einfach ist das dann nun doch nicht ;) Du solltest dir vielleicht erstmal die Grundlagen ansehen und verstehen. Dafür gibt es genug Tutorials im Internet. Wenn du dich sogar wunderst, wenn auf einmal solche Klammern () hin müssen, dann hast du ja noch nicht mal die Syntax verinnerlicht. Das gibt mir zu denken übrig.

    Und zum Abschluss. Die ominösen eckigen Klammern nennt man Generics ;)
     
  3. Schranz0r_23, 05.04.2011 #3
    Schranz0r_23

    Schranz0r_23 Threadstarter Neuer Benutzer

    Beiträge:
    14
    Erhaltene Danke:
    0
    Registriert seit:
    20.12.2010
    Ah vielen vielen Dank. Die Fragments schau ich mir direkt morgen an, da ich hier Zuhause keine funktionierende IDE habe. Ich programmiere nämlich idr. nicht in Java. Also nicht falsch verstehen. Vom programmieren hab ich ne menge Ahnung, nur halt nicht von Java. Daher ist die Syntax auch sehr ungewohnt. Hab jetzt fast 8 Jahre nur Web Programmierung gemacht. Was ich auch sehr ungewohnt finde, dass man hier den Dereferenzierungsoperator nicht anwendet... egal egal, mit Deinen Sachen haste mir schon geholfen.

    Edit:
    Wenn wir schon mal dabei sind.. Wie kann ich diese Zeile lesen? Darum ging es mir nämlich, der Rest ist simples OOP.

    private ArrayList<String> checkList = new ArrayList<String>();
     
  4. v Ralle v, 05.04.2011 #4
    v Ralle v

    v Ralle v Android-Lexikon

    Beiträge:
    913
    Erhaltene Danke:
    199
    Registriert seit:
    27.08.2010
    Eine ArrayListe erkläre ich jetzt nicht. Das Konzept sollte klar sein. Zu den Generics: Die Liste muss wissen, was für Objekte sie beinhaltet. Das macht alles beim Programmieren einfach, zB. beim Iterieren über die Liste. Das Schlagwort ist hier auch Typsicherheit. Die Liste soll beispielsweise nicht ein String, Integer, etc. Objekt enthalten.

    Du kannst den Aufruf also eine ArrayListe von Strings verstehen. Stell dir das mit den eckigen Klammern einfach so vor, dass die Klasse ArrayList konkretisiert wird.

    Das new ArrayList<String>(); sieht anfangs vielleicht komisch aus, macht aber sehr viel Sinn. Einfach der Vergleich:

    new ArrayList<String>();
    new Object();

    ArrayList wird halt nur konkretisiert, das halt Syntax die man so hinnehmen muss. Für den Rest bitte googlen ;)

    Edit: schau auch mal bei der Insel vorbei http://openbook.galileocomputing.de...07_001.htm#mjc4a1f6f3499a02fb64fe89046739edca
     
    Schranz0r_23 bedankt sich.
  5. Fr4gg0r, 06.04.2011 #5
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    Fragments sind doch für Tablets gedacht und was stört dich an der Lösung mit dem LinearLayout?
    Als orientation meinst du wohl horizontal ;) welches der default wert ist.
     
  6. v Ralle v, 06.04.2011 #6
    v Ralle v

    v Ralle v Android-Lexikon

    Beiträge:
    913
    Erhaltene Danke:
    199
    Registriert seit:
    27.08.2010
    Nichts stört mich daran, sonst hätte ich es ja nicht erklärt :) Jep, dann mein ich halt horinzontal ;) Ich komm da immer wieder durcheinander. Bedeutet horizontal nicht parallel zum Horizont?! Ich gehe immer von der Trennlinie der Kinder, dass die parallel, ist aber genau anders rum, daher verwechsle ich das immer :D Komische Denkblockade.
     
  7. Schranz0r_23, 07.04.2011 #7
    Schranz0r_23

    Schranz0r_23 Threadstarter Neuer Benutzer

    Beiträge:
    14
    Erhaltene Danke:
    0
    Registriert seit:
    20.12.2010
    Moin!

    Danke erstmal für die Hilfe hier.

    Habe nun meine main.xml so wie ich das gerne hätte:
    HTML:
    <?xml version="1.0" encoding="utf-8"?>
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="horizontal"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         >
         <ListView  
             android:id="@+id/customer_list_view"
             android:layout_width="350px"
             android:layout_height="wrap_content"
             android:layout_weight="0"
             />
         <TextView android:id="@+id/customer_text_view"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="Kein Kunde gewählt"
             android:layout_weight="1"
             />
     </LinearLayout> 
    
    Die Fragments hätte ich gerne genutzt. Leider hat mein Eclipse gesagt, er könne die jeweiligen Basisklassen der Fragmente nicht finden. Liegt es eventuell daran, dass ich als Project Build Target Google APIs, P.:2.2, L:8 verwende? Ist auch halb so wild jetzt, da ja mein Layout so ausschaut wie ich das gerne hätte.

    Nun bin ich allerdings an einer neuen Android Baustelle.. Wie schon erwähnt, hätte ich im ersten Step im linken Bereich des Layouts gerne eine Liste mit Kunden.

    Dazu habe ich mir eine Klasse namens CustomerListView angelegt die von der Klasse ListActivity erbt. Jetzt verstehe ich nicht so recht, wie ich die Daten dieser ListActivity in meine Liste reinbekomme, die in der main.xml definiert wurde (customer_list_view). Also wo an welcher Stelle (Ich vermute mal in der MainActivity), muss ich dem Kollegen sagen, dass er die Daten aus der CustomerActivity in die customer_list_view schreibt.

    Danke

    CustomerListView
    Code:
    package com.packages;
    
    import java.util.ArrayList;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    import android.app.ListActivity;
    import android.content.Context;
    import android.os.Bundle;
    
    import android.widget.ArrayAdapter;
    import android.widget.Toast;
    
    public class CustomerActivity extends ListActivity {
        
        private ArrayList<String> customerList = new ArrayList<String>();
        
        private static String getTagValue(final String sTag, final Element eElement){
            NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
            Node nValue = (Node) nlList.item(0); 
            return nValue.getNodeValue();    
        }
    
        @SuppressWarnings({ "rawtypes", "unchecked" })
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            Context context = getApplicationContext();
            
            try {
                
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document doc = builder.parse("xxxxxxx");
                doc.getDocumentElement().normalize();
                
                NodeList nList = doc.getElementsByTagName("contact");
    
                for(int temp=0; temp < nList.getLength(); temp++) {
                   Node nNode = nList.item(temp);
                   if(nNode.getNodeType() == Node.ELEMENT_NODE) {
                      Element eElement = (Element)nNode;
                      String id = getTagValue("id",eElement);
                      String pre = getTagValue("pre",eElement);
                      String last = getTagValue("last",eElement);
                      customerList.add(pre + " " + last);
                    }
                }
                
                setContentView(R.layout.main);
                
                ArrayAdapter adapter = new ArrayAdapter(context,
                                                        android.R.layout.simple_list_item_1,
                                                        customerList);
                setListAdapter(adapter);
                adapter.notifyDataSetChanged();
                
            } catch (Exception e) {
                CharSequence text = "XML Parsing Exception: " + e.getMessage();
                int duration = Toast.LENGTH_SHORT;
                Toast toast = Toast.makeText(context, text, duration);
                toast.show();
            }
        }
    
    }
    
    MainActivity
    Code:
    public class Main extends Activity {
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            
            Context context = getApplicationContext();
    
    
            /*
            ProgressDialog dialog = ProgressDialog.show(Main.this,
                    "", 
                    "Loading. Please wait...",
                    true);
            */
            try {
                
            } catch (Exception e) {
                CharSequence msg = "Fehler: " + e.getMessage();
                ToastMessage.create(msg, context);
            }
            
            
        }
        
    }
    
    Der Vollständigkeit halber, die ToastMessage-Klasse anbei:
    Code:
    public class ToastMessage {
        
        static public void create(CharSequence msg, Context context) {
            CharSequence text = msg;
            int duration = Toast.LENGTH_SHORT;
            Toast toast = Toast.makeText(context, text, duration);
            toast.show();
        }
    
    }
    
     
  8. Fr4gg0r, 07.04.2011 #8
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    mMn solltest du eine Klasse erstellen, die von Adapter oder ListView erbt statt von Activity. Du erstellst ja auch keine 3. Activity für das TextView. ;)

    Wenn du von ListView erbst, müsstest du das xml entsprechend anpassen:
    statt ListView
    de.2spaltenlayout.MyListView
    oder du erbst von Adapter (in deinem Fall ArayAdapter), baust da deine Liste auf, und kannst dann wie gehabt in der MainActivity
    ListView lv = findViewById(R.id.customer_list_view);
    lv.setAdapter(new MyArrayAdapter());
    das anzeigen lassen.

    Ansonsten könntest du auch alles was du in CustomerActiviy hast, auch in die MainActivity verlegen ;).
    Je nachdem wie dus gern hättest.
     
    Schranz0r_23 bedankt sich.
  9. Schranz0r_23, 07.04.2011 #9
    Schranz0r_23

    Schranz0r_23 Threadstarter Neuer Benutzer

    Beiträge:
    14
    Erhaltene Danke:
    0
    Registriert seit:
    20.12.2010
    Sorry, aber da komme ich noch nicht so ganz mit. Haste eventuell Links in Petto? Ich weis nämlich noch nicht so ganz ausm Kopf wie ich meine Klasse komplett anpassen muss, sobald ich von einer anderen Erbe. Wenn ich z.B. von extends ListActivity nach ListView wechsel, dann schaut der Konstruktur und die onCreate..Methode ja anders aus.

    Danke
     
  10. Schranz0r_23, 08.04.2011 #10
    Schranz0r_23

    Schranz0r_23 Threadstarter Neuer Benutzer

    Beiträge:
    14
    Erhaltene Danke:
    0
    Registriert seit:
    20.12.2010
    HA. Ich hab et mir ma einfach gemacht und Teile aus dem ContactManager aus der Doku einfach gemopst.

    So find ich den Code schomma ganz gut:

    Code:
    package com.packages;
    
    import android.app.Activity;
    import android.content.Context;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.ContactsContract;
    import android.view.View;
    import android.widget.Button;
    import android.widget.CheckBox;
    import android.widget.CompoundButton;
    import android.widget.CompoundButton.OnCheckedChangeListener;
    import android.widget.ListView;
    import android.widget.SimpleCursorAdapter;
    
    public class Main extends Activity {
    
        public static final String TAG = "Kontakt Manager";
    
        private Button mAddAccountButton;
        private ListView mContactList;
        private boolean mShowInvisible;
        private CheckBox mShowInvisibleControl;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.contact_manager);
            
            Context context = getApplicationContext();
            
            /*
            ProgressDialog dialog = ProgressDialog.show(Main.this,
                    "", 
                    "Loading. Please wait...",
                    true);
            */
            try {
                mContactList = (ListView) findViewById(R.id.contactList);
                
                // Initialize class properties
                //mShowInvisible = false;
                //mShowInvisibleControl.setChecked(mShowInvisible);
                
                // Register handler for UI elements
                //mAddAccountButton.setOnClickListener(new View.OnClickListener() {
                //    public void onClick(View v) {
                //    }
                //});
                
                //mShowInvisibleControl.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                //    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                //        mShowInvisible = isChecked;
                //        //populateContactList();
                //    }
                //});
                
                populateContactList();
                
            } catch (Exception e) {
                CharSequence msg = "Fehler: " + e.getMessage();
                ToastMessage.create(msg, context);
            }
        }
        
        private void populateContactList() {
            // Build adapter with contact entries
            Cursor cursor = getContacts();
            String[] fields = new String[] {
                    ContactsContract.Data.DISPLAY_NAME
            };
            SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.contact_entry, cursor,
                    fields, new int[] {R.id.contactEntryText});
            mContactList.setAdapter(adapter);
        }
        
        private Cursor getContacts() {
            // Run query
            Uri uri = ContactsContract.Contacts.CONTENT_URI;
            String[] projection = new String[] {
                    ContactsContract.Contacts._ID,
                    ContactsContract.Contacts.DISPLAY_NAME
            };
            String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" +
                    (mShowInvisible ? "0" : "1") + "'";
            String[] selectionArgs = null;
            String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
    
            return managedQuery(uri, projection, selection, selectionArgs, sortOrder);
        }
        
    }
    
    Nun muss ich allerdings die Methode getContacts modifizieren, dass dort nicht auf die interne Kontaktliste zurückgegriffen wird, sondern eben auf die XML-Struktur.

    Dazu habe ich ja noch folgenden funktionierenden Code:
    Code:
    
    
            Context context = getApplicationContext();
            
            try {
                
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document doc = builder.parse("http://xxxx");
                doc.getDocumentElement().normalize();
                
                NodeList nList = doc.getElementsByTagName("contact");
    
                for(int temp=0; temp < nList.getLength(); temp++) {
                   Node nNode = nList.item(temp);
                   if(nNode.getNodeType() == Node.ELEMENT_NODE) {
                      Element eElement = (Element)nNode;
                      String id = getTagValue("id",eElement);
                      String pre = getTagValue("pre",eElement);
                      String last = getTagValue("last",eElement);
                      customerList.add(pre + " " + last);
                    }
                }
                
                setContentView(R.layout.main);
                
                ArrayAdapter adapter = new ArrayAdapter(context,
                                                        android.R.layout.simple_list_item_1,
                                                        customerList);
                setListAdapter(adapter);
                adapter.notifyDataSetChanged();
                
            } catch (Exception e) {
                CharSequence text = "XML Parsing Exception: " + e.getMessage();
                int duration = Toast.LENGTH_SHORT;
                Toast toast = Toast.makeText(context, text, duration);
                toast.show();
            }
    
    Tja und jetzt weis ich auch nicht mehr weiter... Denn ich habe folgendes Verständnisproblem:

    Die Daten aus dem XML-Doc speichere ich in einer ArrayList<String>.
    private ArrayList<String> customerList = new ArrayList<String>();

    Der ContactManager speichert die Kontakte allerdings so:
    private ListView mContactList;

    bzw. wird dort ein SimpleCursorAdapter injiziert
    mContactList.setAdapter(adapter);

    Ich muss es also irgendwie hinbekommen, dass ich eine Methode getXMLContacts habe, die mir die Daten so zurückliefert:

    return managedQuery(uri, projection, selection, selectionArgs, sortOrder);
     

Diese Seite empfehlen