2016-03-22 20 views
7

[AM BODEN EDITED]Wie bekomme ich eine Kinderansicht von RecyclerView?

ich manuell diese Arten von Animationen Code versuchen:

Google Calendar

Wenn Sie genau diese Ansichten sehen, die sie zu einer Liste oder RecyclerView gehören, aber sie sind animiert (Größe Animation, Übersetzung Animation) aus Eltern Grenzen.

Wenn ich versuche, das zu tun, ist das Ergebnis, dass meine Ansicht unter die Grenzen meiner Eltern geht.

https://drive.google.com/file/d/0B-V0KHNRjbE_bkJEekExNGNLbDA/view?usp=sharing


Dies ist ein Rahmen, sorgfältig nur um zu sehen gestoppt, dass das Kind Ansicht von dem Elternteil genommen worden ist, und beginnt, auf die gesamte Ansicht erweitert:

enter image description here

und das ist, wo es fast 100% erweitert ist:

enter image description here


Ich wollte nur auf eine andere Art und Weise darauf hinweisen. Ist das ein Thema in Bezug auf Activity Transitions? Wenn ja, habe ich keine Ahnung, wie es geht.

Antwort

1

Ich denke an zwei Möglichkeiten, diesen Effekt zu erreichen:

Ein Weg ist mit Geteilt Element Aktivität Transition. Es erfordert zwei Aktivitäten: eine mit Recycler-Ansicht, die zweite mit Vollbild-Ansicht. Die Animation wird automatisch zwischen dem Wechsel zwischen Aktivität Eins und Aktivität Zwei angewendet. Diese Lösung wird funktionieren und erfordert nicht viel Code, aber Sie werden auf ein Problem stoßen, zwei Aktivitäten synchron zu halten (z. B. die genaue Position von RecyclerView). Anpassung ist nicht unmöglich, könnte aber schwierig sein, da Sie sich stark auf das Framework verlassen.

Die zweite Möglichkeit besteht darin, innerhalb derselben Aktivität zu bleiben und Objektanimatoren zu verwenden, um zwischen dem Recycler-Ansichtselement und der Vollbildansicht zu wechseln. Der Trick besteht nicht darin, die Ansicht zu animieren, die sich in RecyclerView befindet, sondern Ihre Vollbildansicht von den Grenzen der Ansicht aus zu animieren, die sich in der RecyclerView befindet. Auf diese Weise werden Sie nicht durch die Grenzen der Eltern eingeschränkt. Ich habe die zweite Lösung implementiert, da sie sehr anpassbar ist und Ihnen die volle Kontrolle über alle Animationen gibt.

Diese Beispiel-App enthält Übersetzungs- und Skalierungs-Animatoren. Es wird von der kleinen quadratischen Positionsansicht auf der linken Seite des Bildschirms animiert. Dieses Verhalten kann leicht geändert werden.

Demo: https://dl.dropboxusercontent.com/u/87080012/device-2016-03-25-160611.mp4

Link auf den Projekt-Repo: https://[email protected]/dkarmazi/androidrecyclerviewanimation.git

Aktivität

public class MainActivity extends AppCompatActivity implements Adapter.ItemClickListener, CustomView.CloseButtonClickListener { 
    public static final int ANIMATION_SPEED = 3000; 
    private RecyclerView recyclerView; 
    private CustomView customView; 
    private RelativeLayout rootView; 
    private Rect lastClickedRecyclerViewItemRect; 

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

     rootView = (RelativeLayout) findViewById(R.id.root_view); 
     recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
     customView = (CustomView) findViewById(R.id.custom_view); 

     recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); 
     recyclerView.setAdapter(new Adapter(getApplicationContext(), this, getSampleData())); 
    } 

    @Override 
    public void onItemClicked(View clickedView, int position, String title) { 
     lastClickedRecyclerViewItemRect = new Rect(); 
     clickedView.getGlobalVisibleRect(lastClickedRecyclerViewItemRect); 

     Rect targetViewRect = new Rect(); 
     rootView.getGlobalVisibleRect(targetViewRect); 

     AnimatorSet animatorSet = getViewToViewScalingAnimator(rootView, customView, lastClickedRecyclerViewItemRect, targetViewRect, ANIMATION_SPEED, 0); 

     customView.setData(position, title, this); 
     customView.setVisibility(View.VISIBLE); 

     animatorSet.start(); 
    } 

    @Override 
    public void onCloseButtonClicked(int position) { 
     Rect clickedViewRect = new Rect(); 
     customView.getGlobalVisibleRect(clickedViewRect); 
     AnimatorSet animatorSet = getViewToViewScalingAnimator(rootView, customView, clickedViewRect, lastClickedRecyclerViewItemRect, ANIMATION_SPEED, 0); 

     animatorSet.addListener(new Animator.AnimatorListener() { 
      @Override 
      public void onAnimationStart(Animator animation) { 
       // no op 
      } 

      @Override 
      public void onAnimationEnd(Animator animation) { 
       customView.setVisibility(View.GONE); 
      } 

      @Override 
      public void onAnimationCancel(Animator animation) { 
       // no op 
      } 

      @Override 
      public void onAnimationRepeat(Animator animation) { 
       // no op 
      } 
     }); 

     animatorSet.start(); 
    } 

    public static AnimatorSet getViewToViewScalingAnimator(final RelativeLayout parentView, 
                  final View viewToAnimate, 
                  final Rect fromViewRect, 
                  final Rect toViewRect, 
                  final long duration, 
                  final long startDelay) { 
     // get all coordinates at once 
     final Rect parentViewRect = new Rect(), viewToAnimateRect = new Rect(); 
     parentView.getGlobalVisibleRect(parentViewRect); 
     viewToAnimate.getGlobalVisibleRect(viewToAnimateRect); 

     viewToAnimate.setScaleX(1f); 
     viewToAnimate.setScaleY(1f); 

     // rescaling of the object on X-axis 
     final ValueAnimator valueAnimatorWidth = ValueAnimator.ofInt(fromViewRect.width(), toViewRect.width()); 
     valueAnimatorWidth.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
      @Override 
      public void onAnimationUpdate(ValueAnimator animation) { 
       // Get animated width value update 
       int newWidth = (int) valueAnimatorWidth.getAnimatedValue(); 

       // Get and update LayoutParams of the animated view 
       RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewToAnimate.getLayoutParams(); 

       lp.width = newWidth; 
       viewToAnimate.setLayoutParams(lp); 
      } 
     }); 

     // rescaling of the object on Y-axis 
     final ValueAnimator valueAnimatorHeight = ValueAnimator.ofInt(fromViewRect.height(), toViewRect.height()); 
     valueAnimatorHeight.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
      @Override 
      public void onAnimationUpdate(ValueAnimator animation) { 
       // Get animated width value update 
       int newHeight = (int) valueAnimatorHeight.getAnimatedValue(); 

       // Get and update LayoutParams of the animated view 
       RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewToAnimate.getLayoutParams(); 
       lp.height = newHeight; 
       viewToAnimate.setLayoutParams(lp); 
      } 
     }); 

     // moving of the object on X-axis 
     ObjectAnimator translateAnimatorX = ObjectAnimator.ofFloat(viewToAnimate, "X", fromViewRect.left - parentViewRect.left, toViewRect.left - parentViewRect.left); 

     // moving of the object on Y-axis 
     ObjectAnimator translateAnimatorY = ObjectAnimator.ofFloat(viewToAnimate, "Y", fromViewRect.top - parentViewRect.top, toViewRect.top - parentViewRect.top); 

     AnimatorSet animatorSet = new AnimatorSet(); 
     animatorSet.setInterpolator(new DecelerateInterpolator(1f)); 
     animatorSet.setDuration(duration); // can be decoupled for each animator separately 
     animatorSet.setStartDelay(startDelay); // can be decoupled for each animator separately 
     animatorSet.playTogether(valueAnimatorWidth, valueAnimatorHeight, translateAnimatorX, translateAnimatorY); 

     return animatorSet; 
    } 

    private static List<String> getSampleData() { 
     List<String> dataList = new ArrayList<>(); 
     dataList.add("zero"); 
     dataList.add("one"); 
     dataList.add("two"); 
     dataList.add("three"); 
     dataList.add("four"); 
     dataList.add("five"); 
     dataList.add("six"); 
     dataList.add("seven"); 
     dataList.add("eight"); 
     dataList.add("nine"); 
     dataList.add("ten"); 
     dataList.add("eleven"); 
     dataList.add("twelve"); 
     dataList.add("thirteen"); 
     dataList.add("fourteen"); 
     dataList.add("fifteen"); 
     dataList.add("sixteen"); 
     dataList.add("seventeen"); 
     dataList.add("eighteen"); 
     dataList.add("nineteen"); 
     dataList.add("twenty"); 

     return dataList; 
    } 
} 

Aktivität Layout

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/root_view" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/recycler_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="@android:color/white"/> 

    <com.dkarmazi.android.myapplication.CustomView 
     android:id="@+id/custom_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:visibility="gone"/> 
</RelativeLayout> 

Benutzerdefinierte Ansicht, die Vollbild angezeigt wird

public class CustomView extends FrameLayout { 
    public interface CloseButtonClickListener { 
     void onCloseButtonClicked(int position); 
    } 

    private TextView positionView; 
    private TextView titleView; 
    private View closeView; 
    private CloseButtonClickListener closeButtonClickListener; 
    private int position; 

    public CustomView(Context context) { 
     super(context); 
     init(); 
    } 

    public CustomView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     init(); 
    } 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
     init(); 
    } 

    private void init() { 
     inflate(getContext(), R.layout.custom_view, this); 
     positionView = (TextView) findViewById(R.id.custom_view_position); 
     titleView = (TextView) findViewById(R.id.custom_view_title); 
     closeView = findViewById(R.id.custom_view_close_button); 

     closeView.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if(closeButtonClickListener != null) { 
        closeButtonClickListener.onCloseButtonClicked(position); 
       } 
      } 
     }); 
    } 

    public void setData(int position, String title, CloseButtonClickListener closeButtonClickListener) { 
     this.position = position; 
     this.positionView.setText("" + position); 
     this.titleView.setText(title); 
     this.closeButtonClickListener = closeButtonClickListener; 
    } 
} 

-Layout für die benutzerdefinierte Ansicht

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@android:color/holo_red_dark"> 

    <ImageView 
     android:id="@+id/custom_view_close_button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@android:drawable/ic_menu_close_clear_cancel" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentRight="true"/> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" 
     android:gravity="center" 
     android:layout_marginTop="50dp"> 

     <TextView 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:textColor="@android:color/white" 
      android:textSize="20sp" 
      android:gravity="center" 
      android:layout_gravity="top" 
      android:text="Position:" /> 

     <TextView 
      android:id="@+id/custom_view_position" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:textColor="@android:color/white" 
      android:textSize="25sp" 
      android:gravity="center" 
      android:layout_gravity="top" 
      android:paddingBottom="100dp" /> 

     <TextView 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:textColor="@android:color/white" 
      android:textSize="20sp" 
      android:gravity="center" 
      android:layout_gravity="top" 
      android:text="Title:" /> 

     <TextView 
      android:id="@+id/custom_view_title" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:textColor="@android:color/white" 
      android:gravity="center" 
      android:textSize="25sp" 
      android:layout_gravity="center"/> 
    </LinearLayout> 
</RelativeLayout> 

RecyclerView Adapter

public class Adapter extends RecyclerView.Adapter { 
    public interface ItemClickListener { 
     void onItemClicked(View v, int position, String title); 
    } 

    private Context context; 
    private ItemClickListener itemClickListener; 
    private List<String> dataList; 

    public Adapter(Context context, ItemClickListener itemClickListener, List<String> dataList) { 
     this.context = context; 
     this.itemClickListener = itemClickListener; 
     this.dataList = dataList; 
    } 

    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(context).inflate(R.layout.recycler_view_item, null, false); 

     return new MyViewHolder(view, new OnRecyclerItemClickListener()); 
    } 


    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
     ((MyViewHolder) holder).onRecyclerItemClickListener.updatePosition(position); 
     ((MyViewHolder) holder).position.setText("" + position); 
     ((MyViewHolder) holder).title.setText(dataList.get(position)); 
    } 

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

    private class MyViewHolder extends RecyclerView.ViewHolder { 
     private OnRecyclerItemClickListener onRecyclerItemClickListener; 
     private TextView position; 
     private TextView title; 

     public MyViewHolder(View itemView, OnRecyclerItemClickListener onRecyclerItemClickListener) { 
      super(itemView); 

      itemView.setOnClickListener(onRecyclerItemClickListener); 
      this.onRecyclerItemClickListener = onRecyclerItemClickListener; 
      this.position = (TextView) itemView.findViewById(R.id.position); 
      this.title = (TextView) itemView.findViewById(R.id.title); 
     } 
    } 


    private class OnRecyclerItemClickListener implements View.OnClickListener { 
     private int position = -1; 

     public void updatePosition(int position) { 
      this.position = position; 
     } 

     @Override 
     public void onClick(View v) { 
      if(itemClickListener != null) { 
       itemClickListener.onItemClicked(v.findViewById(R.id.position), position, dataList.get(position)); 
      } 
     } 
    } 
} 

Recycler Artikel ansehen Layout

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/recycler_view_item" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:padding="10dp"> 

    <TextView 
     android:id="@+id/position" 
     android:layout_width="30dp" 
     android:layout_height="50dp" 
     android:textColor="@android:color/white" 
     android:gravity="center" 
     android:background="@android:color/holo_green_light" 
     android:layout_alignParentLeft="true"/> 

    <TextView 
     android:id="@+id/title" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:textColor="@android:color/white" 
     android:gravity="center" 
     android:background="@android:color/holo_green_dark" 
     android:layout_toRightOf="@id/position" 
     android:layout_alignParentRight="true"/> 
</RelativeLayout> 
+0

(vergibt die Prämie, wenn SO ermöglicht es mir, es zu tun) . Ich denke, es gibt keine Möglichkeit, dies mit einer Aktivität zu tun, die ich gerade dachte. Also das ist endlich der Trick !! danke sehr mcuh –

Verwandte Themen