2016-07-07 3 views
5

LinearLayout 내부에 Recyclerview 및 기타 요소가있는 화면이 있습니다. 문제는 RecyclerView 항목을 제거 할 때 animateLayoutChanges가이 경우 작동하지 않는다는 것입니다. 왜 이런 일이 일어날 지 알지?AnimateLayoutChanges가 RecyclerView에서 작동하지 않습니다.

Demo

XML 잠시 후

<LinearLayout 
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.example.alvaro.resizetest.MainActivity"> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:animateLayoutChanges="true" 
    android:orientation="vertical"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/recyclerview" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

    <LinearLayout 
     android:id="@+id/test1" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:background="@color/colorAccent" 
     android:gravity="center_vertical"> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="LinearLayout" 
      android:textColor="#FFFFFF" 
      android:textSize="22sp"/> 
    </LinearLayout> 


    <LinearLayout 
     android:id="@+id/test2" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:background="@color/colorPrimaryDark" 
     android:gravity="center_vertical"> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="LinearLayout" 
      android:textColor="#FFFFFF" 
      android:textSize="22sp"/> 
    </LinearLayout> 


    <LinearLayout 
     android:id="@+id/test3" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:background="@color/colorAccent" 
     android:gravity="center_vertical"> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="LinearLayout" 
      android:textColor="#FFFFFF" 
      android:textSize="22sp"/> 
    </LinearLayout> 


    <LinearLayout 
     android:id="@+id/test4" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:background="@color/colorPrimaryDark" 
     android:gravity="center_vertical"> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="LinearLayout" 
      android:textColor="#FFFFFF" 
      android:textSize="22sp"/> 
    </LinearLayout> 


</LinearLayout> 

JAVA

public class MainActivity extends AppCompatActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview); 

    Adapter adapter = new Adapter(); 

    recyclerView.setLayoutManager(new LinearLayoutManager(this)); 
    recyclerView.setAdapter(adapter); 
    recyclerView.setNestedScrollingEnabled(true); 

    View.OnClickListener listener = new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      view.setVisibility(View.GONE); 
     } 
    }; 

    findViewById(R.id.test1).setOnClickListener(listener); 
    findViewById(R.id.test2).setOnClickListener(listener); 
    findViewById(R.id.test3).setOnClickListener(listener); 
    findViewById(R.id.test4).setOnClickListener(listener); 

} 


class Adapter extends RecyclerView.Adapter<Adapter.Holder>{ 

    int size = 3; 

    public Adapter() { 
    } 

    @Override 
    public Holder onCreateViewHolder(ViewGroup parent, int viewType) { 

     View view = getLayoutInflater().inflate(R.layout.item, parent, false); 

     return new Holder(view); 
    } 

    @Override 
    public void onBindViewHolder(Holder holder, int position) { 

    } 

    @Override 
    public int getItemCount() { 
     return size; 
    } 

    class Holder extends RecyclerView.ViewHolder { 

     public Holder(final View itemView) { 
      super(itemView); 

      itemView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        size --; 
        notifyItemRemoved(getAdapterPosition()); 
       } 
      }); 

     } 
    } 
} 

답변

5

나는 해결책을 얻었다. 나는 recyclerView 높이에 애니메이션을 적용하는 함수를 만들었습니다.

enter image description here

JAVA

public class MainActivity extends AppCompatActivity { 

private final String TAG = MainActivity.class.getSimpleName(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview); 

    Adapter adapter = new Adapter(recyclerView); 

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this) { 
     @Override 
     public boolean canScrollVertically() { 
      return false; 
     } 
    }; 

    recyclerView.setLayoutManager(linearLayoutManager); 
    recyclerView.setAdapter(adapter); 
    recyclerView.setNestedScrollingEnabled(true); 

    View.OnClickListener listener = new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      view.setVisibility(View.GONE); 
     } 
    }; 

    findViewById(R.id.test1).setOnClickListener(listener); 
    findViewById(R.id.test2).setOnClickListener(listener); 
    findViewById(R.id.test3).setOnClickListener(listener); 
    findViewById(R.id.test4).setOnClickListener(listener); 

} 


public void animateHeight(final View v, final int height) { 

    final int initialHeight = v.getMeasuredHeight(); 
    int duration = 500; 
    Interpolator interpolator = new AccelerateInterpolator(2); 

    // I have to set the same height before the animation because there is a glitch 
    // in the beginning of the animation 
    v.getLayoutParams().height = initialHeight; 
    v.requestLayout(); 

    Animation a = new Animation() { 
     @Override 
     protected void applyTransformation(float interpolatedTime, Transformation t) { 
      Log.d(TAG, "InterpolatedTime: " + interpolatedTime); 
      Log.d(TAG, "Collapsing height: " + (initialHeight - (int) (height * interpolatedTime))); 
      v.getLayoutParams().height = initialHeight - (int) (height * interpolatedTime); 
      v.requestLayout(); 
     } 

     @Override 
     public boolean willChangeBounds() { 
      return true; 
     } 
    }; 

    a.setDuration(duration); 
    a.setInterpolator(interpolator); 
    v.startAnimation(a); 
} 


class Adapter extends RecyclerView.Adapter<Adapter.Holder> { 

    RecyclerView mRecyclerView; 
    int size = 3; 

    public Adapter(RecyclerView recyclerView) { 
     mRecyclerView = recyclerView; 
    } 

    @Override 
    public Holder onCreateViewHolder(ViewGroup parent, int viewType) { 

     View view = getLayoutInflater().inflate(R.layout.item, parent, false); 

     return new Holder(view); 
    } 

    @Override 
    public void onBindViewHolder(Holder holder, int position) { 

    } 

    @Override 
    public int getItemCount() { 
     return size; 
    } 

    class Holder extends RecyclerView.ViewHolder { 

     public Holder(final View itemView) { 
      super(itemView); 

      itemView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        size--; 
        notifyItemRemoved(getAdapterPosition()); 
        animateHeight((View) itemView.getParent(), itemView.getMeasuredHeight()); 
       } 
      }); 

     } 
    } 
} 

} 나를 위해 일한 무엇

0

단지에서 onCreate에 다음 코드를 추가했다 :

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 
    ((ViewGroup) findViewById(R.id.llRoot)).getLayoutTransition() 
     .enableTransitionType(LayoutTransition.CHANGING); 
} 

llRoot 당신입니다 r RecyclerView가 포함 된 LinearLayout.

LinearLayout에 android:animateLayoutChanges="true"을 유지해야합니다. 그렇지 않으면 충돌이 발생합니다.

JellyBean 아래에서이를 지원하려면 사용자 정의 솔루션이 필요하다고 생각합니다.

해결책에 대한 설명은 여기에 있습니다. https://proandroiddev.com/the-little-secret-of-android-animatelayoutchanges-e4caab2fddec

관련 문제