Android thêm hình động đơn giản trong khi setvisibility (view.Gone)


237

Tôi đã thiết kế một bố cục đơn giản. Tôi đã hoàn thành thiết kế mà không có hoạt hình, nhưng bây giờ tôi muốn thêm hình ảnh động khi sự kiện nhấp vào textview và tôi không biết cách sử dụng nó. Thiết kế xml của tôi có tốt hay không? Mọi lơi đê nghị đêu nên được đanh gia cao.

XML của tôi

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:longClickable="false"
    android:orientation="vertical"
    android:weightSum="16" >

<LinearLayout 
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#00DDA0"
    android:layout_weight="3" >
</LinearLayout>
 <TextView
        android:id="@+id/Information1"
        android:layout_width="match_parent"
        android:layout_height="1dp" 
        android:text="Child Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>

 <LinearLayout
     android:id="@+id/layout1"
     android:layout_width="fill_parent"
     android:layout_height="0dp"
     android:layout_weight="8.5"
     android:background="#BBBBBB"
     android:orientation="vertical" >

     <TextView
         android:id="@+id/textView1"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
 </LinearLayout>

  <TextView
        android:id="@+id/Information2"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Parent Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
  <LinearLayout 
          android:id="@+id/layout2"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView2"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
   <TextView
        android:id="@+id/Information3"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Siblings" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
   <LinearLayout 
          android:id="@+id/layout3"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView3"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
    <TextView
        android:id="@+id/Information4"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Teacher Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
    <LinearLayout 
          android:id="@+id/layout4"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView4"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
     <TextView
        android:id="@+id/Information5"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Grade Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
     <LinearLayout 
          android:id="@+id/layout5"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
      <TextView
        android:id="@+id/Information6"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Health Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
      <LinearLayout 
          android:id="@+id/layout6"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
    <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" 
         android:layout_weight="8.5" />
      </LinearLayout>

</LinearLayout>

Java của tôi

public class Certify_Info extends Activity {

    private static TextView tv2,tv3,tv5,tv6,tv4,tv1;
    private static LinearLayout l1,l2,l3,l4,l5,l6;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_certify__info);

        tv1=(TextView) findViewById(R.id.Information1);
        tv2=(TextView) findViewById(R.id.Information2);
        tv3=(TextView) findViewById(R.id.Information3);
        tv4=(TextView) findViewById(R.id.Information4);
        tv5=(TextView) findViewById(R.id.Information5);
        tv6=(TextView) findViewById(R.id.Information6); 

        l1=(LinearLayout) findViewById(R.id.layout1);
        l2=(LinearLayout) findViewById(R.id.layout2);
        l3=(LinearLayout) findViewById(R.id.layout3);
        l4=(LinearLayout) findViewById(R.id.layout4);
        l5=(LinearLayout) findViewById(R.id.layout5);
        l6=(LinearLayout) findViewById(R.id.layout6); 

        l2.setVisibility(View.GONE);
        l3.setVisibility(View.GONE); 
        l4.setVisibility(View.GONE); 
        l5.setVisibility(View.GONE);
        l6.setVisibility(View.GONE);

        tv1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l1.setVisibility(View.VISIBLE);
            }
        });
        tv2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l2.setVisibility(View.VISIBLE);
            }
        });
        tv3.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l3.setVisibility(View.VISIBLE);

            }
        });
        tv4.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l4.setVisibility(View.VISIBLE); 
            }
        });
        tv5.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l6.setVisibility(View.GONE);
                l5.setVisibility(View.VISIBLE); 
            }
        });
        tv6.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.VISIBLE);
            }
        });

    }
}

Câu trả lời:


703

Bạn có thể thực hiện hai điều để thêm hình ảnh động, đầu tiên bạn có thể để Android thay đổi bố cục cho bạn. Bằng cách đó, mỗi khi bạn thay đổi thứ gì đó trong bố cục như thay đổi mức độ hiển thị của chế độ xem hoặc xem vị trí, android sẽ tự động tạo hiệu ứng mờ dần / chuyển tiếp. Để sử dụng bộ đó

android:animateLayoutChanges="true"

trên nút gốc trong bố trí của bạn.

Tùy chọn thứ hai của bạn sẽ là thêm hình ảnh động theo cách thủ công. Để làm điều này, tôi khuyên bạn nên sử dụng API hoạt hình mới được giới thiệu trong Android 3.0 (Honeycomb). Tôi có thể cho bạn một vài ví dụ:

Điều này mất dần View:

view.animate().alpha(0.0f);

Điều này làm mờ nó trở lại trong:

view.animate().alpha(1.0f);

Điều này di chuyển Viewxuống theo chiều cao của nó:

view.animate().translationY(view.getHeight());

Điều này trả về Viewvị trí bắt đầu của nó sau khi nó đã được chuyển đi nơi khác:

view.animate().translationY(0);

Bạn cũng có thể sử dụng setDuration()để đặt thời lượng của hình ảnh động. Ví dụ: điều này mất dần Viewtrong khoảng thời gian 2 giây:

view.animate().alpha(0.0f).setDuration(2000);

Và bạn có thể kết hợp bao nhiêu hình động tùy thích, ví dụ như điều này mờ dần a Viewvà di chuyển nó xuống cùng một lúc trong khoảng thời gian 0,3 giây:

view.animate()
        .translationY(view.getHeight())
        .alpha(0.0f)
        .setDuration(300);

Và bạn cũng có thể chỉ định một người nghe cho hình ảnh động và phản ứng với tất cả các loại sự kiện. Giống như khi hoạt hình bắt đầu, khi nó kết thúc hoặc lặp lại, v.v. Bằng cách sử dụng lớp trừu tượng, AnimatorListenerAdapterbạn không phải thực hiện tất cả các cuộc gọi lại AnimatorListenercùng một lúc mà chỉ những người bạn cần. Điều này làm cho mã dễ đọc hơn. Ví dụ, đoạn mã sau làm mờ đi một Viewbước di chuyển xuống theo chiều cao của nó trong khoảng thời gian 0,3 giây (300 mili giây) và khi hoạt ảnh hoàn thành, khả năng hiển thị của nó được đặt thành View.GONE.

view.animate()
        .translationY(view.getHeight())
        .alpha(0.0f)
        .setDuration(300)
        .setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                view.setVisibility(View.GONE);
            }
        });

6
@Natix Tôi sẽ không gọi siêu dự phòng đó. Đừng chỉnh sửa bề ngoài không có gì sai.
Xaver Kapeller

5
Là tốt nhưng nghịch đảo không hoạt động chính xác tại sao? view.setVisibility (View.VISIBLE); VỚI alpha (1.0f), xuất hiện với 100 phần đệm trên cùng ...
delive

15
Phải xóa hình ảnh động trước khi đặt chế độ hiển thị >> view.clearAnimation(); view.setVisibility(View.GONE);nếu không bố cục sẽ vẫn ẩn và không biến mất.
Eftekhari

2
@Eftekhari Họ không chuyên sâu về tài nguyên. Và nếu bạn có một phiên bản Android cập nhật, nhưng vẫn bị lag hơn bạn có thể có một chiếc điện thoại cũ hơn với bộ nhớ thấp hoặc chip đồ họa xấu. Và tôi không nói về một thư viện mới. Các họa sĩ hoạt hình là người bản địa. Chúng là một phần của Khung Android. Chúng đã được phát hành 5 năm trước và ngày nay 97,9% tất cả các thiết bị hỗ trợ chúng. Không có lý do gì để không sử dụng Animators hoặc ít nhất ViewCompat.animate()là một phần của thư viện hỗ trợ và sử dụng Animators trên các phiên bản mới hơn và Xem Animations trên Android 3.0 trở xuống.
Xaver Kapeller

1
Nhưng khi 97,9% tất cả các thiết bị là Android 4.0 trở lên thì không còn nhiều usecase để lại ViewCompat.animate().
Xaver Kapeller

69

Cách dễ nhất để Visibilitythay đổi hoạt hình là sử dụng gói Transition APIcó sẵn trong gói hỗ trợ (androidx). Chỉ cần gọi TransitionManager.beginDelayedTransitionphương thức sau đó thay đổi tầm nhìn của chế độ xem. Có một số chuyển tiếp mặc định như Fade, Slide.

import androidx.transition.TransitionManager;
import androidx.transition.Transition;
import androidx.transition.Fade;

private void toggle() {
    Transition transition = new Fade();
    transition.setDuration(600);
    transition.addTarget(R.id.image);

    TransitionManager.beginDelayedTransition(parent, transition);
    image.setVisibility(show ? View.VISIBLE : View.GONE);
}

Cha parentmẹ ViewGroupcủa xem hoạt hình ở đâu. Kết quả:

nhập mô tả hình ảnh ở đây

Đây là kết quả của Slidequá trình chuyển đổi:

import androidx.transition.Slide;

Transition transition = new Slide(Gravity.BOTTOM);

nhập mô tả hình ảnh ở đây

Thật dễ dàng để viết chuyển đổi tùy chỉnh nếu bạn cần một cái gì đó khác nhau. Đây là ví dụ CircularRevealTransitionmà tôi đã viết trong một câu trả lời khác . Nó hiển thị và ẩn chế độ xem với hình ảnh động tròn tròn.

Transition transition = new CircularRevealTransition();

nhập mô tả hình ảnh ở đây

android:animateLayoutChanges="true"tùy chọn này cũng tương tự, nó chỉ sử dụng AutoTransition làm quá trình chuyển đổi.


@TouhidulIslam không. Lớp này có sẵn trong gói androidx. Mọi thứ đều tương thích ngược
ashakirov

2
Điều gì về việc mở rộng / thu gọn một nhóm xem?
TheRealChx101

Bạn có thể làm nhiều beginDelayedTransitions?
Jeongbebs

26

Vui lòng kiểm tra liên kết này . Điều này sẽ cho phép các hình ảnh động như hình ảnh động L2R, R2L, T2B, B2T.

Mã này hiển thị hình ảnh động từ trái sang phải

TranslateAnimation animate = new TranslateAnimation(0,view.getWidth(),0,0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
view.setVisibility(View.GONE);

Nếu bạn muốn làm điều đó từ R2L thì hãy sử dụng

TranslateAnimation animate = new TranslateAnimation(0,-view.getWidth(),0,0);

từ trên xuống dưới như

TranslateAnimation animate = new TranslateAnimation(0,0,0,view.getHeight());

và ngược lại ..


8
Điều này thay thế quan điểm từ vị trí ban đầu của nó.
Relm

24

Hãy thử thêm dòng này vào bố trí cha mẹ xml

 android:animateLayoutChanges="true"

Bố cục của bạn sẽ trông như thế này

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:longClickable="false"
    android:orientation="vertical"
    android:weightSum="16">

    .......other code here

    </LinearLayout>

Điều này làm việc cho tôi. Thiết lập của tôi sử dụng một bố cục ràng buộc như chế độ xem gốc. Khi chế độ xem được đặt thành View.VISIBLE, hình động được hiển thị
EdgeDev

giải pháp rất đơn giản và thanh lịch
Naveed Ahmad

11

Dựa trên câu trả lời của @Xaver Kapeller, tôi đã tìm ra cách tạo hoạt hình cuộn khi các chế độ xem mới xuất hiện trên màn hình (và cả hoạt hình để ẩn chúng).

Nó đi từ trạng thái này:

  • Cái nút
  • Nút cuối cùng

đến

  • Cái nút
  • Nút 1
  • Nút 2
  • Nút 3
  • Nút 4
  • Nút cuối cùng

và ngược lại.

Vì vậy, khi người dùng nhấp vào nút đầu tiên, các yếu tố "Nút 1", "Nút 2", "Nút 3" và "Nút 4" sẽ xuất hiện bằng cách sử dụng hình ảnh động mờ dần và phần tử "Nút cuối cùng" sẽ di chuyển xuống cho đến khi kết thúc. Chiều cao của bố cục cũng sẽ thay đổi, cho phép sử dụng chế độ xem cuộn đúng cách.

Đây là mã để hiển thị các yếu tố với hình ảnh động:

private void showElements() {
    // Precondition
    if (areElementsVisible()) {
        Log.w(TAG, "The view is already visible. Nothing to do here");
        return;
    }

    // Animate the hidden linear layout as visible and set
    // the alpha as 0.0. Otherwise the animation won't be shown
    mHiddenLinearLayout.setVisibility(View.VISIBLE);
    mHiddenLinearLayout.setAlpha(0.0f);
    mHiddenLinearLayout
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .alpha(1.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    updateShowElementsButton();
                    mHiddenLinearLayout.animate().setListener(null);
                }
            })
    ;

    mLastButton
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .translationY(mHiddenLinearLayoutHeight);

    // Update the high of all the elements relativeLayout
    LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();

    // TODO: Add vertical margins
    layoutParams.height = mLastButton.getHeight() + mHiddenLinearLayoutHeight;
}

và đây là mã để ẩn các thành phần của hình ảnh động:

private void hideElements() {
    // Precondition
    if (!areElementsVisible()) {
        Log.w(TAG, "The view is already non-visible. Nothing to do here");
        return;
    }

    // Animate the hidden linear layout as visible and set
    mHiddenLinearLayout
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .alpha(0.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    Log.v(TAG, "Animation ended. Set the view as gone");
                    super.onAnimationEnd(animation);
                    mHiddenLinearLayout.setVisibility(View.GONE);
                    // Hack: Remove the listener. So it won't be executed when
                    // any other animation on this view is executed
                    mHiddenLinearLayout.animate().setListener(null);
                    updateShowElementsButton();
                }
            })
    ;

    mLastButton
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .translationY(0);

    // Update the high of all the elements relativeLayout
    LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();

    // TODO: Add vertical margins
    layoutParams.height = mLastButton.getHeight();
}

Lưu ý có một cách hack đơn giản về phương thức để ẩn hình ảnh động. Trên trình nghe hoạt hình mHiddenLinearLayout, tôi đã phải loại bỏ trình nghe bằng cách sử dụng:

mHiddenLinearLayout.animate().setListener(null);

Điều này là do một khi trình nghe hoạt hình được gắn vào một khung nhìn, lần tiếp theo khi bất kỳ hoạt ảnh nào được thực thi trong khung nhìn này, thì trình nghe cũng sẽ được thực thi. Đây có thể là một lỗi trong trình nghe hoạt hình.

Mã nguồn của dự án là trên GitHub: https://github.com/jiahaoliuliu/ViewsAnimated

Chúc mừng mã hóa!

Cập nhật : Đối với bất kỳ trình nghe nào được đính kèm với các khung nhìn, nó sẽ bị xóa sau khi hoạt ảnh kết thúc. Điều này được thực hiện bằng cách sử dụng

view.animate().setListener(null);

Đây là câu trả lời hay nhất
Naveen Kumar M

1
Các view.animate().setListener(null);tuyên bố đã cứu ngày của tôi. Đây chắc chắn là một lỗi.
Michal Vician

@MichalVician Vui mừng vì đã làm!
jiahao

8

Tôi đã có thể hiển thị / ẩn một menu theo cách này:

MenuView.java (mở rộng FrameLayout)

private final int ANIMATION_DURATION = 500;

public void showMenu()
{
    setVisibility(View.VISIBLE);
    animate()
            .alpha(1f)
            .setDuration(ANIMATION_DURATION)
            .setListener(null);
}

private void hideMenu()
{
    animate()
            .alpha(0f)
            .setDuration(ANIMATION_DURATION)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    setVisibility(View.GONE);
                }
            });
}

Nguồn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.