Android ListView (Custom) soll auf Hardwaretasten nicht reagieren.

insidERR

Mitglied
Hallo zusammen,
ich bin absolut neu in der Java/Androidwelt. Erstelle aber schon lange Tools in VBA, VB.net und habe etwas C (Arduino) Erfahrung.

Meine Java "Hallo Welt" ist eine App für einen Barcodescanner der auf der Arbeit in der Warenwirtschaft eingesetzt werden soll.
Ziel ist es Codes zu scannen und Informationen dazu zu erhalten. Die App soll eigentlich nur den Barcode (Zahlenfolge) an einen Server senden und die antwort darstellen. Das serverseitige Programm habe ich schon in VB.net erstellt. Die Kommunikation funktioniert perfekt.

Mein Problem ist im aktuellen Fall, dass ich die Tasten(Auf/ab, links/rechts, enter, P1,P2) auf dem Gerät schon für andere Funktionen der App nutze, wie z.B. in einem Textfeld die Stückzahl durch auf/ab zu erhöhen/reduzieren und mit {Enter} bestätigen.. Sonst haben die Tasten keine weitere Funktion.

Ich habe ein ListView (benutzerdefiniert mit zwei Zeilen) welches beim Scannen gefüllt wird (Server kriegt den Zahlencode, wertet ihn aus und schickt 1-10 zweizeilige Einträge als antwort welche in der ListView angezeigt werden). Funzt alles wie gewollt.
Nun ist das blöde, dass wenn die Liste gefüllt ist und ich die Tasten auf/ab oder Enter auf dem Geät drücke alle Aktionen auf der/dem ListView landen und verarbeitet werden. Heisst wenn ich {ab} drücke, will ich dass in dem unter dem ListView liegenen Textfeld der Zahlwert kleiner wird.
Das mache ich mit
Java:
@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode==KeyEvent.KEYCODE_DPAD_UP){
            if(StückZahl<999){
                VibrateDevice(150);
                StückZahl++;
                AnzahlEingabe.setText(String.valueOf(StückZahl));
            }
        }

        if(keyCode==KeyEvent.KEYCODE_DPAD_DOWN){
            if(StückZahl>0){
                VibrateDevice(150);
                StückZahl--;
                AnzahlEingabe.setText(String.valueOf(StückZahl));
            }
        }

        if(keyCode==KeyEvent.KEYCODE_DPAD_RIGHT){
            if(StückZahl<989){
                VibrateDevice(150);
                StückZahl +=10;
                AnzahlEingabe.setText(String.valueOf(StückZahl));
            }
        }

        if(keyCode==KeyEvent.KEYCODE_DPAD_LEFT){
            if(StückZahl>9){
                VibrateDevice(150);
                StückZahl -=10;
                AnzahlEingabe.setText(String.valueOf(StückZahl));
            }
        }

        //Buttons: einbuchen / ausbuchen aktivieren
        if(keyCode==KeyEvent.KEYCODE_ENTER){
            Einbuchen.setEnabled(true);
            Ausbuchen.setEnabled(true);
            VibrateDevice(150);
        }
        return false;
    }
Bei leerer ListView klappt alles wie gewollt.
Bei gefüllter ListView gehe ich mit den auf/ab Tasten die Liste rauf und runter. Mit {enter} wird ein Clickereigniss ausgelöst als hätte man auf dem Display geklickt. Der hier beschriebene Code wird dabei größtenteils solange ignoriert, bis ich mich mit den Tasten ganz nach oben oder unter durchgeklickt habe und es nicht weiter geht. Dann werden die Ereignisse hier ausgelöst. Die Tasten links/rechts werden hier immer erfasst. Auf {enter} wird hier garnicht reagiert.

Frage: gibt es eine Möglichkeit, wie ich einstellen kann, dass ListView auf keine Taste, sondern nur auf Touchclicks reagiert? Das ".setOnItemClickListener" Ereigniss muss aber funktionieren, da ich mit den angeklickten Werten weiter arbeiten will.

Mit der SuFu bin ich weder Google noch hier weiter gekommen.
Danke :)
 

Jw456

Top Contributor
Du hast also ein Android Gerät mit einer HW Tastatur.

Zeige mal wie du die oder den Listener die Listview gesetzt hast.
 

Jw456

Top Contributor
In dem KeyEventListener solltest du prüfen von wo das Event kommt. Welche View gerade den Fokus hat. Ist es die ListView dann überspringst du einfach deine Tasten.
 

insidERR

Mitglied
Hallo "Jw456"
Danke für deine Antwort.
Ich habe die benutzerdefinierte ListView anhand von verschiedenen Beispielen aus dem Netz erstellt.
Bin grad nicht sicher was du meinst, da ich noch alle Begriffe kenne.
Mit dem Code hier kann ich mir den angeklickten Listeneintrag oder gedrückte Taste anzeigen lassen.
Java:
DetailListe.setOnKeyListener((v, keyCode, event)->{
    char pressedKey = (char) event.getUnicodeChar();
    Toast.makeText(MainActivity.this, "KeyCode: "+keyCode,Toast.LENGTH_SHORT).show();
    return false;
});

DetailListe.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    //@Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Toast.makeText(MainActivity.this, "Zeile 1: "+ String.valueOf(xZeile1.get(position)) + " ; Zeile 2: " + String.valueOf(xZeile2.get(position)),Toast.LENGTH_SHORT).show();
    }
});

Scheint, als hätte die ListView (DetailListe) den Focus dauerhaft.

Die ListView wird über den folgenden Adapter gefüttert.
Java:
    class myListViewAdapter extends ArrayAdapter<String> {
        Context context; String rZeile1[]; String rZeile2[];
        myListViewAdapter (Context c, ArrayList<String> Zeile1, ArrayList<String> Zeile2) {
            super(c, R.layout.listeneintrag, R.id.txtZeile1, Zeile2);
            this.context = c;
            this.rZeile1 = Zeile1.toArray(new String[0]);
            this.rZeile2 = Zeile2.toArray(new String[0]);
        }

        @Override
        public View getView(int position,  View convertView,  ViewGroup parent) {
            LayoutInflater layoutInflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View row = layoutInflater.inflate(R.layout.listeneintrag, parent, false);

            TextView Zeile1 = row.findViewById(R.id.txtZeile1);
            TextView Zeile2 = row.findViewById(R.id.txtZeile2);
            Zeile1.setText(rZeile1[position]);
            Zeile2.setText(rZeile2[position]);
            return row;
        }
    }

Aufruf erfolgt über
Java:
        myListViewAdapter AdapterListe = new myListViewAdapter(this, xZeile1, xZeile2);
        DetailListe.setAdapter(AdapterListe);

xZeile1 und xZeile2 sind beide gefüllte "ArrayList"
 

Jw456

Top Contributor
Estmal eins Klassen schreibt man Groß Variablen klein.
"myListViewAdapter AdapterListe = new myListViewAdapter(this, xZeile1, xZeile2);"
Die Kasse "MyListView" bitte Groß und die Variable "adapterListe" kein erleichtert das lesen.
Auch das „DetailListe“ ist bestimmt das Objekt von der ListView und nicht die Klasse.



Für was setzt du einen Klicklistener auf die ListView?
„DtailListe.setOnKeyListener((v, keyCode, event)->{„
Ohne den Listener, kann die Liste auch mit den HW Tasten gesteuert werden.

Da wird der ich sage mal defaultlister der Activity nicht aufgerufen. „onKeyDown“
Damit hast du zwei Listener auf das Objekt gesetzt.

PS bevor jetzt wider Einwände von Usern wegen der Begrifflichkeit
„Default Listener Activity“ kommt ich weiß das dis nicht der richtige Ausdruck ist erschien mir hier aber doch sinnvoll.


Außer du bist in der Liste ganz oben drückst nach oben dann wird der default aufgerufen. Am ende der Liste das gleiche.
 

insidERR

Mitglied
Hallo Jw456,
danke für deine Antwort.
Das mit der Groß/kleinschreibung ist ne persöhnliche Sache. Bringe das Programmiere mir selbst bei. Meinen Code liest außer mir keiner.
Habe da nicht besonders drauf geachtet. Bin aber für Tips immer offen, wenns etwas erleichtert. Werde versuchen darauf zu achten. :)
„DtailListe.setOnKeyListener((v, keyCode, event)->{„ hatte ich nur temporär gemacht um zu sehen ob das Objekt auf Tastenevents reagiert. Kann praktisch weg.

Ich habe jetzt diesen Code hier geschrieben, der in die richtige Richtung geht.
Wenn "DetailListe" Tastenanschläge erkennt, werden diese an den zuerst geposteten Code übergeben und alles weitere abgebrochen. Allerdings wird der erste Eintrag in der Liste markiert.
Außerdem wird der "onKeyDown" zwei Mal hintereinander schnell durchlaufen was bewirkt dass mein auf/abzähler das doppelte addiert/subtrahiert.
Java:
        DetailListe.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View view, int i, KeyEvent keyEvent) {
                onKeyDown(keyEvent.getKeyCode(), keyEvent);
                return true;
            }
        });
Wenn ich "onKeyDown" weg lasse, werden alle Tastenanschläge ignoriert :-(
 

Jw456

Top Contributor
Der listener wird beim Taste down Taste up durchlaufen. Du musst schon das Event auswerten nicht nur den Tasten Code. Im Event ist der Tasten Code und ob die Taste gedrückt oder losgelassen wird.
 

Jw456

Top Contributor
Ich weiß jest nicht genau wenn du true zurück gibst wird glaube auch der cursor der Liste eins hoch oder runter gesetzt oder war es false musst du testen.
 

insidERR

Mitglied
Also wenn ich auch das Event auswerte und zwar so:
Java:
        DetailListe.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View view, int i, KeyEvent keyEvent) {
                 if(keyEvent.getKeyCode()==KeyEvent.KEYCODE_DPAD_DOWN || keyEvent.getKeyCode()==KeyEvent.KEYCODE_DPAD_UP||keyEvent.getKeyCode()==KeyEvent.KEYCODE_ENTER)
                {
                    //onKeyDown(keyEvent.getKeyCode(), keyEvent);
                    return true;
                }
                return false;
            }
        });
werden die Tasten auf/ab und enter komplett ignoriert. Der Cursor geht die Liste auch nicht mehr auf/ab. Das blöde ist, dass auch der ganz am Anfang gepostete Code "OnKeyDown" nicht abgearbeitet wird. Das brauch ich aber, da dort auf die besagten Tasten reagiert werden soll.
Wenn ich in dem auskommentiertem Code hier den Aufruf "onKeyDown" wieder aktiviere, wird er anscheinend gleich zwei Mal hintereinander durchlaufen.
Im aktuellen Fall werden alle anderen Tasten bis auf die besagten abgearbeitet z.B. links/rechts. Da wird das "onKeyDown" abgearbeitet. Je ein Mal beim Drücken. Genau wie gewoll. Die Liste interessiert links/rechts natürlich nicht.
Wenn die ListView noch nicht gefüllt ist, funktionieren auch die Tasten auf/ab/enter wie gewollt.
 

Jw456

Top Contributor
Zu deinem letzten Code.
Das ist ja der Listener der von die Listview bei einem KeyEvent aufgerufen wird.
In diesem rufst du ja deinen Default listnener auf. in der auskommentierten Zeile 6.
Du leidest eigentlich das empfangene Event einfach wieder an den Globalen Listener.
Da du in Zeile 7 gibst du True zurück das heißt für dieLlistView das sich schon um das Event gekümmert wurde und es den Listen Cursor nicht setzen muss .

Wie ich schon sagte ist es vollkommen normal das die Callback Methode zweimal aufgerufen wird einmal beim Drücken der Taste und einmal beim Loslassen der Taste.

Du solltest prüfen welche Action in dem Event gesetzt ist und vielleicht nur bei einen ACTION_DOWN reagieren. Das würde ich in dem globalen Listener machen denn den willst du ja auch benutzen wenn du nicht in der ListView bist. Auch wenn du nicht in der Liste bist wird bei einem Tastenklick der Listener zweimal aufgerufen
Java:
 @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            {
                if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
                    if (StückZahl < 999) {
                        VibrateDevice(150);
                        StückZahl++;
                        AnzahlEingabe.setText(String.valueOf(StückZahl));
                    }
                }
                ......



die Zeile 6 solltest du wieder activiren.
 

insidERR

Mitglied
Hallo und Danke nochmal,
das sieht sehr gut aus. Ich muss noch weiter Verständnis für Java enwickeln. In .NET läufts etwas anders.
Jetzt wird nicht mehr durch die Listeneinträge geklickt und es gibt auch keine Doppelklicks mehr. Super :)

Was jetz etwas stört ist, dass wenn die Liste zum ersten Mal gefüllt wird und ich links/rechts oder enter drücke, der erste (oder angeklickte) Listeneintrag markiert(etwas dunklerer Hintergrund) wird und sonst nix passiert. Erst beim zweiten Tastenklick wird rauf/runter gezählt oder auf enter reagiert.
Der erste Eintrag in der Liste bleibt solange "markiert" bis ich auf dem Display irgendwohin drücke. Dann wird die Markierung (Focus) für immer aufgehoben, egal was danach passiert.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Probleme mit custom dynamic ListView Android & Cross-Platform Mobile Apps 15
B Android ListView set custom check Image and delete Android & Cross-Platform Mobile Apps 0
L Android SearchBox für Custom Listview Android & Cross-Platform Mobile Apps 5
J ListView Item individuell einfärben Android & Cross-Platform Mobile Apps 17
I Android ListView, Werte aktualisieren ohne die Liste komplett neu zu laden Android & Cross-Platform Mobile Apps 5
W ListView OnItemClicklistener setzen mit Ausgabe Android & Cross-Platform Mobile Apps 35
K Null-Pointer-Exception in ListView - wird über Datenbank gefüllt Android & Cross-Platform Mobile Apps 1
W ListView und Arrays... Android & Cross-Platform Mobile Apps 68
W Android Wieso kann ich keine ListView mehr zum Layout hinzufügen? Android & Cross-Platform Mobile Apps 1
W Android Kann keine ListView mehr in der MainActivtiy anzeigen, obwohl noch sehr viel Platz frei ist Android & Cross-Platform Mobile Apps 1
L ListView aktuallisiert sich nicht Android & Cross-Platform Mobile Apps 15
L Android ListView kollabiert in Scrollview Android & Cross-Platform Mobile Apps 9
A ImageButton in ListView Item bei klick ändern Android & Cross-Platform Mobile Apps 3
J Android Suche in einer ListView Android & Cross-Platform Mobile Apps 3
H Android ArrayList <-> ArrayAdapter <-> ListView Android & Cross-Platform Mobile Apps 10
L Android ListView swipe zum löschen Android & Cross-Platform Mobile Apps 1
M Android ListView wird nicht dargestellt Android & Cross-Platform Mobile Apps 2
Maresuke Android Android ListView Textfarbe und Texthintergrund ändern? Android & Cross-Platform Mobile Apps 5
A Android Problem mit ListView und OnItemClickListener.. Android & Cross-Platform Mobile Apps 10
S Listview Einträge aus "xml" Datei Android & Cross-Platform Mobile Apps 1
S Android Studio MySql Daten in Listview mit sub Item Android & Cross-Platform Mobile Apps 11
S Textdatei in ListView einlesen Tutorial gesucht!? Android & Cross-Platform Mobile Apps 3
kaoZ Tutorial .xml Layouting für z.B ListView elemente Android & Cross-Platform Mobile Apps 7
M Android ListView und Checkbox Android & Cross-Platform Mobile Apps 6
L TableRows in ListView darstellen Android & Cross-Platform Mobile Apps 2
M ListView mit ListAdapter füllen Android & Cross-Platform Mobile Apps 5
U Android ListView Frage Android & Cross-Platform Mobile Apps 6
H Android ListView Images aus dem Internet via Thread Android & Cross-Platform Mobile Apps 3
T Android: ListView-Adapter: Adapter wird ständig aufgerufen Android & Cross-Platform Mobile Apps 2
H Android SAX|ListView NullPointerException Android & Cross-Platform Mobile Apps 2
A Probleme mit ListView / ArrayAdapter Android & Cross-Platform Mobile Apps 3
B Android Memory Leak: Custom Adapter, Timer Android & Cross-Platform Mobile Apps 9
J Android Custom ViewGroup onMeasure() - heightMeasureSpec ist 0. Warum? Android & Cross-Platform Mobile Apps 2
Miguel Gonzalez Android Anfaengerproblem: Multiple Custom Views in Custom Views Android & Cross-Platform Mobile Apps 2
L Custom Dialog Button event Android & Cross-Platform Mobile Apps 2
J Was soll das bedeuten ? does not require android.permission.BIND_JOB_SERVICE permission Android & Cross-Platform Mobile Apps 7
D Wie soll ich anfangen (GWT Mobile, Phone Gap)? Android & Cross-Platform Mobile Apps 3
A Absolute Layout soll auf jedem Gerät gleich aussehen Android & Cross-Platform Mobile Apps 4

Ähnliche Java Themen

Neue Themen


Oben