android custom table list mit einer statischen Zeile

  • Antworten:55
  • OffenNicht stickyBentwortet
  • Forum-Beiträge: 49

10.03.2016, 10:27:28 via Website

hallo zusammen,

in meiner android app habe ich eine custom table list, in der die Daten dynamisch gefüllt werden.
nur die erste Zeile soll eine statische Zeile werden, welche ich via Programmierung löse.
ich habe diese function um die Daten in die Liste zu füllen.

private void showList() {

        boolean FirstRow = true;

        ArrayList<DatabaseListItems> databaseList = new ArrayList<>();
        databaseList.clear();


        String query = "SELECT * FROM " + DatabaseHelper.DATABASE_TABLE;


        Cursor c1 = dbHandler.selectQuery(query);
            if (c1.moveToFirst()) {
                do {
                    DatabaseListItems databaseListItems = new DatabaseListItems();

                    if (c1.getPosition() == 0 && FirstRow == true) {

                        databaseListItems.setFirstRow(true);

                        FirstRow = false;

                        databaseListItems.setFirstName("FIRST ROW");

                        databaseListItems.setSecondName(null);

                        c1.moveToPosition(-1);

                    } else {
                        databaseListItems.setFirstRow(false);

                        FirstRow = false;

                        databaseListItems.setFirstName(c1.getString(c1.getColumnIndex(DatabaseHelper.COLUMN_FIRSTNAME)));

                        databaseListItems.setSecondName(c1.getString(c1.getColumnIndex(DatabaseHelper.COLUMN_SECONDNAME)));

                        }


                    databaseList.add(databaseListItems);

                } while (c1.moveToNext());
            }
            c1.close();


        DatabaseListAdapter databaseListAdapter = new DatabaseListAdapter(getActivity(), databaseList);
        ListView.setAdapter(databaseListAdapter);


    }

DatabaseListItems

public class DatabaseListItems {

    String firstname;
    String secondname;
    Boolean FirstRow;



    public String getFirstName() {
        return firstname;
    }

    public void setFirstName(String first name) {
        this.firstname= firstname;
    }

    public String getSecondName() {
        return secondname;
    }

    public void setSecondName(String secondname) {
        this.secondname = secondname;
    }



    public Boolean getFirstRow() {
        return FirstRow;
    }

    public void setFirstRow(Boolean FirstRow) {
        this.FirstRow = FirstRow;
    }


}

DatabaseListAdapter

public class DatabaseListAdapter extends BaseAdapter {

    Context context;
    ArrayList<DatabaseListItems> databaseList;
    ArrayList<String> DeleteList = new ArrayList<>();




    public DatabaseListAdapter(Context context, ArrayList<DatabaseListItems> list) {
        this.context = context;
        databaseList = list;
    }


    @Override
    public int getCount() {
        return databaseList.size();
    }

    @Override
    public Object getItem(int position) {
        return databaseList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup arg2) {
        final DatabaseListItems databaseListItems = databaseList.get(position);


        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.custom_listview_item, null);

        }


        TextView tvFirstName = (TextView) convertView.findViewById(R.id.txtViewFirstName);
        tvFirstName.setText(databaseListItems.getFirstName());


        TextView tvSecondName = (TextView) convertView.findViewById(R.id.txtViewSecondName);
        tvSecondName.setText(databaseListItems.getSecondName());

        View row = convertView.findViewById(R.id.row);
        ImageView Arrow = (ImageView) convertView.findViewById(R.id.Arrow);






        // First Static Row
        if (databaseListItems.getFirstRow() == true) {

            tvSecondName.setAlpha(0.0f);
            Arrow.setAlpha(1.0f);

            tvFirstName.setTextColor(Color.parseColor("#161616"));
            row.setBackgroundColor(Color.parseColor("#f7f7f7"));
            row.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Intent intent=new Intent(context,OtherActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(intent);
                }
            });
        } else {

            tvSecondName.setAlpha(1.0f);
            Arrow.setAlpha(0.0f);


        }

        return convertView;
    }

}

image
Auf den ersten Blick sieht alls gut aus.
Aber wenn ich dann hoch unter runter scrolle, bekommen zufällige Zeilen die background color und die onClick function , welche eigentlich nur die erste statische Zeile haben sollte

image
image

UPDATE
Mir wurde bereits gesagt, dass ich einen ViewHolder bräuchte, um das Problem zu lösen.

Habe damit aber noch nie gearbeitet und das war dann mein erster Versuch:

DatabaseListAdapter mit ViewHolder

public class DatabaseListAdapter extends BaseAdapter {

    Context context;
    ArrayList<DatabaseListItems> databaseList;
    ArrayList<String> DeleteList = new ArrayList<>();

    static class ViewHolder {
        TextView tvFirstName;
        TextView tvSecondName;
        View row;
    }



    public DatabaseListAdapter(Context context, ArrayList<DatabaseListItems> list) {
        this.context = context;
        databaseList = list;
    }


    @Override
    public int getCount() {
        return databaseList.size();
    }

    @Override
    public Object getItem(int position) {
        return databaseList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }



    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final DatabaseListItems databaseListItems = databaseList.get(position);

        View rowView = convertView;

        if (rowView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            rowView = inflater.inflate(R.layout.custom_listview_item, null);

            ViewHolder viewHolder = new ViewHolder();
            viewHolder.tvFirstName = (TextView) rowView.findViewById(R.id.txtViewFirstName);
            viewHolder.tvSecondName = (TextView) rowView.findViewById(R.id.txtViewSecondName);
            viewHolder.row = rowView.findViewById(R.id.row);

            rowView.setTag(viewHolder);
        }



        final ViewHolder holder = (ViewHolder) rowView.getTag();
        holder.tvFirstName.setText(databaseListItems.getFirstName());
        holder.tvSecondName.setText(databaseListItems.getSecondName());




        if (databaseListItems.getFirstRow() == true) {

            holder.tvSecondName.setAlpha(0.0f);
            holder.tvFirstName.setTextColor(Color.parseColor("#161616"));
            holder.row.setBackgroundColor(Color.parseColor("#f7f7f7"));
            holder.row.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Intent intent=new Intent(context,OtherActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(intent);
                }
            });
        } else {
            holder.tvSecondName.setAlpha(1.0f);
            }
        }

        return rowView;
    }

}

Hat aber leider nichts gebracht :/

— geändert am 10.03.2016, 10:29:36

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

10.03.2016, 14:44:29 via Website

Leider verstehe ich dein Problem nicht, du hast doch eine statische Zeile ( die die im 1. Bild verschommen ist) oder sehe ich das falsch?

Der Code sieht auf den 1. Bilck nicht falsch aus.
Doch wieso machst du es dir so komliziert?
Du kannst doch bevor du die do-while schleife über deine Query machst, das statische Objekt zur liste hinzufügen.
Damit musst du das in der schleife nicht mehr machen ind das Problem ist gelößt

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 49

10.03.2016, 14:46:39 via Website

das Problem ist doch auf Screen 2 und 3 zu erkennen.
es bekommen beim scrollen die zufällig andere Zellen den selben Background-Color wie die erste statische und außerdem bekommen diese auch die onclick Funktion, welche nur die erste statische haben sollte.

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

10.03.2016, 14:53:37 via Website

Ja weil die schelife etwas verwirrend ist.
Am besten du behandelst das statische Elemnt ausßerhalb der schelife, dann hast du das Problem nicht

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 49

10.03.2016, 14:54:48 via Website

okay, und wie füge ich das statische Objekt zur meiner Liste hinzu OHNE die Schleife?

Antworten
  • Forum-Beiträge: 359

10.03.2016, 14:56:10 via Website

Hab dein Problem zwar au net ganz verstanden.
Aber schau mal hier :
http://developer.android.com/reference/android/widget/Adapter.html#getView%28int,%20android.view.View,%20android.view.ViewGroup%29

und versuche mal in deiner getView Methode des Adapter die if bedingung anders zu setzten...:

Du willst ja nicht immer die erste angezeige zeile sonder die erste in der Liste !

somit mache

// First Static Row
if (databaseListItems.getFirstRow() == true) {

        tvSecondName.setAlpha(0.0f);
        Arrow.setAlpha(1.0f);

        tvFirstName.setTextColor(Color.parseColor("#161616"));
        row.setBackgroundColor(Color.parseColor("#f7f7f7"));
        row.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent intent=new Intent(context,OtherActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);
            }
        });
    } else {

        tvSecondName.setAlpha(1.0f);
        Arrow.setAlpha(0.0f);


    }

zu

  // First Static Row
        if (position == 0){ //<-- HIER IST DIE AENDERUNG
        tvSecondName.setAlpha(0.0f);
        Arrow.setAlpha(1.0f);

        tvFirstName.setTextColor(Color.parseColor("#161616"));
        row.setBackgroundColor(Color.parseColor("#f7f7f7"));
        row.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent intent=new Intent(context,OtherActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);
            }
        });
    } else {

        tvSecondName.setAlpha(1.0f);
        Arrow.setAlpha(0.0f);


    }

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

10.03.2016, 14:56:53 via Website

Das ist relativ einfach ;)

       DatabaseListItems staticItem= new DatabaseListItems();
     staticItem.setFirstRow(true);
                    staticItem.setFirstName("FIRST ROW");
                    staticItem.setSecondName(null);                        
databaseList.add(staticItem); // erstet Item hinzufügen

    Cursor c1 = dbHandler.selectQuery(query);
        if (c1.moveToFirst()) {
            do {
                DatabaseListItems databaseListItems = new DatabaseListItems();

                    databaseListItems.setFirstRow(false);

                    FirstRow = false;

                    databaseListItems.setFirstName(c1.getString(c1.getColumnIndex(DatabaseHelper.COLUMN_FIRSTNAME)));

                    databaseListItems.setSecondName(c1.getString(c1.getColumnIndex(DatabaseHelper.COLUMN_SECONDNAME)));


                databaseList.add(databaseListItems);

            } while (c1.moveToNext());
        }
        c1.close();

Einfach das Item erstellen und vor der Schleife der ArrayList hinzufügen.

Übrigens, das Flag istFisrtRow kannst du dir sparen.
Bei Listen hat man immer die Position und wenn Position==0 dann erstes Item

— geändert am 10.03.2016, 14:57:48

LG Pascal //It's not a bug, it's a feature. :) ;)

AndroidEntwickler

Antworten
  • Forum-Beiträge: 49

10.03.2016, 15:05:50 via Website

okay, danke - so klappt es auch mit weniger codezeilen :)
ALLERDINGS hat das mein eigentliches Problem nicht gelöst :(

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

11.03.2016, 11:35:10 via App

hast du die schleife mal angepasst?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 49

11.03.2016, 11:39:43 via Website

ja, sieht jetzt so aus:

private void showList() {

    ArrayList<DatabaseListItems> databaseList = new ArrayList<>();
    databaseList.clear();


    DatabaseListItems staticItem= new DatabaseListItems();
    staticItem.setFirstName("FIRST ROW");
    staticItem.setSecondName(null);
    databaseList.add(staticItem);



    String query = "SELECT * FROM " + DatabaseHelper.DATABASE_TABLE;


    Cursor c1 = dbHandler.selectQuery(query);
    if (c1 != null && c1.getCount() != 0) {
        if (c1.moveToFirst()) {
            do {
                DatabaseListItems databaseListItems = new DatabaseListItems();

                databaseListItems.setFirstName(c1.getString(c1.getColumnIndex(DatabaseHelper.COLUMN_FIRSTNAME)));

                databaseListItems.setSecondName(c1.getString(c1.getColumnIndex(DatabaseHelper.COLUMN_SECONDNAME)));

                databaseList.add(databaseListItems);

            } while (c1.moveToNext()) ;
        }
        c1.close();

    } 

    DatabaseListAdapter databaseListAdapter = new DatabaseListAdapter(getActivity(), databaseList);
    ListView.setAdapter(databaseListAdapter);

}

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

11.03.2016, 11:53:22 via App

Sieht eigentlich ok aus.
Vielleicht mal debuggen und Log ausgaben machen.

— geändert am 11.03.2016, 11:53:31

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 49

11.03.2016, 11:54:44 via Website

und an welcher Stelle soll ich welche Log ausgaben machen?
Weiß ja nicht wonach ich suchen soll - bin total verzweifelt mittlerweile :/
habe schon so viele Stunden über dem Code gehangen und versteh es einfach nicht

habe gerade Mal folgende Log Ausgabe gemacht:

 if (position == 0) {

            Log.e("-->",""+position);
....

Bekomme als Ausgabe:

0 0 0 0

Das 4x Position == 0 sein soll verstehe ich jetzt nicht so wirklich

— geändert am 11.03.2016, 11:59:08

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

11.03.2016, 12:05:36 via App

Das heisst 4 mal wird die pos 0 geladen.
Ich schau mir das später mal an.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 22.353

12.03.2016, 14:00:58 via Website

Hallo AndroidEntwickler,

Bitte nicht pushen, ich bin mir sicher, dass sich hier jemand melden wird, wenn er eine Antwort für dich hat. Danke (smug)

Viele Grüße,
Andy


OnePlus 3 (Resurrection Remix 5.8.2)
LG G Watch

Regeln | unsere Mods & Admins

Pascal P.

Antworten
  • Forum-Beiträge: 49

16.03.2016, 13:39:55 via Website

also mittlerweile bin ich ein Stück weiter gekommen (denke ich)

allerdings stürzt meine App ab, wenn ich einen Eintrag länger gedrückt halte:

java.lang.NullPointerException: Attempt to invoke virtual method
'android.view.View android.view.View.findViewById(int)' on a null
object reference at
xxx.Overview$2.onItemLongClick(Overview.java:72) at
android.widget.AbsListView.performLongPress(AbsListView.java:3127) at
android.widget.AbsListView$CheckForLongPress.run(AbsListView.java:3059)
at android.os.Handler.handleCallback(Handler.java:739) at
android.os.Handler.dispatchMessage(Handler.java:95) at
android.os.Looper.loop(Looper.java:148) at
android.app.ActivityThread.main(ActivityThread.java:5417) at
java.lang.reflect.Method.invoke(Native Method) at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Das ist die betroffene Zeile:

ListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {

                final TextView ItemID = (TextView) ListView.getChildAt(position).findViewById(R.id.txtViewID);
        return FragementView;
    }

— geändert am 16.03.2016, 13:41:58

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

16.03.2016, 13:43:38 via Website

Ich würde nicht direkt mitt dem ListView objekt rbeiten.
Du bekommst doch deine view als view Parameter überfagen, damit kannst du einfach view.findViewById(..); etc. machen.
Dann sollte es auch keine NPE geben

— geändert am 16.03.2016, 13:50:12

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten

Empfohlene Artikel