私は自分のrecyclerviewアニメーションを実装しようとしています-外部ライブラリを使用せずにこれを実現したいと思います。これは理論的なアニメーションがどのように見えるかです。
ユーザーがリストの項目をクリックすると、別のビューを開くアニメーションが発生します。
最小限のコード、おそらく疑似コードでの高レベルでは、そのようなアニメーションを作成するためのプロセスは何でしょうか?
ユーザーが同じアイテムまたは別のアイテムをクリックした場合にもアニメーションを逆に実行できることにも注意したい
私はRecyclerView
クラスにあまり詳しくないので、このクラスとそれに関連するアニメーションについて詳しく知りたいと思います。
解決:
この問題を解決した方法は、View.OnClickListener
であるViewHolder
クラスにリスナーextends RecyclerView.ViewHolder
を実装することでした。したがって、次のコードを取得します。
public static class ExampleViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
private int originalHeight = 0;
private boolean isViewExpanded = false;
private YourCustomView yourCustomView
// ..... CODE ..... //
}
変数originalHeight
およびisViewExpanded
は、アニメーションプロセスで使用されます。コンストラクタで、ビューをView.OnClickListener
に初期化します。
public ExampleViewHolder(View v) {
super(v);
v.setOnClickListener(this);
// Initialize other views, like TextView, ImageView, etc. here
// If isViewExpanded == false then set the visibility
// of whatever will be in the expanded to GONE
if (isViewExpanded == false) {
// Set Views to View.GONE and .setEnabled(false)
yourCustomView.setVisibility(View.GONE);
yourCustomView.setEnabled(false);
}
}
コンストラクタが処理されたので、ユーザーが個々のRecyclerView
アイテムをクリックしたときに何が起こるかを構成します。ここで役立つクラスは、ValueAnimator
オブジェクトとAnimation
オブジェクトです。これを実現するために、onClick
メソッドを次のようにオーバーライドします。
@Override
public void onClick(final View view) {
// If the originalHeight is 0 then find the height of the View being used
// This would be the height of the cardview
if (originalHeight == 0) {
originalHeight = view.getHeight();
}
// Declare a ValueAnimator object
ValueAnimator valueAnimator;
if (!mIsViewExpanded) {
yourCustomView.setVisibility(View.VISIBLE);
yourCustomView.setEnabled(true);
mIsViewExpanded = true;
valueAnimator = ValueAnimator.ofInt(originalHeight, originalHeight + (int) (originalHeight * 2.0)); // These values in this method can be changed to expand however much you like
} else {
mIsViewExpanded = false;
valueAnimator = ValueAnimator.ofInt(originalHeight + (int) (originalHeight * 2.0), originalHeight);
Animation a = new AlphaAnimation(1.00f, 0.00f); // Fade out
a.setDuration(200);
// Set a listener to the animation and configure onAnimationEnd
a.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
yourCustomView.setVisibility(View.INVISIBLE);
yourCustomView.setEnabled(false);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
// Set the animation on the custom view
yourCustomView.startAnimation(a);
}
valueAnimator.setDuration(200);
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
view.getLayoutParams().height = value.intValue();
view.requestLayout();
}
});
valueAnimator.start();
}
ここで、RecyclerView
の個々のカードビューをタッチすると(CardView
の設定があると仮定すると、展開されるはずです。必ず、xmlファイルでcustomViewを適切に宣言してください(たとえば、 CardView
に触れると展開され、他のビューの下にcustomViewが適切に割り当てられます。宣言すると可視性がなくなり、上記のコードのようにアニメーションが開始されると、可視性がVisibleに設定されます。ビューを有効にします。
これが誰かを助けることを願っています。
@AndyRoidの答えのより簡単な代替方法は、Android:animateLayoutChanges="true"
プロパティを使用することです。この方法では、アニメーションコードを記述する必要はありません。ただし、アニメーションを制御する必要がある場合は、この方法にはなりません。
OnClickListener
を作成する必要があります:
class CardTapListener implements View.OnClickListener {
@Override
public void onClick(View v) {
View someView = v.findViewById(R.id.view_to_expand);
if (someView.getVisibility() == View.GONE) {
someView.setVisibility(View.VISIBLE);
}
else if (someView.getVisibility() == View.VISIBLE){
someView.setVisibility(View.GONE);
}
}
}
すべてのViewHolder
に添付:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_layout, viewGroup, false);
v.setOnClickListener(new CardTapListener());
return new ItemViewHolder(v);
}
新しいアイテムをバインドするときは、ビューを折りたたむことを忘れないでください。
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
...
// Collapse (probably opened by user previously) view
ItemViewHolder itemHolder = (ItemViewHolder) viewHolder;
itemHolder.description.setVisibility(View.GONE);
...
}
view_holder_layout.xml:
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:animateLayoutChanges="true"
Android:orientation="vertical">
...
<AnyViewHere
Android:visibility="gone"
Android:id="@+id/view_to_expand" />
</LinearLayout>