Ich befülle ein Layout, um es auf dem Bildschirm anzuzeigen. Jetzt möchte ich dieses Layout teilweise vom Bildschirm verschieben. Ich habe das mit .animate().translationX(-500)
auf dem überhöhten Layout versucht. Es bewegte sich außerhalb des Bildschirms genau, wie ich es wollte aussehen:Bewegen von aufgeblasenem Layout/Ansicht an einer neuen Position auf eine animierte Art und Weise
Bevor:
Nach:
Aber jetzt habe ich das Problem, dass die Bereich, den das Layout ursprünglich belegt hat, ist nicht anklickbar (z. B. kann nur zwischen Homescreens wischen) arbeitet außerhalb des blau markierten Bereichs).
Wie kann ich lösen, dass, so blauer Bereich ist anklickbar nach dem Umzug, aber der remaing Bereich des Layout (roten Bereichs) könnte noch Klicks registrieren (zB wenn ich es wollte, um zurück mit einem onClickListener)? Ich denke, ich muss mit updateViewLayout()
Funktion der windowManager
arbeiten, aber ich weiß nicht, was ich bezüglich der Parameter ändern sollte.
Edit 1:
Hier ist der Code. Die Übersetzung wird durch den Button ausgelöst:
overlay.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#d8ff0000"
android:weightSum="1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="245dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Lorem ipsum "
android:id="@+id/textView6"
android:layout_marginLeft="10dp" />
<Button
android:layout_width="55dp"
android:layout_height="wrap_content"
android:text="X"
android:id="@+id/button"
android:layout_gravity="center_horizontal|top"
android:layout_alignParentTop="true"
android:layout_toEndOf="@+id/textView6"
android:layout_marginStart="27dp" />
</RelativeLayout>
</LinearLayout>
Dienst, die das Layout aufbläst:
OverlayService.java
public class FloatingMenu extends Service{
private WindowManager wm;
private LinearLayout ll;
private boolean isPushedToSide = true;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
ll = new LinearLayout(this);
LinearLayout.LayoutParams llParameters = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
ll.setBackgroundColor(Color.argb(50, 255, 255, 255));
ll.setLayoutParams(llParameters);
final WindowManager.LayoutParams parameters = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
parameters.gravity = Gravity.LEFT | Gravity.TOP;
LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
ll = (LinearLayout) li.inflate(R.layout.overlay, null);
final Button b = (Button) ll.findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (isPushedToSide) {
ll.animate().translationX(0);
isPushedToSide = false;
}else {
ll.animate().translationX(-450);
isPushedToSide = true;
}
}
});
wm.addView(ll, parameters);
}
}
Edit 2:
Während meiner Forschung fand ich heraus, dass .animate().translationX()
nur die Position verschiebt, wo die Ansicht gerendert wird und nicht die Ansicht selbst. Das erklärt auch, warum nach der Verwendung von .animate().translationX()
das onclick-Ereignis immer noch an der gleichen Position ausgelöst wird, wie vor dem "Verschieben" des Layouts.
Jetzt muss ich eine Möglichkeit finden, die tatsächliche Ansicht zu meiner gewünschten Position zu verschieben, die mit einer Animation kombiniert wird. Irgendwelche Ideen, wie man das macht?
bearbeiten 3: ich viele Beiträge mit ähnlichen Problemen gefunden und wenn ich richtig die Lösung für das Problem bin ist ObjectAnimator
statt .animate().translationX()
verwenden. Ich habe versucht, zu ersetzen, dass ein Teil in meinem Code, so dass die onClickListener
sieht nun wie folgt aus:
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (isPushedToSide) {
//ll.animate().translationX(0);
ObjectAnimator.ofFloat(ll, "translationX", 0).setDuration(250).start();
isPushedToSide = false;
}else {
//ll.animate().translationX(-450);
ObjectAnimator.ofFloat(ll, "translationX", -450).setDuration(250).start();
isPushedToSide = true;
}
}
});
ll
ist die Linearlayout ich aufgeblasen haben, mit dem Lorem ipsum
Text und Button
. Wieder funktioniert die Animation selbst, verhält sich aber immer noch genauso. Ich muss immer noch auf die ursprüngliche Position der Taste klicken, um die onClickListener
auszulösen und der blaue Bereich ist immer noch nicht anklickbar.
bearbeiten 4:
war der Vorschlag auszuprobieren .invalidate()
zu verwenden, um die aktuelle Position zu aktualisieren. Es hat jedoch nicht funktioniert. Ich bin mir nicht sicher, ob es richtig verwendet wurde.
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (isPushedToSide) {
//ll.animate().translationX(0);
ObjectAnimator.ofFloat(ll, "translationX", 0).setDuration(250).start();
ll.invalidate();
isPushedToSide = false;
}else {
//ll.animate().translationX(-450);
ObjectAnimator.ofFloat(ll, "translationX", -450).setDuration(250).start();
ll.invalidate();
isPushedToSide = true;
}
}
});
ich auch versucht, den x-Wert von LayoutParams
ändern und ruft wm.updateViewLayou(ll, updatedParameters)
, was in Ordnung war. Wenn ich das Overlay 100px nach rechts verschoben habe, wird der Bereich, der onClickListener
auslöst, ebenfalls um 100px nach rechts geschoben. Das Problem ist, dass ich das Overlay nur innerhalb der Grenzen des eigentlichen Bildschirms bewegen konnte und dass ich es vom Bildschirm entfernen muss. Tied negative Werte, aber das hat auch nicht funktioniert.
Was ich im Wesentlichen brauche, ist eine Schublade Navigation, aber mit einer begrenzten Höhe (zumindest das ist denke ich, was ich brauche). Ich werde sehen, ob ich so etwas richtig machen kann.
Edit 5:
Korrigierte mein Code, so dass .inflate()
aufgerufen wird, wenn die Animation beendet hat, aber es verhält sich immer noch die gleiche Art und Weise:
ObjectAnimator anim = ObjectAnimator.ofFloat (ll „translationX ", 0) .setDuration (250);
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {}
@Override
public void onAnimationEnd(Animator animator) {
b.invalidate();
text.invalidate();
frame.invalidate();
ll.invalidate();
}
@Override
public void onAnimationCancel(Animator animator) {}
@Override
public void onAnimationRepeat(Animator animator) {}
});
anim.start();
Ich habe auch zwei .gifs aufgezeichnet, die das Problem zeigen. Ich setze die gravity
auf CENTER
auf die zweite.
Aber würde diese Methode immer noch den gesamten Inhalt des Layouts anzeigen, nur zusammengedrückt, um die neue Breite anzupassen? – 0x1234
ja, es wird die Größe Ihres Layouts ändern, Sie müssen einen Teil Ihres Layouts verstecken? Können Sie bitte das Code-Schnipsel zeigen? Animationsteil – dosssik
Ja, wenn ich nur die width -Eigenschaft ändern würde, würde es nicht gut aussehen, wenn ich später Inhalt hinzufüge. Ich werde meinen Code später zum Start-Post hinzufügen. – 0x1234