android中在Activity中响应ListView内部按钮的点击事件的两种方法
最近交流群里面有人问到一个问题:如何在Activity中响应ListView内部按钮的点击事件,不要在Adapter中响应?
对于这个问题,我最初给他的解答是,在Adapter中定义一个回调接口,在Activity中实现该接口,从而实现对点击事件的响应。
下班后思考了一下,觉得有两种方式都能比较好的实现:使用接口回调和使用抽象类回调。
正好可以复习一下接口和抽象类的区别,于是写了两个Demo:
1.使用接口回调:
Adapter类
packagecom.ivan.adapter; importjava.util.List; importandroid.content.Context; importandroid.util.Log; importandroid.view.LayoutInflater; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.view.ViewGroup; importandroid.widget.BaseAdapter; importandroid.widget.Button; importandroid.widget.TextView; importcom.ivan.listvieweventcallback.R; publicclassContentAdapterextendsBaseAdapterimplementsOnClickListener{ privatestaticfinalStringTAG="ContentAdapter"; privateList<String>mContentList; privateLayoutInflatermInflater; privateCallbackmCallback; /** *自定义接口,用于回调按钮点击事件到Activity *@authorIvanXu *2014-11-26 */ publicinterfaceCallback{ publicvoidclick(Viewv); } publicContentAdapter(Contextcontext,List<String>contentList, Callbackcallback){ mContentList=contentList; mInflater=LayoutInflater.from(context); mCallback=callback; } @Override publicintgetCount(){ Log.i(TAG,"getCount"); returnmContentList.size(); } @Override publicObjectgetItem(intposition){ Log.i(TAG,"getItem"); returnmContentList.get(position); } @Override publiclonggetItemId(intposition){ Log.i(TAG,"getItemId"); returnposition; } @Override publicViewgetView(intposition,ViewconvertView,ViewGroupparent){ Log.i(TAG,"getView"); ViewHolderholder=null; if(convertView==null){ convertView=mInflater.inflate(R.layout.list_item,null); holder=newViewHolder(); holder.textView=(TextView)convertView .findViewById(R.id.textView1); holder.button=(Button)convertView.findViewById(R.id.button1); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.textView.setText(mContentList.get(position)); holder.button.setOnClickListener(this); holder.button.setTag(position); returnconvertView; } publicclassViewHolder{ publicTextViewtextView; publicButtonbutton; } //响应按钮点击事件,调用子定义接口,并传入View @Override publicvoidonClick(Viewv){ mCallback.click(v); } }
Activity类:
packagecom.ivan.listvieweventdemo; importjava.util.ArrayList; importjava.util.List; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.Menu; importandroid.view.View; importandroid.widget.AdapterView; importandroid.widget.AdapterView.OnItemClickListener; importandroid.widget.ListView; importandroid.widget.Toast; importcom.ivan.adapter.ContentAdapter; importcom.ivan.adapter.ContentAdapter.Callback; importcom.ivan.listvieweventcallback.R; //MainActivity需要实现自定义接口 publicclassMainActivityextendsActivityimplementsOnItemClickListener, Callback{ //模拟listview中加载的数据 privatestaticfinalString[]CONTENTS={"北京","上海","广州","深圳","苏州", "南京","武汉","长沙","杭州"}; privateList<String>contentList; privateListViewmListView; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } privatevoidinit(){ mListView=(ListView)findViewById(R.id.listview); contentList=newArrayList<String>(); for(inti=0;i<CONTENTS.length;i++){ contentList.add(CONTENTS[i]); } // mListView.setAdapter(newContentAdapter(this,contentList,this)); mListView.setOnItemClickListener(this); } @Override publicbooleanonCreateOptionsMenu(Menumenu){ getMenuInflater().inflate(R.menu.main,menu); returntrue; } /** *响应ListView中item的点击事件 */ @Override publicvoidonItemClick(AdapterView<?>arg0,Viewv,intposition,longid){ Toast.makeText(this,"listview的item被点击了!,点击的位置是-->"+position, Toast.LENGTH_SHORT).show(); } /** *接口方法,响应ListView按钮点击事件 */ @Override publicvoidclick(Viewv){ Toast.makeText( MainActivity.this, "listview的内部的按钮被点击了!,位置是-->"+(Integer)v.getTag()+",内容是-->" +contentList.get((Integer)v.getTag()), Toast.LENGTH_SHORT).show(); } }
2.使用抽象类回调
Adapter类:
packagecom.ivan.adapter; importjava.util.List; importandroid.content.Context; importandroid.util.Log; importandroid.view.LayoutInflater; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.view.ViewGroup; importandroid.widget.BaseAdapter; importandroid.widget.Button; importandroid.widget.TextView; importcom.ivan.listvieweventabstract.R; publicclassContentAdapterextendsBaseAdapter{ privatestaticfinalStringTAG="ContentAdapter"; privateList<String>mContentList; privateLayoutInflatermInflater; privateMyClickListenermListener; publicContentAdapter(Contextcontext,List<String>contentList, MyClickListenerlistener){ mContentList=contentList; mInflater=LayoutInflater.from(context); mListener=listener; } @Override publicintgetCount(){ Log.i(TAG,"getCount"); returnmContentList.size(); } @Override publicObjectgetItem(intposition){ Log.i(TAG,"getItem"); returnmContentList.get(position); } @Override publiclonggetItemId(intposition){ Log.i(TAG,"getItemId"); returnposition; } @Override publicViewgetView(intposition,ViewconvertView,ViewGroupparent){ Log.i(TAG,"getView"); ViewHolderholder=null; if(convertView==null){ convertView=mInflater.inflate(R.layout.list_item,null); holder=newViewHolder(); holder.textView=(TextView)convertView .findViewById(R.id.textView1); holder.button=(Button)convertView.findViewById(R.id.button1); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.textView.setText(mContentList.get(position)); holder.button.setOnClickListener(mListener); holder.button.setTag(position); returnconvertView; } publicclassViewHolder{ publicTextViewtextView; publicButtonbutton; } /** *用于回调的抽象类 *@authorIvanXu *2014-11-26 */ publicstaticabstractclassMyClickListenerimplementsOnClickListener{ /** *基类的onClick方法 */ @Override publicvoidonClick(Viewv){ myOnClick((Integer)v.getTag(),v); } publicabstractvoidmyOnClick(intposition,Viewv); } }
Activity类:
packagecom.ivan.listvieweventdemo; importjava.util.ArrayList; importjava.util.List; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.Menu; importandroid.view.View; importandroid.widget.AdapterView; importandroid.widget.AdapterView.OnItemClickListener; importandroid.widget.ListView; importandroid.widget.Toast; importcom.ivan.adapter.ContentAdapter; importcom.ivan.adapter.ContentAdapter.MyClickListener; importcom.ivan.listvieweventabstract.R; publicclassMainActivityextendsActivityimplementsOnItemClickListener{ //模拟listview中加载的数据 privatestaticfinalString[]CONTENTS={"北京","上海","广州","深圳","苏州", "南京","武汉","长沙","杭州"}; privateList<String>contentList; privateListViewmListView; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } privatevoidinit(){ mListView=(ListView)findViewById(R.id.listview); contentList=newArrayList<String>(); for(inti=0;i<CONTENTS.length;i++){ contentList.add(CONTENTS[i]); } //实例化ContentAdapter类,并传入实现类 mListView.setAdapter(newContentAdapter(this,contentList,mListener)); mListView.setOnItemClickListener(this); } @Override publicbooleanonCreateOptionsMenu(Menumenu){ getMenuInflater().inflate(R.menu.main,menu); returntrue; } //响应item点击事件 @Override publicvoidonItemClick(AdapterView<?>arg0,Viewv,intposition,longid){ Toast.makeText(this,"listview的item被点击了!,点击的位置是-->"+position, Toast.LENGTH_SHORT).show(); } /** *实现类,响应按钮点击事件 */ privateMyClickListenermListener=newMyClickListener(){ @Override publicvoidmyOnClick(intposition,Viewv){ Toast.makeText( MainActivity.this, "listview的内部的按钮被点击了!,位置是-->"+position+",内容是-->" +contentList.get(position),Toast.LENGTH_SHORT) .show(); } }; }
两种方式的区别在于,抽象类在Activity中实现的时候,只能定义一个成员变量来实现,不能由Activity直接实现,因为Java不支持多继承。而接口既可以由Activity直接实现,也可以由其成员变量来实现。
原文链接:http://blog.csdn.net/u011895534/article/details/50439547
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。