Android中RecyclerView的item运用覆盖view的方法实现item的动画效果

1.在RecyclerView实现GridView类似效果时,每个item的大小尺寸是随着传入spanCount的数值大小改变而改变的。所以获取item是要实现动态获取。

 mRecyclerView.setLayoutManager(new GridLayoutManager(this, VERTICALCOUNT));


因此在MyAdapter类设置一个接口回调来传入所要知道对应position的item。

 if (mOnItemClickLitener!=null){
            //设置回调
            holder.mItem_fl.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int layoutPosition = holder.getLayoutPosition();
                    mOnItemClickLitener.onItemClick(holder.mItem_fl,layoutPosition);
                }
            });
        }



2.设置OnItemClickLitener的方法时要注意是要传入一个ViewGroup,因为只有ViewGroup中才有getChidAt()这个方法获取子view,而如果传入的是View则没有这个方法从而无法获取item中的子类进行设置对应的coverItem的数据。

 public interface OnItemClickLitener{
       //传入ViewGroup能在获取的时候用其特性获取子view
       void onItemClick(ViewGroup view, int position);
    }

                mChildAt = (TextView) view.getChildAt(0);                   //从viewgroup获取子view
                mItemTvCover.setText(mChildAt.getText());


3.接下来是copy一份与item一模一样的布局,把这个布局添加到根布局中,运用ViewGroup中的addView()添加。

  mAddView = (LinearLayout) LayoutInflater.from(MainActivity.this).inflate(R.layout.addview, mLl, false);
        mLl.addView(mAddView);


4.获取item的宽高值把coverItem设置为item的宽高:

 int measuredWidth = view.getMeasuredWidth();
                int measuredHeight = view.getMeasuredHeight();
 setItemCoverSize(measuredWidth, measuredHeight);
  private void setItemCoverSize(int measuredWidth, int measuredHeight) {
        ViewGroup.LayoutParams layoutParams = mItem_fl_cover.getLayoutParams();
        layoutParams.width = measuredWidth;
        layoutParams.height = measuredHeight;
        mItem_fl_cover.setLayoutParams(layoutParams);
    }



5.获取item的相对屏幕原点的XY坐标,获取coverItem相对于屏幕原点的XY坐标,获取RecycleView的宽高值,item的宽高值。

 //获取item的相对原点位置
                int[] outlocaton = new int[2];
                view.getLocationOnScreen(outlocaton);
                int itemXLoaction = outlocaton[0];
                int itemYtLoacton = outlocaton[1];

                //获取coverItem相对原点位置
                int[] coverLocaton = new int[2];
                mItem_fl_cover.getLocationOnScreen(coverLocaton);
                int coverItemXLoaction = coverLocaton[0];
                int coverItemYLoaction = coverLocaton[1];

                //获取recycleview的宽高
                int measuredWidth1 = mRecyclerView.getMeasuredWidth();
                int measuredHeight1 = mRecyclerView.getMeasuredHeight();


6.将控件对应的位置传入setItemAnimator进行动画设置。

 setItemAnimator(itemXLoaction, y);

在这个过程中遇到很多的问题,尤其是Android中的坐标系的问题,设置错了坐标设置的动画会莫名的跑出屏幕可见的范围之外。



下面是代码:

1.activity_main.xml:

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

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="RecycleViewDemo"
        android:textSize="20dp"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/activity_recycleview"
        android:divider="#ffff0000"
        android:dividerHeight="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </android.support.v7.widget.RecyclerView>


</LinearLayout>
2.item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:background="#44ff0000"
              android:id="@+id/item_fl"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="wrap_content">
    <TextView
        android:layout_gravity="center"
        android:id="@+id/item_tv"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="标签"
        android:textSize="20dip"/>
    <ImageView
        android:id="@+id/item_iv"
        android:src="@mipmap/ic_launcher"
        android:layout_gravity="center"
        android:layout_width="50dp"
        android:layout_height="50dp"/>

</LinearLayout>

3.itemcover.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:background="#8888"
              android:id="@+id/item_fl_cover"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="wrap_content">
    <TextView
        android:layout_gravity="center"
        android:id="@+id/item_tv_cover"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="标签"
        android:textSize="20dip"/>
    <ImageView
        android:id="@+id/item_iv_cover"
        android:src="@mipmap/ic_launcher"
        android:layout_gravity="center"
        android:layout_width="50dp"
        android:layout_height="50dp"/>

</LinearLayout>


4.MainActivity.java:

package com.example.foreveross.addviewdemo;

import android.graphics.Rect;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;

public class MainActivity extends AppCompatActivity {

    private static final int VERTICALCOUNT = 4;
    private String[] mDatas = new String[]{"春炮竹", "福炮竹", "福字", "新年快乐", "灯笼", "狮子头", "耍狮子", "招财猫", "恭喜发财",
            "点燃的炮竹", "剪纸", "春字"};
    private RecyclerView mRecyclerView;
    private MyAdapter mMyAdapter;
    private LinearLayout mLl;
    private LinearLayout mAddView;
    private TextView mItemTvCover;
    private LinearLayout mItem_fl_cover;
    private GoogleApiClient mClient;

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

    private void initEvent() {
        mMyAdapter.setOnItemClickLitener(new MyAdapter.OnItemClickLitener() {
            private TextView mChildAt;
            @Override
            public void onItemClick(ViewGroup view, int position) {
                mItem_fl_cover.setVisibility(View.VISIBLE);
                //获取item的相对原点位置
                int[] outlocaton = new int[2];
                view.getLocationOnScreen(outlocaton);
                int itemXLoaction = outlocaton[0];
                int itemYtLoacton = outlocaton[1];
                //获取coverItem相对原点位置
                int[] coverLocaton = new int[2];
                mItem_fl_cover.getLocationOnScreen(coverLocaton);
                int coverItemXLoaction = coverLocaton[0];
                int coverItemYLoaction = coverLocaton[1];
                //获取recycleview的宽高
                int measuredWidth1 = mRecyclerView.getMeasuredWidth();
                int measuredHeight1 = mRecyclerView.getMeasuredHeight();
                Toast.makeText(MainActivity.this, "y值为:" + itemXLoaction, Toast.LENGTH_SHORT).show();
//                Toast.makeText(MainActivity.this, "itemXLoaction:"+itemXLoaction
//                        + "itemYtLoacton:" + itemYtLoacton
//                        +"coverItemXLoaction:"+coverItemXLoaction
//                        +"coverItemYLoaction:"+coverItemYLoaction, Toast.LENGTH_SHORT).show();
                int measuredWidth = view.getMeasuredWidth();
                int measuredHeight = view.getMeasuredHeight();
                //计算item的行数
                int i = mDatas.length / VERTICALCOUNT;
                //点击的item的Y值与itemcover的Y之间的差值
                int y = -measuredHeight1+itemYtLoacton-measuredHeight ;     //设置item的动画开始的Y位置
                //获取item的尺寸
                setItemCoverSize(measuredWidth, measuredHeight);
                mChildAt = (TextView) view.getChildAt(0);                   //从viewgroup获取子view
                mItemTvCover.setText(mChildAt.getText());
                setItemAnimator(itemXLoaction, y);
            }
        });
    }

    private void setItemCoverSize(int measuredWidth, int measuredHeight) {
        ViewGroup.LayoutParams layoutParams = mItem_fl_cover.getLayoutParams();
        layoutParams.width = measuredWidth;
        layoutParams.height = measuredHeight;
        mItem_fl_cover.setLayoutParams(layoutParams);
    }


    private void initData() {
    }

    private void initView() {
        mLl = (LinearLayout) findViewById(R.id.ll);
        mRecyclerView = (RecyclerView) findViewById(R.id.activity_recycleview);
        //   mRecyclerView.addItemDecoration(new SpaceItemDecoration(R.dimen.space));            //增加item的装饰
        mRecyclerView.setLayoutManager(new GridLayoutManager(this, VERTICALCOUNT));
        mMyAdapter = new MyAdapter(this, mDatas);
        mRecyclerView.setAdapter(mMyAdapter);
        //添加一个覆盖的view
        mAddView = (LinearLayout) LayoutInflater.from(MainActivity.this).inflate(R.layout.addview, mLl, false);
        mLl.addView(mAddView);

        mItemTvCover = (TextView) mLl.findViewById(R.id.item_tv_cover);
        mItem_fl_cover = (LinearLayout) mLl.findViewById(R.id.item_fl_cover);

    }


    private void setItemAnimator(float x, float y) {
//        Toast.makeText(MainActivity.this,"动画设置的x:"+x+"动画设置的Y:"+y,Toast.LENGTH_SHORT).show();
        TranslateAnimation translateAnimaton = new TranslateAnimation(x, x, y, y - 1000);
        AnimationSet animationSet = new AnimationSet(true);
        AlphaAnimation alphaAnimation = new AlphaAnimation(1f, 0);
        animationSet.addAnimation(translateAnimaton);
        animationSet.addAnimation(alphaAnimation);
        animationSet.setDuration(5000);
        mItem_fl_cover.setAnimation(animationSet);
        animationSet.start();
        animationSet.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                //动画结束时隐藏framelayout
                mItem_fl_cover.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

    /**
     * 给item设置装饰
     */
    public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
        int spaceSize;

        public SpaceItemDecoration(int spaceSize) {
            this.spaceSize = spaceSize;
        }

        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            if (parent.getChildPosition(view) != 0) {
                outRect.left = spaceSize;
                outRect.bottom = spaceSize;
                outRect.top = spaceSize;
                outRect.right = spaceSize;
            }
        }
    }
}

5.MyAdapter.java:

package com.example.foreveross.addviewdemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

/**
 * Created by Foreveross on 2017/4/3.
 */
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    Context mContext;
    String[] mData;

    public MyAdapter(Context context, String[] data) {
        this.mContext = context;
        this.mData = data;
    }


    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        MyViewHolder myViewHolder = new MyViewHolder(LayoutInflater.from(mContext)
                .inflate(R.layout.recycleview, parent, false));

        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, int position) {
        holder.mItem_tv.setText(mData[position]);

        if (mOnItemClickLitener!=null){
            //设置回调
            holder.mItem_fl.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int layoutPosition = holder.getLayoutPosition();
                    mOnItemClickLitener.onItemClick(holder.mItem_fl,layoutPosition);
                }
            });
        }
    }

    @Override
    public int getItemCount() {
        return mData.length;
    }

    //创建一个viewholder
    class MyViewHolder extends RecyclerView.ViewHolder {

        private final LinearLayout mItem_fl;
        private final TextView mItem_tv;

        public MyViewHolder(View view) {
            super(view);
            mItem_tv = (TextView) view.findViewById(R.id.item_tv);
            mItem_fl = (LinearLayout) view.findViewById(R.id.item_fl);
        }
    }

    public OnItemClickLitener mOnItemClickLitener;

   public interface OnItemClickLitener{
       //传入ViewGroup能在获取的时候用其特性获取子view
       void onItemClick(ViewGroup view, int position);
    }

    public void setOnItemClickLitener(OnItemClickLitener on){
        this.mOnItemClickLitener=on;
    }

}


代码地址为:http://dl.download.csdn.net/down11/20170404/64060f26830e17abdc6e458f4ba964a2.rar?response-content-disposition=attachment%3Bfilename%3D%22AddViewDemo.rar%22&OSSAccessKeyId=9q6nvzoJGowBj4q1&Expires=1491301209&Signature=i%2FHRiBo8qxSdf90YLlG9uQ8GTes%3D


Android坐标系全解:http://blog.csdn.net/yanbober/article/details/50419117


总结:

1.Android的坐标原点是在屏幕的左上角,以这个点向右为X的正方向,向下为Y的正方向。

2.view.getLocationOnScreen()获取的是view的相对于屏幕的坐标原点,

view.getLocationInWindow()获取的是相对父控件的坐标。

3.getX()返回值为:getLeft()+getTranslationX();

  getLeft():是view自身左边到父控件左边的距离;

  getWidth():layout后有效返回值是mRight-mLeft;

  getMeasuredWidth():返回measure过程得到的mMeasuredWidth值。

4.TranslateAnimation动画中的fromXDelta是动画开始相对于自身的X的坐标位置,fromXDelta是动画结束时相对自身的X的坐标位置。

5.在ViewGroup中添加view是addView()方法,设置view的宽高是先获取view.getLayoutParams()的参数设置之后再添加宽高,最后在view.setLayoutParams(layoutParams)。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值