具體介紹見: 使用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>
效果如下:

