RecyclerView動態添加、刪除及點擊事件
上一節講解了RecyclerView的三種顯示方式,本節將主要研究一下RecyclerView的動態添加、刪除及其單擊和長按事件的處理。我們在上一節代碼的基礎上進行相關操作。
一、修改適配器類MyAdapter,加入添加和刪除這兩個方法:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private Context context; private List<String> datas; private List<Integer> mHights; public MyAdapter(Context context,List<String> datas){ this.context=context; this.datas=datas; mHights=new ArrayList<>(); for (int i=0;i<datas.size();i++){ mHights.add((int)(50+Math.random()*300)); } } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { MyViewHolder holder = new MyViewHolder(LayoutInflater.from( context).inflate(R.layout.item, parent, false)); return holder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { ViewGroup.LayoutParams layoutparams= holder.itemView.getLayoutParams(); layoutparams.height=mHights.get(position); holder.itemView.setLayoutParams(layoutparams); holder.tv.setText(datas.get(position)); } @Override public int getItemCount() { return datas.size(); } public void addItem(int position){ datas.add(position,"新加項"); notifyItemInserted(position); } public void removeItem(int position){ datas.remove(position); notifyItemRemoved(position); } class MyViewHolder extends RecyclerView.ViewHolder { TextView tv; public MyViewHolder(View view) { super(view); tv = (TextView) view.findViewById(R.id.id_num); } } }
二、在MainActivity中添加兩個菜單按鈕,對應添加和刪除方法:
public class MainActivity extends Activity { private RecyclerView mRecyclerView; private List<String> mDatas; private MyAdapter myAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); mRecyclerView = (RecyclerView) findViewById(R.id.recycleview); mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL)); myAdapter = new MyAdapter(this, mDatas); mRecyclerView.setAdapter(myAdapter); mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this)); mRecyclerView.setItemAnimator(new DefaultItemAnimator()); } protected void initData() { mDatas = new ArrayList<String>(); for (int i = 1; i < 100; i++) { mDatas.add("" + i); } } @Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(1,1,1,"添加"); menu.add(1,2,2,"刪除"); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case 1: myAdapter.addItem(1); break; case 2: myAdapter.removeItem(1); break; } return true; } }
調用了setItemAnimator方法,傳入系統默認的動畫對象進行“添加或刪除Item”動畫的添加。編寫了兩個菜單按鈕,單擊添加按鈕時,在positon為1的位置添加一個Item,單擊刪除按鈕,刪除position為1的Item 。 運行實例如下:
單擊添加按鈕時,添加了一個新加項,單擊刪除按鈕時,這個新加項被刪除。
RecyclerView沒有提供單擊監聽和長按監聽,需要我們自己實現,這裏采用回調接口的方法實現這兩個監聽。
修改適配器類文件MyAdapter,添加一個接口,接口中定義兩個方法:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private Context context; private List<String> datas; private List<Integer> mHights; public interface onItemClickListener{ void onItemClick(View view ,int position); void onItemLongClick(View view,int position); } private onItemClickListener onItemClickListener; public void setOnItemClickListener(onItemClickListener onItemClickListener){ this.onItemClickListener=onItemClickListener; } public MyAdapter(Context context,List<String> datas){ this.context=context; this.datas=datas; mHights=new ArrayList<>(); for (int i=0;i<datas.size();i++){ mHights.add((int)(50+Math.random()*300)); } } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { MyViewHolder holder = new MyViewHolder(LayoutInflater.from( context).inflate(R.layout.item, parent, false)); return holder; } @Override public void onBindViewHolder(final MyViewHolder holder, final int position) { ViewGroup.LayoutParams layoutparams= holder.itemView.getLayoutParams(); layoutparams.height=mHights.get(position); holder.itemView.setLayoutParams(layoutparams); holder.tv.setText(datas.get(position)); if(onItemClickListener!=null){ holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int layoutPos=holder.getLayoutPosition(); onItemClickListener.onItemClick(holder.itemView,layoutPos); } }); holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { int layoutPos=holder.getLayoutPosition(); onItemClickListener.onItemLongClick(holder.itemView,layoutPos); return false; } }); } } @Override public int getItemCount() { return datas.size(); } public void addItem(int position){ datas.add(position,"新加項"); notifyItemInserted(position); } public void removeItem(int position){ datas.remove(position); notifyItemRemoved(position); } class MyViewHolder extends RecyclerView.ViewHolder { TextView tv; public MyViewHolder(View view) { super(view); tv = (TextView) view.findViewById(R.id.id_num); } } }
這裏采用了回調函數的方法,實現RecyclerView子Item的單擊和長按監聽。為了保證動態添加和刪除時position值的正確性,我們使用了getLayoutPosition方法獲得position,這裏要註意。
MainActivity中也添加了一些代碼如下:
public class MainActivity extends Activity {
private RecyclerView mRecyclerView;
private List<String> mDatas;
private MyAdapter myAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
mRecyclerView = (RecyclerView) findViewById(R.id.recycleview);
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));
myAdapter = new MyAdapter(this, mDatas);
mRecyclerView.setAdapter(myAdapter);
mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
myAdapter.setOnItemClickListener(new MyAdapter.onItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this,"onClick"+position,Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(View view, int position) {
Toast.makeText(MainActivity.this,"onLongClick"+position,Toast.LENGTH_SHORT).show();
}
});
}
protected void initData() {
mDatas = new ArrayList<String>();
for (int i = 1; i < 100; i++) {
mDatas.add("" + i);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(1,1,1,"添加");
menu.add(1,2,2,"刪除");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case 1:
myAdapter.addItem(1);
break;
case 2:
myAdapter.removeItem(1);
break;
}
return true;
}
}
在對應的匿名內部類方法裏寫入了對應的Toast,用於測試是否正確,運行項目實例:
單擊新加項Toast出了onClick1,長按新加項Toast出了onLongClick1。這時可能有同學會註意到一個問題,在Toast出onLongClick1後還Toast了一個onClick1,這時將MyAdapter中的onLongClick方法的返回值改成true即可,這樣攔截了單擊事件,可以再次運行測試一下。
RecyclerView動態添加、刪除及點擊事件