上一節(jié)講解了RecyclerView的三種顯示方式,本節(jié)將主要研究一下RecyclerView的動(dòng)態(tài)添加、刪除及其單擊和長按事件的處理。我們?cè)谏弦还?jié)代碼的基礎(chǔ)上進(jìn)行相關(guān)操作。
一、修改適配器類MyAdapter,加入添加和刪除這兩個(gè)方法:
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,"新加項(xiàng)");
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中添加兩個(gè)菜單按鈕,對(duì)應(yīng)添加和刪除方法:
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;
}
}
調(diào)用了setItemAnimator方法,傳入系統(tǒng)默認(rèn)的動(dòng)畫對(duì)象進(jìn)行“添加或刪除Item”動(dòng)畫的添加。編寫了兩個(gè)菜單按鈕,單擊添加按鈕時(shí),在positon為1的位置添加一個(gè)Item,單擊刪除按鈕,刪除position為1的Item 。 運(yùn)行實(shí)例如下:
http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/24-1.png" alt="這里寫圖片描述" />
http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/24-2.png" alt="這里寫圖片描述" />
單擊添加按鈕時(shí),添加了一個(gè)新加項(xiàng),單擊刪除按鈕時(shí),這個(gè)新加項(xiàng)被刪除。
RecyclerView沒有提供單擊監(jiān)聽和長按監(jiān)聽,需要我們自己實(shí)現(xiàn),這里采用回調(diào)接口的方法實(shí)現(xiàn)這兩個(gè)監(jiān)聽。
修改適配器類文件MyAdapter,添加一個(gè)接口,接口中定義兩個(gè)方法:
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,"新加項(xiàng)");
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);
}
}
}
這里采用了回調(diào)函數(shù)的方法,實(shí)現(xiàn)RecyclerView子Item的單擊和長按監(jiān)聽。為了保證動(dòng)態(tài)添加和刪除時(shí)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;
}
}
在對(duì)應(yīng)的匿名內(nèi)部類方法里寫入了對(duì)應(yīng)的Toast,用于測試是否正確,運(yùn)行項(xiàng)目實(shí)例:
http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/24-3.png" alt="這里寫圖片描述" />
http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/24-4.png" alt="這里寫圖片描述" />
單擊新加項(xiàng)Toast出了onClick1,長按新加項(xiàng)Toast出了onLongClick1。這時(shí)可能有同學(xué)會(huì)注意到一個(gè)問題,在Toast出onLongClick1后還Toast了一個(gè)onClick1,這時(shí)將MyAdapter中的onLongClick方法的返回值改成true即可,這樣攔截了單擊事件,可以再次運(yùn)行測試一下。