Mam układ ukryty przed widokiem. Po kliknięciu przycisku chcę, aby przesuwał się od dołu, popychając całą zawartość ekranu w górę, bardzo podobnie do tego, jak WhatsApp pokazuje panel emotikonów na ekranie czatu.
Widziałem SlidingDrawer, który nie działa dla mnie. Wymaga obrazu jako uchwytu, który jest pokazany na środku ekranu, nie chcę tego. Przesuwa się również po istniejącej zawartości ekranu, szukam sposobu na przeniesienie istniejącej zawartości w górę.
Aktualizacja 1:
Próbowałem użyć animacji zgodnie z sugestią Sanketa Kachhela. Ale ukryty układ nigdy nie jest pokazywany. Oto kod.
Układ (activity_main.xml):
<RelativeLayout
android:id="@+id/main_screen"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
android:layout_alignParentTop="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
android:layout_centerInParent="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Slide up / down"
android:layout_alignParentBottom="true"
android:onClick="slideUpDown"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/hidden_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/main_screen">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name" />
</RelativeLayout>
Aktywność (MainActivity.java):
package com.example.slideuplayout;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
public class MainActivity extends Activity {
private ViewGroup hiddenPanel;
private boolean isPanelShown;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hiddenPanel = (ViewGroup)findViewById(R.id.hidden_panel);
hiddenPanel.setVisibility(View.INVISIBLE);
isPanelShown = false;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void slideUpDown(final View view) {
if(!isPanelShown) {
// Show the panel
Animation bottomUp = AnimationUtils.loadAnimation(this,
R.anim.bottom_up);
hiddenPanel.startAnimation(bottomUp);
hiddenPanel.setVisibility(View.VISIBLE);
isPanelShown = true;
}
else {
// Hide the Panel
Animation bottomDown = AnimationUtils.loadAnimation(this,
R.anim.bottom_down);
hiddenPanel.startAnimation(bottomDown);
hiddenPanel.setVisibility(View.INVISIBLE);
isPanelShown = false;
}
}
}
Animacje:
bottom_up.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="75%p"
android:toYDelta="0%p"
android:fillAfter="true"
android:duration="500" />
</set>
bottom_down.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0%p"
android:toYDelta="100%p"
android:fillAfter="true"
android:interpolator="@android:anim/linear_interpolator"
android:duration="500" />
</set>
Jakieś pomysły, jak można to zrobić?
Dzięki.
hiddenPanel.bringToFront()
przed rozpoczęciem animacji i sprawdź, czy działa. Daj nam również znać, czy otrzymujesz widok hidden_panel w układzie graficznymactivity_main.xml
?Odpowiedzi:
Użyj tych animacji:
bottom_up.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="75%p" android:toYDelta="0%p" android:fillAfter="true" android:duration="500"/> </set>
bottom_down.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="0%p" android:toYDelta="100%p" android:fillAfter="true" android:interpolator="@android:anim/linear_interpolator" android:duration="500" /> </set>
Użyj tego kodu w swojej aktywności, aby ukryć / animować widok:
źródło
.setVisibility(View.VISIBLE)
uratował mój dzień!Byłeś blisko. Kluczem do sukcesu jest nadmuchanie ukrytego układu
match_parent
zarówno pod względem wzrostu, jak i wagi. Po prostu zacznij jakoView.GONE
. W ten sposób użycie procentu w animatorach działa poprawnie.Układ (activity_main.xml):
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main_screen" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/hello_world" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:onClick="slideUpDown" android:text="Slide up / down" /> <RelativeLayout android:id="@+id/hidden_panel" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:visibility="gone" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_name" android:layout_centerInParent="true" android:onClick="slideUpDown" /> </RelativeLayout> </RelativeLayout>
Aktywność (MainActivity.java):
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; public class OffscreenActivity extends Activity { private View hiddenPanel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); hiddenPanel = findViewById(R.id.hidden_panel); } public void slideUpDown(final View view) { if (!isPanelShown()) { // Show the panel Animation bottomUp = AnimationUtils.loadAnimation(this, R.anim.bottom_up); hiddenPanel.startAnimation(bottomUp); hiddenPanel.setVisibility(View.VISIBLE); } else { // Hide the Panel Animation bottomDown = AnimationUtils.loadAnimation(this, R.anim.bottom_down); hiddenPanel.startAnimation(bottomDown); hiddenPanel.setVisibility(View.GONE); } } private boolean isPanelShown() { return hiddenPanel.getVisibility() == View.VISIBLE; } }
Jedyną inną rzeczą, w której się zmieniłem, była
bottom_up.xml
. Zamiastandroid:fromYDelta="75%p"
Użyłem:
android:fromYDelta="100%p"
Ale to kwestia preferencji, jak sądzę.
źródło
android:zAdjustment="top"
naAnimation
lubAnimtionSet
.Wystarczy dodać jakąś linię do swojej aplikacji, znajdź ją pod poniższym linkiem:
Pokaż i ukryj widok z animacją przesuwania w górę / w dół
Po prostu dodaj animację do swojego układu w następujący sposób:
mLayoutTab.animate() .translationYBy(120) .translationY(0) .setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
źródło
Oto, co ostatecznie zadziałało dla mnie.
Układy:
activity_main.xml
<RelativeLayout android:id="@+id/main_screen" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_alignParentBottom="true"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" android:layout_alignParentTop="true"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" android:layout_centerInParent="true" /> <Button android:id="@+id/slideButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Slide up / down" android:layout_alignParentBottom="true" android:onClick="slideUpDown"/> </RelativeLayout>
hidden_panel.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/hidden_panel" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Test" /> </LinearLayout>
Java: pakiet com.example.slideuplayout;
import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import android.view.animation.AnimationUtils; public class MainActivity extends Activity { private ViewGroup hiddenPanel; private ViewGroup mainScreen; private boolean isPanelShown; private ViewGroup root; int screenHeight = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mainScreen = (ViewGroup)findViewById(R.id.main_screen); ViewTreeObserver vto = mainScreen.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { screenHeight = mainScreen.getHeight(); mainScreen.getViewTreeObserver().removeGlobalOnLayoutListener(this); } }); root = (ViewGroup)findViewById(R.id.root); hiddenPanel = (ViewGroup)getLayoutInflater().inflate(R.layout.hidden_panel, root, false); hiddenPanel.setVisibility(View.INVISIBLE); root.addView(hiddenPanel); isPanelShown = false; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void slideUpDown(final View view) { if(!isPanelShown) { // Show the panel mainScreen.layout(mainScreen.getLeft(), mainScreen.getTop() - (screenHeight * 25/100), mainScreen.getRight(), mainScreen.getBottom() - (screenHeight * 25/100)); hiddenPanel.layout(mainScreen.getLeft(), mainScreen.getBottom(), mainScreen.getRight(), screenHeight); hiddenPanel.setVisibility(View.VISIBLE); Animation bottomUp = AnimationUtils.loadAnimation(this, R.anim.bottom_up); hiddenPanel.startAnimation(bottomUp); isPanelShown = true; } else { isPanelShown = false; // Hide the Panel Animation bottomDown = AnimationUtils.loadAnimation(this, R.anim.bottom_down); bottomDown.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation arg0) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animation arg0) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation arg0) { isPanelShown = false; mainScreen.layout(mainScreen.getLeft(), mainScreen.getTop() + (screenHeight * 25/100), mainScreen.getRight(), mainScreen.getBottom() + (screenHeight * 25/100)); hiddenPanel.layout(mainScreen.getLeft(), mainScreen.getBottom(), mainScreen.getRight(), screenHeight); } }); hiddenPanel.startAnimation(bottomDown); } } }
źródło
Użyj tego układu. Jeśli chcesz animować kurczenie się widoku głównego, musisz dodać animację do wysokości ukrytego paska, kup, może być wystarczająco dobre, aby użyć animacji tłumaczenia na pasku i mieć skok wysokości widoku głównego zamiast animacji.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:id="@+id/main_screen" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/hello_world" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:onClick="slideUpDown" android:text="Slide up / down" /> </RelativeLayout> <RelativeLayout android:id="@+id/hidden_panel" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="#fcc" android:visibility="visible" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_name" /> </RelativeLayout> </LinearLayout>
źródło
Ok, są dwa możliwe podejścia. Najprostszy - to użycie przesuwanej biblioteki menu . Umożliwia tworzenie dolnego przesuwanego menu, może animować górny kontener, aby był widoczny dno, obsługuje zarówno przeciąganie palcem, jak i animację programową za pomocą przycisku (StaticDrawer).
Trudniej - jeśli chcesz korzystać z Animacji, jak już zostało zasugerowane. W przypadku animacji musisz NAJPIERW zmienić układy. Więc spróbuj najpierw zmienić układ do stanu końcowego bez żadnych animacji. Ponieważ jest bardzo prawdopodobne, że nie układasz swoich widoków poprawnie w RelativeLayout, więc nawet jeśli pokazujesz widok z dołu, pozostaje on zasłonięty przez górny. Po poprawnej zmianie layoutu - jedyne co musisz zrobić, to zapamiętać tłumaczenia przed układem i zastosować animację tłumaczenia PO layoucie.
źródło
Mój kod do przesuwania animacji w górę, w dół bez XML
private static ObjectAnimator createBottomUpAnimation(View view, AnimatorListenerAdapter listener, float distance) { ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationY", -distance); // animator.setDuration(???) animator.removeAllListeners(); if (listener != null) { animator.addListener(listener); } return animator; } public static ObjectAnimator createTopDownAnimation(View view, AnimatorListenerAdapter listener, float distance) { view.setTranslationY(-distance); ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationY", 0); animator.removeAllListeners(); if (listener != null) { animator.addListener(listener); } return animator; }
Używanie Do zsuń
createTopDownAnimation(myYellowView, null, myYellowView.getHeight()).start();
Do przesuwania
createBottomUpAnimation(myYellowView, null, myYellowView.getHeight()).start();
źródło
Wypróbuj poniższy kod, jest bardzo krótki i prosty.
transalate_anim.xml
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2013 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="4000" android:fromXDelta="0" android:fromYDelta="0" android:repeatCount="infinite" android:toXDelta="0" android:toYDelta="-90%p" /> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="4000" android:fromAlpha="0.0" android:repeatCount="infinite" android:toAlpha="1.0" /> </set>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.naveen.congratulations.MainActivity"> <ImageView android:id="@+id/image_1" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginBottom="8dp" android:layout_marginStart="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:srcCompat="@drawable/balloons" /> </android.support.constraint.ConstraintLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final ImageView imageView1 = (ImageView) findViewById(R.id.image_1); imageView1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startBottomToTopAnimation(imageView1); } }); } private void startBottomToTopAnimation(View view) { view.startAnimation(AnimationUtils.loadAnimation(this, R.anim.translate_anim)); } }
źródło
Oto rozwiązanie jako rozszerzenie [ https://stackoverflow.com/a/46644736/10249774]
Dolny panel wypycha główną zawartość w górę
https://imgur.com/a/6nxewE0
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/my_button" android:layout_marginTop="10dp" android:onClick="onSlideViewButtonClick" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <LinearLayout android:id="@+id/main_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center_horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="main " android:textSize="70dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="main " android:textSize="70dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="main " android:textSize="70dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="main" android:textSize="70dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="main" android:textSize="70dp"/> </LinearLayout> <LinearLayout android:id="@+id/footer_view" android:background="#a6e1aa" android:orientation="vertical" android:gravity="center_horizontal" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="footer content" android:textSize="40dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="footer content" android:textSize="40dp" /> </LinearLayout> </RelativeLayout>
Główna aktywność:
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.animation.TranslateAnimation; import android.widget.Button; public class MainActivity extends AppCompatActivity { private Button myButton; private View footerView; private View mainView; private boolean isUp; private int anim_duration = 700; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); footerView = findViewById(R.id.footer_view); mainView = findViewById(R.id.main_view); myButton = findViewById(R.id.my_button); // initialize as invisible (could also do in xml) footerView.setVisibility(View.INVISIBLE); myButton.setText("Slide up"); isUp = false; } public void slideUp(View mainView , View footer_view){ footer_view.setVisibility(View.VISIBLE); TranslateAnimation animate_footer = new TranslateAnimation( 0, // fromXDelta 0, // toXDelta footer_view.getHeight(), // fromYDelta 0); // toYDelta animate_footer.setDuration(anim_duration); animate_footer.setFillAfter(true); footer_view.startAnimation(animate_footer); mainView.setVisibility(View.VISIBLE); TranslateAnimation animate_main = new TranslateAnimation( 0, // fromXDelta 0, // toXDelta 0, // fromYDelta (0-footer_view.getHeight())); // toYDelta animate_main.setDuration(anim_duration); animate_main.setFillAfter(true); mainView.startAnimation(animate_main); } public void slideDown(View mainView , View footer_view){ TranslateAnimation animate_footer = new TranslateAnimation( 0, // fromXDelta 0, // toXDelta 0, // fromYDelta footer_view.getHeight()); // toYDelta animate_footer.setDuration(anim_duration); animate_footer.setFillAfter(true); footer_view.startAnimation(animate_footer); TranslateAnimation animate_main = new TranslateAnimation( 0, // fromXDelta 0, // toXDelta (0-footer_view.getHeight()), // fromYDelta 0); // toYDelta animate_main.setDuration(anim_duration); animate_main.setFillAfter(true); mainView.startAnimation(animate_main); } public void onSlideViewButtonClick(View view) { if (isUp) { slideDown(mainView , footerView); myButton.setText("Slide up"); } else { slideUp(mainView , footerView); myButton.setText("Slide down"); } isUp = !isUp; } }
źródło
Możesz zdefiniować główny ekran i drugi ekran, który chcesz przewijać w górę jako fragmenty. Gdy przycisk na głównym ekranie zostanie wciśnięty, fragment wyśle wiadomość do działania, które następnie zastąpi główny ekran tym, który chcesz przewinąć w górę i animuje zastąpienie.
źródło