Shape - Darstellungsfehler beim Fokus (mehrfaches Überzeichnen?)

  • Antworten:9
  • OffenNicht stickyNicht beantwortet
  • Forum-Beiträge: 53

12.10.2017, 15:30:20 via Website

Hallo,

ich bins mal wieder. Mir fiel kein besserer Titel ein, sorry.

Bei einem EditFeld habe ich folgenden Shape als Hintergrund:

<shape xmlns:android="..."
android:shape="rectangle" >
<stroke android:width="3dp"
    android:color="@color/color_main_black"/>

<corners android:bottomLeftRadius="5dp"
    android:topLeftRadius="5dp"
    android:bottomRightRadius="5dp"
    android:topRightRadius="5dp" />

<gradient android:startColor="#c8000000"
    android:endColor="#c8000000"
    android:angle="90"/>
</shape>

Hab zur besseren Sicht des Problems gleiche Farben genommen.
Es wird richtig angezeigt. Sobald ich allerdings mit dem Fokus im EditFeld bin, kommt es zu einem Darstellungsfehler (An den Rändern bilden sich "Striche". Es sieht für mich so aus, als würde der Hintergrund immer und immer wieder "drauf"-gezeichnet werden, denn der Fehler wird mit der Zeit immer deutlicher).

Im folgenden Bild ist oben der normale Zustand, unten der Zustand, wenn ich das EditFeld selektiere und ein paar Sekunden warte (baut sich sozusagen immer weiter auf).
EDIT: Kann leider kein Bild und auch kein Link anhängen. Hoffe ihr habt trotzdem verstanden, was das Problem ist.

Kann mir jemand sagen, wo da der Fehler liegt? Ich komme nicht drauf und für google scheinen mir offensichtlich die "passenden" Suchwörter nicht einzufallen, oder das Problem ist nicht bekannt...

Antworten
  • Forum-Beiträge: 53

30.10.2017, 13:47:26 via Website

Ich habe jetzt auch mal bischen in den Entwicklerwerkzeugen in Android geschaut.
Bei "Update mit GPU-Ansicht" ist jetzt schön zu sehen, das mein Editfeld bei jedem Cursor-Blink geupdated wird.
Nur wieso wird es nicht neu, sondern "erneut drauf" gezeichnet, so das mein Shape immer und immer weiter "überlappt"?

Ich habe zum Testen mal "setCursorVisible(false)" gesetzt. Damit erhalte ich das Problem nicht, da ja kein Cursor blinkt und somit kein Update "notwendig" ist.
Wenn ich jetzt etwas eingebe, so zeigt mir die aktive Entwickleroption nach jedem eingegebenen Buchstaben ein "Update" an, was wieder zu besagtem Problem führt.

Weiß da jemand weiter?
- Warum ist bei jedem Cursor-Blinken und bei jedem Buchstaben ein Update des Background notwendig?
- Warum wird der Background nicht einfach NEU gezeichnet? Er wird quasi einfach NEU DRAUFGEZEICHNET, was zu meinem Problem führt.

Ich meine, das ist doch kein Standardverhalten, oder? Ich weiß einfach nicht weiter.
Ich habs auch mal mit Java direkt versucht, also kein XML

GradientDrawable retGD = new GradientDrawable();

retGD.setColor(colorBackground);
retGD.setCornerRadii(finalCornorRadius);
retGD.setStroke(strokeWidth, colorStroke);

Aber auch da das gleiche.

Ist es bei euch denn wirklich anders?
Wenn ihr ein Hintergrund bei einem Editfeld setzt, bekommt ihr keinen solchen Fehler?

Übrigens hab ich's auch mal mit anderen Steuerelementen getestet. Habe einen Button mit einem solchen Hintergrund versehen, dabei verschiedene Drawables für die Zustände (normal, gedrückt).
Wenn ich jetzt auf den Button drücke, aber noch nicht loslasse sondern meinen Finger zur Seite weg vom Button schiebe,
so wird ja logischerweise erst der gedrückte Zustand gezeichnet, dann (nachdem Finger zur Seite) wieder der normale Zustand.
Wenn ich es nun paar mal hintereinander mache, so kommt auch beim Button-Hintergrund der gleiche Fehler.

Hat da jemand einen Rat?

Antworten
  • Forum-Beiträge: 53

01.11.2017, 13:10:20 via Website

Vielleicht werd ich jetzt langsam verrückt, aber irgendwie sehen die "Linien" am Rand so aus,
als wären es "9-Patch-Linien".
Wenn ich in meinem Shape den Radius der Ecken vergrößere, so sind auch diese Linien kleiner.

Falls ihr nicht genau verstanden habt, was das Problem ist, auf folgendem Bild sieht mans:
image

Oben: Der normale Zustand
Unten: Der Zustand nach ein paar Sekunden, wenn ich im Editfeld Fokus habe...

Das Problem tritt übrigens überall auf.
Ich habe es mal als Hintergrund für Buttons, Editfelder und Items in einer RV gesetzt, überall das gleiche.
Wenn ich z.B. das Item-Layout einer RV mit diesem Shape versehe und dann durch die RV scrolle, so
entstehen auch da die genannten Linien.

Ich weiss einfach nicht mehr weiter...

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

01.11.2017, 13:30:08 via Website

Hmm, ich hab bisher kaum mit Shapes etc. gearbeitet, dewegen kann ich dazu nichts sagen..
scheint aber so, als gäbe es hier massive Render Fehler.. - was bei solchen spezifischen Fragen helfen könnte, wäre StackOverflow. Da schon einmal nachgesehen?
Hast du das auch schon auf mehreren Geräten getestet? Vlt, liegt es am Gerät (Firmware/Rom/Hersteller etc..)?

Ansonsten kannst du mal probieren, das nicht über Sapes zu machen, sondern dir ein Eigenes View bauen, dass deinen Aunforderungen entspricht, aber das wird es wohl nicht besser machen...

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

Antworten
  • Forum-Beiträge: 2.907

01.11.2017, 13:47:29 via Website

Hallo Next User,

Shapes ( ob XML oder Coded ) in einem EditFeld sind Hardware und System-abhängig.
Du wirst überall verschiedene Ergebnisse sehen.

Das habe ich auch schon festgestellt und deswegen umgehe ich Custom-EditFields und arbeite
bei den restlichen Elementen auch nur noch via Code zur Runtime.

Es gibt allerdings ein Workaround :

Erstelle dir eine abgleitete Klasse und rendere (zu Fuss) in onDraw.
Dabei musst du auch den Cursor Zustand berücksichtigen.

Hier ein Grund-Beispiel
https://github.com/alphamu/PinEntryEditText/blob/master/pinentryedittext/src/main/java/com/alimuzaffar/lib/pin/PinEntryEditText.java

.
.
Wenn alles nicht hilft , erstelle dir einen Hintergrund und setze ein standard - transparentes Edit darauf.
(Layer basierend)

— geändert am 01.11.2017, 14:10:25

Liebe Grüße - Stefan
[ App - Entwicklung ]

Antworten
  • Forum-Beiträge: 53

01.11.2017, 14:13:53 via Website

Hi,

vielen dank für die schnellen Antworten. Werde ich mir heute Abend näher anschauen.

@Pascal:
Was genau meinst du mit eigener View? Ich nutze diese Form (ob XML oder Java) als Hintergrund einer View.

@Swa00
Gut, bei Editfeldern kann ich es ja noch verstehen, das da vielleicht Unterschiede im Ergebniss entstehen, wobei
ich ehrlich gesagt dachte, das z.B. eine Erstellung mittels "GradientDrawable" einheitlich wäre.
Außerdem hatte ich ja erwähnt, das das Problem anscheinend unabhängig des Objekts (Editfeld, Button, Item in RV, ...) auftretet.

Naja, werde heute Abend wieder mehr Zeit haben.

Antworten
  • Forum-Beiträge: 2.907

01.11.2017, 14:21:40 via Website

Also das es bei anderen Elementen nicht funktioniert , kann ich nicht nachvollziehen .
Ich denke , da vergisst du was

Hier mal ein paar Snipets von mir

///////////////////////////////////////////////////////////////////////////////
public void setImageDrawableByColor (ImageView v, int Resource, int color)
{
Drawable IconNext;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
IconNext = mActivity.getResources().getDrawable(Resource);
else
IconNext = mActivity.getResources().getDrawable(Resource,null);
IconNext.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
v.setImageDrawable(IconNext);
}
public void setCheckBoxColor (CheckBox check, int normal, int checked)
{
int states[][] = {{android.R.attr.state_checked}, {}};
int colors[] = {normal,checked};
CompoundButtonCompat.setButtonTintList(check, new ColorStateList(states, colors));
}
///////////////////////////////////////////////////////////////////////////////
public void setRadioButtonColor (RadioButton radio, int normal, int checked)
{
if(Build.VERSION.SDK_INT>=21)
{
ColorStateList colorStateList = new ColorStateList(new int[][]{new int[]{-android.R.attr.state_enabled}, //disabled
new int[]{android.R.attr.state_enabled}},
new int[]{normal, checked});
radio.setButtonTintList(colorStateList);//set the color tint list
radio.invalidate(); //could not be necessary
}
}
///////////////////////////////////////////////////////////////////////////////
public void setSwitchColor (Switch sw, int color)
{
sw.getThumbDrawable().setColorFilter(color, PorterDuff.Mode.MULTIPLY);
sw.getTrackDrawable().setColorFilter(color, PorterDuff.Mode.MULTIPLY);
}
///////////////////////////////////////////////////////////////////////////////
public void setRoundedButton (Button btn, int fillcolor, int strokecolor, int textcolor)
{
btn.setBackgroundResource(R.drawable.global_round_corner_button);
btn.setPadding(0, 0, 0, 0);
btn.setTextColor(textcolor);
btn.setTextSize(16);
btn.setTransformationMethod(null);
btn.setGravity(Gravity.CENTER_HORIZONTAL| Gravity.CENTER_VERTICAL);
btn.setTypeface(FONT);
GradientDrawable bgShapeic = (GradientDrawable)btn.getBackground();
bgShapeic.setColor (fillcolor);
bgShapeic.setStroke(2,strokecolor);
bgShapeic.setCornerRadius((float)50);
}

Liebe Grüße - Stefan
[ App - Entwicklung ]

Antworten
  • Forum-Beiträge: 2.907

01.11.2017, 14:24:55 via Website

image

............

Liebe Grüße - Stefan
[ App - Entwicklung ]

Antworten
  • Forum-Beiträge: 53

02.11.2017, 13:07:48 via Website

@swa00
Ich hab grad mal einfach einen simplen Button mit einem ImageButton verglichen.
Beide habe ich normal im Layout (XML) erstellt und die weiter oben bereits erwähnte
GradientDrawable als Hintergrund gesetzt.
Die Buttons haben keine Funktion, sodass ich sie immer wieder anklicken kann.

Im folgenden Bild sind links die normalen Zustände und rechts die Zustände nach ein paar Klicks.
image
Bei normalen Buttons tritt der Fehler offenbar nicht auf.
Jetzt frag ich mich aber, warum er bei ImageButtons kommt.

Außerdem, ich habe eine Liste mit Items erstellt. Den ItemContainer (RelativeLayout im Item-Layout) versehe
ich mit einem Hintergrund. Wenn ich die Liste jetzt bischen hin und her scrolle, so entstehen seitlich auch
solche Linien. Die bewegen sich allerdings nicht mit.
Das könnt ihr euch so vorstellen, das die Linien im rechten Bild beim ImageButton konstant auf der Stelle bleiben,
der Button selber einer der Items wäre, welches man hoch und runter scrollen kann.

Antworten

Empfohlene Artikel