UI-Komponente: Editierbarer Baum anhand eine SQL Lite Datenstruktur

  • Antworten:3
Björn Karpenstein
  • Forum-Beiträge: 26

27.05.2014, 23:31:06 via Website

Hallo liebe Entwickler!

eine Tabelle, die in als Baum dargestellt werden soll, erhält die Daten von einer SQLLite Datenbank der folgenden Struktur;

Tabelle productgroup (beliebige Tiefe)

id (Autoincrement)
parent_row_id (Parent ID hier hat die Produktgruppe untergruppen
title (Der Titel der im Baum als Schriftelement gezeigt wird)
description (Eine Langtextbeschreibung)
rabatt (Gibt an ob Rabatte auf die Produktgruppe gegeben werden)
...
image

Meine Frage:
Welche Datenstruktur und welche UI Komponente eignet sich hierfür? Der Baum soll editierbar und verschiebbar sein.
Ich suche eine gute Möglichkeit einen Baum mit einer Android UI Kompoenente anhand der gezeigten Tabellenstruktur (-1 ist die erste Ebene den Rest könnte man rekursiv anhand von parent_row_id aufbauen.

Ich wurde in Foren bereits auf auf ExpandableListAdapter hingewiesen und auch schon ein starres Konstrukt, welches die erste Ebene anhand einer "HashMap<String, ArrayList<WarengruppenVO>> childrenByParentID;" generiert.

Ist die gewählte Methode (s.u.) gut? Ich habe das Problem das beim SecondLevelAdapter an der STelle, getGroupView, wo der SecondLevelAdapter instanziert wird, ein Hochzählen der Positionen schwierig ist. Ich bräuchte allerdings einen laufenden Index um die Kinder der zweiten Ebene anzuzeigen.

Mir wäre es am Liebsten wenn der Baum theoretisch unendelich tief sein könnte. Wie geht ihr bei sowas vor?

package com.caprisoft.cashdroiddesk.ui.fragment;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Fragment;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.TextView;

import com.caprisoft.cashdroiddesk.MainActivity;
import com.caprisoft.cashdroiddesk.R;
import com.caprisoft.cashdroiddesk.database.WarengruppenDBAdapter;
import com.caprisoft.cashdroiddesk.model.WarengruppenVO;

public class WarengruppenFragment extends Fragment{

    public static int arrayPosition = 0;

    public ArrayList&lt;WarengruppenVO&gt; warengruppenEbene1;
    public HashMap&lt;String, ArrayList&lt;WarengruppenVO&gt;&gt; childrenByParentID;

    public WarengruppenDBAdapter warengruppenDBAdapter;

    ExpandableListView explvlist;

    @Override
    public void onStart()
    {
        super.onStart();
        warengruppenDBAdapter=((MainActivity) getActivity()).warengruppenDBAdapter; 
        childrenByParentID = warengruppenDBAdapter.getAllProductGroupsAsHashMapByParentID();
        warengruppenEbene1 = childrenByParentID.get(&quot;-1&quot;);
        initControls();
    }   

    public void initControls()
    {
        explvlist = (ExpandableListView) getActivity().findViewById(R.id.ParentLevel);
        explvlist.setAdapter(new ParentLevel());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_warengruppen, container, false);
    }

    public class ParentLevel extends BaseExpandableListAdapter {

        @Override
        public Object getChild(int arg0, int arg1) {
               return arg1;
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
               return Integer.parseInt(warengruppenEbene1.get(groupPosition).get_id());
        }

        String warengruppenDatenbankID;

        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) 
        {

               // Diese Funktion wird jedesmal aufgerufen, wenn ein Parent auf Ebene 1 expandiert wird.
               // Daher hole ich hier die ID f&uuml;r jeden Eintrag um die Childs zu laden
               warengruppenDatenbankID =  ((WarengruppenVO) warengruppenEbene1.get(groupPosition)).get_id();

               // Diese Funktion wird jedesmal aufgerufen, wenn ein Parent expandiert wird.
               CustExpListview secondLevelexplv = new CustExpListview(getActivity());
               secondLevelexplv.setAdapter(new SecondLevelAdapter(warengruppenDatenbankID));
               secondLevelexplv.setGroupIndicator(null);
               return secondLevelexplv;
        }

        /** To Do: **/
        @Override
        public int getChildrenCount(int groupPosition) {
               return childrenByParentID.get(((WarengruppenVO) warengruppenEbene1.get(groupPosition)).get_id()).size();
        }

        @Override
        public Object getGroup(int groupPosition) {
               return warengruppenEbene1.get(groupPosition);
        }

        @Override
        public int getGroupCount() {
               return warengruppenEbene1.size();
        }

        @Override
        public long getGroupId(int groupPosition) {
               return Integer.parseInt(warengruppenEbene1.get(groupPosition).get_id());
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
               WarengruppenVO wgVO = warengruppenEbene1.get(groupPosition);

               TextView tv = new TextView(getActivity());
               tv.setText(wgVO.getParent_row_id()+ &quot; &quot;+wgVO.get_id()+&quot; &quot; +wgVO.getTitle() + &quot; &quot;+isExpanded);
               tv.setTextColor(Color.BLACK);
               tv.setTextSize(20);
               tv.setBackgroundColor(Color.BLUE);
               tv.setPadding(10, 7, 7, 7);

               return tv;
        }

        @Override
        public boolean hasStableIds() {
               return true;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
               return true;
        }
 }

    public class CustExpListview extends ExpandableListView {

            int intGroupPosition, intChildPosition, intGroupid;

            public CustExpListview(Context context) {
                   super(context);
            }

            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                   widthMeasureSpec = MeasureSpec.makeMeasureSpec(960, MeasureSpec.AT_MOST);
                   heightMeasureSpec = MeasureSpec.makeMeasureSpec(600, MeasureSpec.AT_MOST);
                   super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
     }

    public class SecondLevelAdapter extends BaseExpandableListAdapter {


        String parentId = &quot;-2&quot;;

        public SecondLevelAdapter(String parentID)
        {
            this.parentId=parentID;
        }

        @Override
        public Object getChild(int groupPosition, int childPosition) {
               return childPosition;
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
               return childPosition;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {

               TextView tv = new TextView(getActivity());
               tv.setText(&quot;child&quot; + groupPosition + &quot; &quot; + childPosition + &quot; &quot;+isLastChild);
               tv.setTextColor(Color.BLACK);
               tv.setTextSize(20);
               tv.setPadding(15, 5, 5, 5);
               tv.setBackgroundColor(Color.YELLOW);
              // tv.setLayoutParams(new ListView.LayoutParams(Li, LayoutParams.FILL_PARENT));

               return tv;
        }

        @Override
        public int getChildrenCount(int groupPosition) {
               return childrenByParentID.get(((WarengruppenVO) warengruppenEbene1.get(groupPosition)).get_id()).size();
        }

        @Override
        public Object getGroup(int groupPosition) {
               return groupPosition;
        }

        @Override
        public int getGroupCount() {
               return 1;
        }

        @Override
        public long getGroupId(int groupPosition) {
               return groupPosition;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
               TextView tv = new TextView(getActivity());

               //String parentID = ((WarengruppenVO) warengruppenEbene1.get(parent.getId())).get_id();
               Log.d(&quot;BIER&quot;, parent.getId() + &quot;&lt;&lt;&lt; Die Parent ID&quot;);

               //WarengruppenVO vo = childrenByParentID.get(parent.getId()).get(groupPosition);
               tv.setText(groupPosition+&quot; &quot;+isExpanded+&quot; &quot;+parentId+&quot; &quot;+parent.getId()+ &quot; &quot; + arrayPosition);
               tv.setTextColor(Color.BLACK);
               tv.setTextSize(20);
               tv.setPadding(12, 7, 7, 7);
               tv.setBackgroundColor(Color.RED);

               return tv;

        }

        @Override
        public boolean hasStableIds() {
               // TODO Auto-generated method stub
               return true;
        }



        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
               // TODO Auto-generated method stub
               return true;
        }
    }   
}

— geändert am 28.05.2014, 12:53:04

Antworten
Björn Karpenstein
  • Forum-Beiträge: 26

28.05.2014, 12:32:56 via Website

Hi Fabian!

Vielen Dank für Deine Antwort. Ich vermute meine Anforderung lässt sich leider nicht in einen binären Baum abbilden, da ich hier nicht nur links/rechts-Zeiger hätte.

Wenn Du dir den Screenshot oben ansiehst, hätte ich die folgende Tabellenstruktur:

|
--Getr&auml;nke  (id: 1 / Parent -1 / title / description / rabatt)
|            |
|            --&gt; SoftDrinks  (id: 2 / Parent 1/ title / description / rabatt)
|            |
|            --&gt; Spirituosen  (id: 3 / Parent 1/ title / description / rabatt)
|            |
|            --&gt; Cocktails  (id: 4 / Parent 1/ title / description / rabatt)
|            |
--Speisen  (id: 5 / Parent -1/ title / description / rabatt)
|            |
|            --&gt; Pizza  (id: 6 / Parent 5/ title / description / rabatt)
|            |
|            --&gt; Salate  (id: 7 / Parent 5/ title / description / rabatt)
|            |
|            --&gt; Tappas  (id: 8 / Parent 5/ title / description / rabatt)
|            |
|            --&gt; Carne (id: 9 / Parent 5/ title / description / rabatt)

Ich habe ein Objekt "WarengruppenVO" mit den Attributen id, parent, title, description, rabatt

Gesucht ist eine UI Komponente und eine passende Datenstruktur hierfür, die beliebig tief diese Objekte strukturieren kann.

Der Baum soll editierbar (also z.B. der Titel Getränke) und verschiebbar sein (Drag and Drop). Die Datenstruktur soll sich aktualisieren und ich muss die Möglichkeit haben beim Aktualisieren eine Datenbankanweisung durchzuführen.

Antworten
Fabian Simon
  • Forum-Beiträge: 359

02.06.2014, 13:28:35 via Website

Nö ich versteh dein Problem nicht...
Warum als Baum anzeigen ???
und nicht als Tabelle ??
bzw. wie soll der Baum aussehen ??
Das ist ja ein Gui problem oder ?
Kein Struktur Problem.

Antworten