RecyclerView实现的瀑布流效果
具体介绍见: 使用RecyclerView实现ListView,GridView的效果(上下,左右滑动)
MainActivity:
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.util.Log; import android.view.View; import java.util.ArrayList; /** * 再循环视图,内部实现了复用 */ public class MainActivity extends AppCompatActivity { /** * 复用视图的控件 */ private RecyclerView recyclerView; /** * 显示的数据 */ private ArrayList<String> mDatas; /** * RecyclerView的适配器 */ private MyRecyclerViewAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //1.找到控件 recyclerView = (RecyclerView) findViewById(R.id.recyclerview); //2.声名为瀑布流的布局方式: 3列,垂直方向 StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL); //3.为recyclerView设置布局管理器 recyclerView.setLayoutManager(staggeredGridLayoutManager); initData();//初始化数据 //3.创建适配器 adapter = new MyRecyclerViewAdapter(this, mDatas); //设置添加,移除item的动画,DefaultItemAnimator为默认的 recyclerView.setItemAnimator(new DefaultItemAnimator()); //4.设置适配器 recyclerView.setAdapter(adapter); //添加点击事件 adapter.setOnItemClickListener(new MyRecyclerViewAdapter.OnRecyclerItemClickListener() { @Override public void onItemClick(View view, int position) { //Toast.makeText(MainActivity.this,"单击了:"+mDatas.get(position),Toast.LENGTH_SHORT).show(); adapter.addItem(position,"添加的内容"); Log.i("tag", "onItemClick: "+position); Log.i("tag", "集合: "+mDatas.toString()); } }); //设置长按事件 adapter.setOnItemLongClickListener(new MyRecyclerViewAdapter.onRecyclerItemLongClickListener() { @Override public void onItemLongClick(View view, int position) { //Toast.makeText(MainActivity.this,"长按了:"+mDatas.get(position),Toast.LENGTH_SHORT).show(); adapter.removeItem(position); Log.i("tag", "onItemLongClick: "+position); Log.i("tag", "集合: "+mDatas.toString()); } }); } //初始化数据 protected void initData(){ mDatas = new ArrayList<String>(); for (int i = 'A'; i < 'z'; i++){ mDatas.add("" + (char) i); } } }
适配器,MyRecyclerViewAdapter
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.TextView; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * 实现瀑布流效果的适配器 */ public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder> { private Context context; private List<String> list;//数据 private List<Integer> heightList;//装产出的随机数 private OnRecyclerItemClickListener mOnItemClickListener;//单击事件 private onRecyclerItemLongClickListener mOnItemLongClickListener;//长按事件 public MyRecyclerViewAdapter(Context context, List<String> list) { this.context = context; this.list = list; //记录为每个控件产生的随机高度,避免滑回到顶部出现空白 heightList = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { int height = new Random().nextInt(200) + 100;//[100,300)的随机数 heightList.add(height); } } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //找到item的布局 View view= LayoutInflater.from(context).inflate(R.layout.recycler_item_layout,parent,false); return new MyViewHolder(view);//将布局设置给holder } @Override public int getItemCount() { return list.size(); } /** * 绑定视图到holder,就如同ListView的getView(),但是这里已经把复用实现了,我们只需要填充数据就行. * 由于在复用的时候都是调用该方法填充数据,但是上滑的时候,又会随机产生高度设置到控件上,这样当滑 * 到顶部可能就会看到一片空白,因为后面随机产生的高度和之前的高度不一样,就不能填充屏幕了,所以 * 需要记录每个控件产生的随机高度,然后在复用的时候再设置上去 */ @Override public void onBindViewHolder(final MyViewHolder holder, final int position) { //填充数据 holder.textView.setText(list.get(position)+""); //由于需要实现瀑布流的效果,所以就需要动态的改变控件的高度了 ViewGroup.LayoutParams params = holder.textView.getLayoutParams(); params.height=heightList.get(position); holder.textView.setLayoutParams(params); //设置单击事件 if(mOnItemClickListener !=null){ holder.textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //这里是为textView设置了单击事件,回调出去 //mOnItemClickListener.onItemClick(v,position);这里需要获取布局中的position,不然乱序 mOnItemClickListener.onItemClick(v,holder.getLayoutPosition()); } }); } //长按事件 if(mOnItemLongClickListener != null){ holder.textView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { //回调出去 mOnItemLongClickListener.onItemLongClick(v,holder.getLayoutPosition()); return true;//不返回true,松手还会去执行单击事件 } }); } } class MyViewHolder extends RecyclerView.ViewHolder{ TextView textView; public MyViewHolder(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.textView); } } /** * 处理item的点击事件,因为recycler没有提供单击事件,所以只能自己写了 */ interface OnRecyclerItemClickListener { public void onItemClick(View view, int position); } /** * 长按事件 */ interface onRecyclerItemLongClickListener{ public void onItemLongClick(View view, int position); } /** * 暴露给外面的设置单击事件 */ public void setOnItemClickListener(OnRecyclerItemClickListener onItemClickListener){ mOnItemClickListener = onItemClickListener; } /** * 暴露给外面的长按事件 */ public void setOnItemLongClickListener(onRecyclerItemLongClickListener onItemLongClickListener){ mOnItemLongClickListener = onItemLongClickListener; } /** * 向指定位置添加元素 */ public void addItem(int position, String value) { if(position > list.size()) { position = list.size(); } if(position < 0) { position = 0; } /** * 使用notifyItemInserted/notifyItemRemoved会有动画效果 * 而使用notifyDataSetChanged()则没有 */ list.add(position, value);//在集合中添加这条数据 heightList.add(position,new Random().nextInt(200) + 100);//添加一个随机高度,会在onBindViewHolder方法中得到设置 notifyItemInserted(position);//通知插入了数据 } /** * 移除指定位置元素 */ public String removeItem(int position) { if(position > list.size()-1) { return null; } heightList.remove(position);//删除添加的高度 String value = list.remove(position);//所以还需要手动在集合中删除一次 notifyItemRemoved(position);//通知删除了数据,但是没有删除list集合中的数据 return value; } }
主布局,activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.workspace.my.recyclerviewtest.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="match_parent"></android.support.v7.widget.RecyclerView> </RelativeLayout>
Item布局文件,recycler_item_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/textView" android:textSize="30sp" android:gravity="center" android:layout_margin="3dp" android:background="#ffcccc" android:layout_width="match_parent" android:layout_height="200dp" /> </LinearLayout>
效果如下: