Bilder als Buttons

  • Antworten:34
  • Bentwortet
iRazoR
  • Forum-Beiträge: 66

30.03.2013, 00:01:34 via Website

Ein "Hallo" an alle Android Developer des Forums,

ich habe gerade damit begonnen Android Apps zu entwickeln und benötige etwas Schützenhilfe.
Ich habe eine App programmiert, welche soweit auch funktioniert, jedoch besteht die Oberfläche aktuell
noch aus den Standardknöpfen.

Nun würde ich das Ganze gern etwas verfeinern und habe einen Entwurf eines möglichen Layouts gezeichnet (momentan noch auf Papier).
Das Problem ist, dass ich die Buttons gern kreisförmig anordnen würde, wie hier beispielhaft dargestellt:



A und B sind zwei Knöpfe, wie unterschiedliche Funktionen haben sollen.

Hat jemand eine Idee, wie ich das umsetzen kann? Kann man bestimmten Bereichen eines Bildes eine Funktion zuweisen, oder kann ich die Buttons irgendwie einzeln einbinden und zum Gesamtbild zusammensetzen?

Antworten
Appsoluts
  • Forum-Beiträge: 304

30.03.2013, 09:52:48 via Website

Arbeite mit einem FrameLayout. Das Bild legst du als BG des FrameLayoutes und "da drüber" kannst du dann transparente Buttons legen

Antworten
iRazoR
  • Forum-Beiträge: 66

30.03.2013, 14:06:42 via App

Hey CBsol,

danke für die Antwort. Mit Framelayouts habe ich noch nicht gearbeitet. Kannst du mir etwas genauer erklären, was es damit auf sich hat und wie das genau funktioniert?

Antworten
Appsoluts
  • Forum-Beiträge: 304

30.03.2013, 14:10:51 via Website

Mir fällt gerade ein, dass du garkein FrameLayout brauchst,

du kannst einfach nen RelativeLayout kreieren, welchem du als BG dein ButtonBild setzt.
dann kannst du ja relative alle Buttons darein schreiben, und setzt alle Buttons einfach auf transparent !

Antworten
iRazoR
  • Forum-Beiträge: 66

30.03.2013, 14:26:11 via App

so in der Richtung habe ich mir das gedacht, das Problem ist, das ich die Buttons nicht an meine Form anpassen kann, da die ja immer viereckig sind oder gibt es da einen Trick?

P.S.: Mit BG meinst du Background, oder?

Antworten
impjor
  • Forum-Beiträge: 1.793

30.03.2013, 18:26:54 via App

Ich denke nicht, das man die Form der Buttons anpassen kann. Ich würde eine View zum anzeigen alle Buttons nehmen, und in onTouch die Koordinaten prüfen und so den entsprechenden Button herauszufinden.
Gruß

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

Antworten
iRazoR
  • Forum-Beiträge: 66

30.03.2013, 19:59:44 via App

@impjor: Die Idee ist auch nicht schlecht, klingt aber nach viel Arbeit. Ich werde mir mal anschauen, wie umfangreich das Ganze für meine 44 Buttons ist ;-)

Für weitere Vorschläge bin ich trotzdem offen.

Antworten
Paul Bussmann
  • Forum-Beiträge: 5

31.03.2013, 22:16:11 via Website

Hy, das bekommst auch mit normalen .jpg oder . png hin in dem du diese als ImageView in dein Layout ziehst und dann kannst am besten noch die Id auf Button1, Button2 usw.... ändern. In meinen Beispiel habe ich bot1, bot2 usw da ich schreibfaul bin:what:
in deiner Java Classe wandelst die ImageView einfach als Button um!
Du Inplementierst einfach nen OnClickListener und zauberst aus der ImageView ein Butten:blink:

Hier mal ein beispiel von mir (sind aber mehrere ImageViews (Buttons) dann hast gleich was für ne Activity mit mehreren Buttons:

1package com.imageview.button;
2
3import android.app.Activity;
4import android.content.Intent;
5import android.os.Bundle;
6import android.view.Menu;
7import android.view.View;
8import android.view.View.OnClickListener;
9import android.widget.ImageView;
10
11public class MainActivity extends Activity implements OnClickListener {
12
13 ImageView bot1;
14 ImageView bot2;
15 ImageView bot3;
16 ImageView bot4;
17 ImageView bot5;
18 Intent intentbot1;
19 Intent intentbot2;
20 Intent intentbot3;
21 Intent intentbot4;
22 Intent intentbot5;
23
24 @Override
25 protected void onCreate(Bundle savedInstanceState) {
26 super.onCreate(savedInstanceState);
27 setContentView(R.layout.main);
28 bot1= (ImageView)findViewById(R.id.bot1);
29 bot2 = (ImageView)findViewById(R.id.bot2);
30 bot3 = (ImageView)findViewById(R.id.bot3);
31 bot4 = (ImageView)findViewById(R.id.bot4);
32 bot5 = (ImageView)findViewById(R.id.bot5);
33
34 { final Intent intentbot1 = new Intent();
35 intentbot1.setClass(MainActivity.this, DeineActivity1.class);
36 bot1.setOnClickListener(new OnClickListener() {
37 public void onClick(View v) {
38 startActivity(intentbot1);
39 }});}
40 {
41 final Intent intentbot2 = new Intent();
42 intentbot2 .setClass(MainActivity.this, DeineActivity2.class);
43 bot2.setOnClickListener(new OnClickListener() {
44 public void onClick(View v) {
45 startActivity(intentbot2 );
46 }});}
47
48 { final Intent intentbot3 = new Intent();
49 intentbot3 .setClass(MainActivity.this, DeineActivity3.class);
50 bot3.setOnClickListener(new OnClickListener() {
51 public void onClick(View v) {
52 startActivity(intentbot3 );
53 }});
54 }
55 { final Intent intentbot4 = new Intent();
56 intentbot4 .setClass(MainActivity.this, DeineActivity4.class);
57 bot4.setOnClickListener(new OnClickListener() {
58 public void onClick(View v) {
59 startActivity(intentbot4 );
60 }});
61
62 {
63 final Intent intentbot2 = new Intent();
64 intentbot2 .setClass(MainActivity.this,DeineActivity5.class);
65 bot5.setOnClickListener(new OnClickListener() {
66 public void onClick(View v) {
67 startActivity(intentbot2 );
68 }});}
69 }
70
71
72 }
73
74 @Override
75 public boolean onCreateOptionsMenu(Menu menu) {
76 // Inflate the menu; this adds items to the action bar if it is present.
77 getMenuInflater().inflate(R.menu.main, menu);
78 return true;
79 }
80
81 @Override
82 public void onClick(View v) {
83 // TODO Auto-generated method stub
84
85 }
86
87}

Antworten
iRazoR
  • Forum-Beiträge: 66

01.04.2013, 17:37:58 via App

hey, danke für den Beispiel Code. Das Problem ist nur leider nach wie vor, dass meine Buttons nicht viereckig werden sollen wie oben auf dem Bild zu sehen ist, weshalb es mit den ImageViews denke ich nicht so gut klappt. Die Idee mit den Koordinaten ist glaube ich schon das richtige, ich bin nur leider noch nicht dazu gekommen es zu testen, da ich momentan noch an einem anderen Problem hänge.

Trotzdem vielen vielem Dank.

Antworten
Paul Bussmann
  • Forum-Beiträge: 5

02.04.2013, 20:38:33 via Website

Naja müssen die ja auch nicht! Du kannst ja z.B in Photoshop die Grafik zusammenstellen! Es ist ja möglich im PS ein Bield aus einzelne Elemente zusammen zu bauen nent man da Ebenen und Exportierst einfach die Hauptgrafik (den Hintergrund später fürs Layout) getrent von den Buchstaben, dann die eizelnen Buchstaben.
Dann setzt halt in der layout.xml die Hauptgrafik als Hintergrund und fügst dan die Buchstaben als Einzelne Views dazu und 1-2-3 hast die Buchstaben als Views da drauf und weist die als clickbare Views dem OnClickListener zu und dann sind die wie als wären das Buttons.
Zu dem noch versätzbar falls du mal was ändern willst oder ne überarbeitete Grafik da einfügen willst:bashful:
Aber in Java führen viele wege ob leichter oder umständlich zum selben Ziel:lol:

Antworten
iRazoR
  • Forum-Beiträge: 66

02.04.2013, 22:33:04 via Website

Exakt ;-)

Ich glaube einfach, dass ist so nicht vorgesehen. Ich weis auch nicht, warum ich mein Layout unbedingt kreisförmig anordnen möchte =) Mal sehen, wenn ich wieder ein bisschen Zeit finde, ob mir noch etwas einfällt

Antworten
impjor
  • Forum-Beiträge: 1.793

02.04.2013, 23:23:58 via App

Ich würde versuchen, alle Buttons als Grafiken abzuspeichern (einnzeln) und dann in mehreren Views anlegen, die du dann natürlich irgendwie so anordnen musst, dass sie deinen Runden Layout entsprechen.
Nun kannst du die einzelnen Views mit onTochListenern versehen und anhand der x/y-Koordinaten prüfen, ob ein farbiges Pixel berührt wurde. Dann wurde der Button gedrückt. Wurde ein transparentes Pixel berührt musst du den Touch irgendwie an die anderen Views weiterleiten.
Gruß

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

Antworten
iRazoR
  • Forum-Beiträge: 66

03.04.2013, 16:13:10 via Website

impjor
Ich würde versuchen, alle Buttons als Grafiken abzuspeichern (einnzeln) und dann in mehreren Views anlegen, die du dann natürlich irgendwie so anordnen musst, dass sie deinen Runden Layout entsprechen.
Nun kannst du die einzelnen Views mit onTochListenern versehen und anhand der x/y-Koordinaten prüfen, ob ein farbiges Pixel berührt wurde. Dann wurde der Button gedrückt. Wurde ein transparentes Pixel berührt musst du den Touch irgendwie an die anderen Views weiterleiten.
Gruß

Der Vorschlag hat mich gerade auf eine geniale Idee gebracht. Um mal ein wenig licht ins Dunkel zu bringen: Das Ganze soll letztendlich eine Art Farbkreis/ -Ring werden der eine Aktion in Abhängigkeit vom gerückten Button ausführt. Durch den Vorschlag von Impjor ist mir gerade die folgende Idee gekommen:

1. Der Gesamte Kreis wird als ein ImageView eingebunden
2. Anwender drückt auf den Bildschirm
3. Drückt auf den Bereich der ImageView (also irgendwo auf den Kreis) wird geprüft welche Farbe die Pixel an der entsprechenden Stelle haben
4. Action wird anhand der Pixelfarbe ausgeführt.

Ist so etwas möglich? Kann die OnTouch Methode erkennen, welche Farbe der Hintergrund hat?

Antworten
impjor
  • Forum-Beiträge: 1.793

03.04.2013, 17:20:34 via Website

Nein ein OnTouchListener bekommt diese Info nicht mit. Allerdings kannst du anhand der Kooridinaten des MotionEvent's die Farbe des Pixel des ImageView bestimmen.
Siehe hier: http://stackoverflow.com/questions/7807360/how-to-get-pixel-colour-in-android

Gruß und viel Erfolg:D

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

iRazoR

Antworten
iRazoR
  • Forum-Beiträge: 66

05.04.2013, 17:59:10 via Website

Ok, das dachte ich mir, aber die Idee klingt echt gut, dass anhand der Pixel zu machen, darauf bin ich nicht gekommen. Vielen vielen Dank für die Unterstützung.

Antworten
iRazoR
  • Forum-Beiträge: 66

02.05.2013, 19:26:55 via Website

Nach langer Zeit bin ich nun endlich mal dazu gekommen, an dem Problem weiter zu arbeiten. Die Idee mit der Pixelfarbe entspricht genau dem, was ich benötige, nur leider scheitert es an der Umsetzung. Ich habe diverse Foren durchsucht, es will aber einfach nicht klappen.

Ich habe nun ein Bild wie dieses hier:



Das Bild heißt "circle" und liegt im Ordner "drawable". Nun hab ich das Bild als ImageView eingefügt und als onTouch deklariert:

ImageView circle = (ImageView) findViewById(R.id.circle);
circle.setOnTouchListener(this);

Und jetzt scheiterts an meinen Programmierkenntnissen.

Wie genau bekomme ich es nun hin, dass bei Berührung des Bildes die X- und Y-Koordinaten ermittelt werden und anhand derer dann die Pixelfarbe ausgegeben wird?

Antworten
Michele
  • Forum-Beiträge: 1.525

02.05.2013, 20:57:40 via Website

Ich finde das Arbeiten mit x und y Koordinaten zu kompliziert bei sowas.

Du machst einfach alle 4 Farben als einzelnes Bild.
Dann kannst du jedes Bild ein eigenen setOnClickListener(this); oder setOnTouchListener(this); z.B geben.



LG

Antworten
iRazoR
  • Forum-Beiträge: 66

02.05.2013, 22:57:12 via Website

Wir haben leider weiter oben im Thread schon festgestellt, dass eben genau das nicht funktioniert, da die Buttons nicht viereckig sein dürfen (in dem Beispiel mit den vier Farben würde das zwar funktionieren, mit mehreren Farben jedoch nicht, da sich die Buttons überschneiden würden).

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

02.05.2013, 23:03:04 via Website

Wieso zerteilst du das nicht in vier bereiche und setzt die Buttons dicht beieinander per Layout ?
Ich würde da exakt 0 energie was die Pixel Berechnung angeht. Je nach Device und Screen der verbaut
wurde ist das eh schon ungenau. Vielmehr die 48DP Größen die Google vorschlägt solltest du einhalten, größer geht ja
immer.

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Michele
  • Forum-Beiträge: 1.525

02.05.2013, 23:03:51 via Website

Warum soll sich das überschneiden wenn du es richtig setzt und die Grafik richtig malst?
Mac Systems sagte es auch nochmal wie ich es meinte.

Also gehen tut es.

PS: Wenn du sie als Button benutzen willst, heißt es noch lange nicht das du ein Button nehmen musst.
4x ImageView richtig gesetzt und alles geht ohne Probleme mit Touch oder Click.

LG

— geändert am 02.05.2013, 23:08:25

Antworten
iRazoR
  • Forum-Beiträge: 66

03.05.2013, 00:57:08 via Website

Wie gesagt, in dem Beispiel mag das gehen, der Kreis hat in der fertigen Ausführung aber bis zu 20 Farben, d.h. ich kann die Buttons nicht einfach einzeln einfügen und zusammensetzen, da sie dann überlappen und so nicht genau getroffen werden können.

Antworten
iRazoR
  • Forum-Beiträge: 66

03.05.2013, 00:59:43 via Website

Man sieht ja in meinem ersten Post, wie das ganze dann aussieht. Durch die Winkel würden viereckige Buttons überlappen was sicherlich Probleme gibt.

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

03.05.2013, 10:57:46 via Website

Was mich gerade stört ist das hier die ultimative lösung diskutiert wird anstatt da mal pragmatisch dranzugehen...

Nur mal so als Tip: Du kannst jeden View also auch ein layout mittels http://developer.android.com/reference/android/view/View.html#attr_android:rotation drehen.

Abgesehen davon wenn du jetzt soooo lange damit rum hampelst, wieso machst du es nicht einfacher ? Oder willst du in Schönheit sterben ?

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

03.05.2013, 10:58:13 via Website

Was mich gerade stört ist das hier die ultimative lösung diskutiert wird anstatt da mal pragmatisch dranzugehen...

Nur mal so als Tip: Du kannst jeden View also auch ein layout mittels http://developer.android.com/reference/android/view/View.html#attr_android:rotation drehen.

Abgesehen davon wenn du jetzt soooo lange damit rum hampelst, wieso machst du es nicht einfacher ? Oder willst du in Schönheit sterben ?

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
iRazoR
  • Forum-Beiträge: 66

03.05.2013, 11:55:08 via Website

Du verstehst mich falsch, es geht nicht um die perfekte Lösung aber ich möchte wenigstens eine Lösung, die fehlerfrei funktioniert. Das mit der Rotation ist ja schön und gut, nichtsdestotrotz überlappen die Views dann trotzdem, da die Buttons immer viereckig sind.

Wenn ich falsch liege, dann berichtige mich bitte aber ich denke mit Geometrie komme ich noch ganz gut klar.

Hier nochmal zur Verdeutlichung:



Wie du siehst überlappen die Buttons, wenn ich jedes einzelne Feld als View einfüge. Wenn ich außen klicke mag das nicht unbedingt stören, da die Displays der Geräte aber sehr klein sind wird problematisch.

— geändert am 03.05.2013, 12:21:32

Antworten
Michele
  • Forum-Beiträge: 1.525

03.05.2013, 12:29:10 via Website

Wenn das dann wirklich so komisch ist.

Dann bleibt dir halt nur noch X- und Y übrigt.
Und das alles in einem Bild halt.


LG

Antworten
iRazoR
  • Forum-Beiträge: 66

03.05.2013, 12:37:04 via Website

Leider ja. Technisch bedingt können Bilder leider nur viereckig exportiert/erstellt werden und Android Buttons sind auch immer nur viereckig. Deswegen bleibt letztendlich nur noch die Möglichkeit mit Koordinaten in einem Bild zu arbeiten und die Pixelfarbe abzufragen. Nur eben genau da hapert es bei mir. Wie muss die onTouch Methode aussehen um da umzusetzen? Ich weis, dass das Bild irgendwie in Bitmap konvertiert werden muss und die Pixelabfrage anhand der Motionevents funktioniert nur hat bisher keine meiner Versuche funktioniert.

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

03.05.2013, 12:53:52 via Website

da die Displays der Geräte aber sehr klein sind wird problematisch.


Und daher ist das auch schon dein eigentliches Problem. Das Design Skaliert nicht, bzw auf kleinen Devices, selbst mit deiner forcierten Lösung
wird es schwer für den Otto Normal User das zu verstehen. Dir ist klar das du Buttons mindest 48DP groß halten sollst, klickst du in die Mitte
ist das aber nicht unbedingt gegeben. Ich würde das einfach verwerfen und eine ANDERE Lösung dafür finden. Design lernte mich oftmals
Dinge die Ich Programmieren kann nicht zu tun, da der Enduser das nicht nutzten kann, bzw der "Mehrwert" den Aufwand nicht lohnt.

Aber da du dich ja gut mit Geometrie auskennst sollte das wirklich kein Thema sein festzustellen wo der Click denn jetzt war. Schreib dir einen Unit Tests der ohne UI Auskommt wo du genau diese Logic implementierst dann musst du in deiner onClick nur noch die Logic aufrufen und die liefert dir die ID oder was auch immer des Buttons zurück!

— geändert am 03.05.2013, 13:33:12

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
iRazoR
  • Forum-Beiträge: 66

03.05.2013, 22:08:17 via Website

Dir ist klar das du Buttons mindest 48DP groß halten sollst, klickst du in die Mitte
ist das aber nicht unbedingt gegeben.

Das mit der Größe ist erstmal nicht das Problem, da die App für ein 10" Tablet ausgelegt und da genug Platz ist.

Aber da du dich ja gut mit Geometrie auskennst sollte das wirklich kein Thema sein festzustellen wo der Click denn jetzt war. Schreib dir einen Unit Tests der ohne UI Auskommt wo du genau diese Logic implementierst dann musst du in deiner onClick nur noch die Logic aufrufen und die liefert dir die ID oder was auch immer des Buttons zurück!

Genau hier liegt mein Problem, da ich erst mit dem Programmieren begonnen habe...

Naja ich schaue mal ob ich es nicht doch noch hinbekomme!

Antworten
iRazoR
  • Forum-Beiträge: 66

05.05.2013, 13:29:11 via App

Danke für den Hinweis. Den Link (und viele weitere) habe ich mir bereits angesehen nur irgendwie komme ich mit der syntax nicht ganz klar.

Also das mit dem Koordinaten hnd der anschließende Teil mit den Farben ist denke ich nicht das Problem. Woran ich scheitere ist der Teil mit dem Bitmap.

In deinem Beispiel sieht das so aus:

ImageView imageView = ((ImageView)v);
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
int pixel = bitmap.getPixel(x,y);

Kannst du (oder jemand anderes) mir vielleicht kurz erklären, was hier gemacht wird bzw. das resultat daraus ist? Muss ich nicht auch irgendwomangeben, um welches Bild es sich handelt? Ich habe bisher immer unterschiedliche Ausführungen gefunden weshalb ich nicht ganz durchblicke.

Antworten
impjor
  • Forum-Beiträge: 1.793

05.05.2013, 18:23:39 via App

Ein Bitmap ist ein Bild. Über getPixel() bekommst du die Farbe des jeweiligen Pixels an x/y als int. Doch woher bekommt man nun das Bitmap-Objekt? Du könntest es über BitmapFactory.decodeResource(..) aus deinem res.drawable holen, über BitmapFactory.decodeStream aus einem Stream usw. Oder aber du fragst den Bitmap eines ImageView ab, welches die zweite Zeile tut. Das ImageView kommt aus der ersten Zeile. diese kommt wahrscheinlich aus einer onTouch-Methode, da diese das.Objekt, auf welches gedrückt wurde mitliefert. (Als Parameter v). Da eine onTouch Methode auf jeder View gesetzt werden kann, ein Button aber keinen Bitmap zurückliefern kann, wird nochmal dem Compiler gesagt, dass v ein ImageView ist, bzw. es wird in ein ImageView umgewandelt.

Gruß

— geändert am 05.05.2013, 18:25:32

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

iRazoR

Antworten
iRazoR
  • Forum-Beiträge: 66

05.05.2013, 19:30:02 via Website

@impjor

Vielen vielen Dank, ich denke jetzt hab ichs. Nur eine Frage stellt sich mir noch. Das mit dem Bitmap macht ja Sinn bezüglich der Farben. Muss ich meine Imageview dann auch als Bitmap im drawable Ordner speichern oder wird das hier automatisch nach Bitmap konvertiert?

Antworten