2016-03-22 34 views
7

將帖子在底部]如何從RecyclerView中取出一個childview?

我試圖代碼手動將這些類型的動畫:

Google Calendar

如果你仔細看這些意見,他們屬於一個列表或RecyclerView,但他們在親本的範圍內動畫(大小動畫,翻譯動畫)。

如果我嘗試這樣做,結果是我的視圖在我父母的界限之下。

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


這是一個框架,仔細停止正好看到孩子觀點已經從上級單位部門,並開始擴展到整個視圖:

enter image description here

這是它幾乎100%擴展的地方:

enter image description here


我只是想以另一種方式重新指出這一點。這是否與Activity Transitions有關?因爲如果是這樣,我不知道該怎麼做。

回答

1

我能想到的兩種方法來實現這種效果:

一種方法是使用共享單元的活動轉移。這將需要使用2個活動:一個用於回收者視圖,另一個用於全屏視圖。在活動一和活動二之間切換時,動畫將自動應用。這個解決方案可以工作,並且不需要太多的代碼,但是你會遇到保持兩個活動同步的問題(比如RecyclerView的確切位置)。定製並非不可能,但可能很困難,因爲您嚴重依賴框架。

第二種方式是停留在同一活動中,並使用對象動畫製作人員在回收站視圖項目和全屏視圖之間切換。竅門是不要爲位於RecyclerView內部的視圖設置動畫效果,而是從位於RecyclerView內部的視圖邊界爲您的全屏視圖設置動畫效果。這樣,你就不會受到父母的界限的限制。我繼續實施第二種解決方案,因爲它具有高度的可定製性,可以全面控制所有動畫。

此示例應用程序包括翻譯和縮放動畫師。它將從屏幕左側的小方形位置視圖中生成動畫。這種行爲可以很容易地改變。

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

鏈接到項目的回購協議:https://[email protected]/dkarmazi/androidrecyclerviewanimation.git

活動

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; 
    } 
} 

活動佈局

<?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> 

自定義視圖將被全屏顯示

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; 
    } 
} 

佈局自定義視圖

<?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適配器

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)); 
      } 
     } 
    } 
} 

回收站視圖項目佈局

<?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

(將頒發獎金時SO允許我這樣做) 。我認爲沒有辦法通過一項活動來完成這項活動,而這正是我認爲它正在實施的活動。所以這是最後的把戲!非常感謝你 –

相關問題