Android学习----自定义Adapter实现ListView
2015-05-14 21:52
405 查看
前言:
对于ListView而言,自定义的Adapter对于显示复杂的界面有很大的灵活性 。使用自定义的Adapter需要继承BaseAdapter,然后重写getCount(),getView(),getItem,getItemId()4个方法。adapter在绘制listview时是先根据getCount()获得底层数据的个数来判断绘制item的个数,然后通过getView绘制单个item。
ListView实现的效果如下:
详细步骤:
1.新建Activity,在对应的布局文件中放置listview,textview和图片按钮;
2.新建一个布局文件,布局文件中包含图片,两个textview,一个checkbox
3.自定义MyAdapter继承BaseAdapter重写4个方法;
4.给listview绑定适配器,给按钮添加点击事件。
具体实现:
布局文件:(item.xml)
layout_main.xml
java代码:
代码均已测试,无明显bug。因本人水平有限,出错之处在所难免,欢迎指正。
对于ListView而言,自定义的Adapter对于显示复杂的界面有很大的灵活性 。使用自定义的Adapter需要继承BaseAdapter,然后重写getCount(),getView(),getItem,getItemId()4个方法。adapter在绘制listview时是先根据getCount()获得底层数据的个数来判断绘制item的个数,然后通过getView绘制单个item。
ListView实现的效果如下:
详细步骤:
1.新建Activity,在对应的布局文件中放置listview,textview和图片按钮;
2.新建一个布局文件,布局文件中包含图片,两个textview,一个checkbox
3.自定义MyAdapter继承BaseAdapter重写4个方法;
4.给listview绑定适配器,给按钮添加点击事件。
具体实现:
布局文件:(item.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" /> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/img" android:textSize="20sp" android:text="" /> <TextView android:id="@+id/info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/img" android:layout_toRightOf="@+id/img" android:textSize="12sp" android:text="" /> <!--注意checkBox中focusable="false",如果不设置的话,listview的item点击事件没有用,因为item此时不能获取焦点--> <CheckBox android:id="@+id/cb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:focusable="false" android:text="" /> </RelativeLayout>
layout_main.xml
<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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_toLeftOf="@id/title" android:text="@string/title" /> <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/imageButton1" > </ListView> <ImageButton android:id="@+id/imageButton1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignRight="@+id/listView1" android:visibility="invisible" android:src="@drawable/delete" /> </RelativeLayout>
java代码:
public class MainActivity extends Activity { ListView listview; //list中存储listview的每一行的内容,每一行的内容存储在map中,根据键可以取出对应的值 List<Map<String,Object>> list; ImageButton imgbtn; //positions中保存的是当前选中的所有元素 List<Map<String,Object>> positions=new ArrayList<Map<String,Object>>(); MyAdapter adapter=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listview=(ListView) findViewById(R.id.listView1); imgbtn=(ImageButton) findViewById(R.id.imageButton1); list=getData(); adapter =new MyAdapter(this,list); listview.setAdapter(adapter); listview.setOnItemClickListener(cl); /* * 根据选中的内容,删除listview中的显示 * positions中存放的是当前所有的选中项,每次删除完毕之后,应该把它清空,不然下次删除的时候 * 它还有数据,此时会出现问题。 * 删除完毕之后调用adapteradapter.notifyDataSetChanged(); 刷新view */ imgbtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getApplicationContext(), "delete", Toast.LENGTH_SHORT).show(); //list.remove(int location)不能在for循环中使用 for(int i=0;i<positions.size();i++){ list.remove(positions.get(i)); } //每一次删除完之后,把当前positions的元素删除 Iterator<Map<String,Object>> iterator=positions.iterator(); while(iterator.hasNext()){ iterator.next(); iterator.remove(); } adapter.notifyDataSetChanged(); //删除之后设置按钮不显示 imgbtn.setVisibility(View.INVISIBLE); } }); } //点击时确定当前选中的checkBox @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } /* * 设置item的点击事件 */ OnItemClickListener cl=new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub Toast.makeText(getApplicationContext(), (String)list.get(position).get("title"), Toast.LENGTH_SHORT).show(); } }; /* * 提供音乐列表中的数据,包括每行数据中的歌手图片,歌曲名称,歌曲简介 */ public List<Map<String,Object>> getData(){ List<Map<String,Object>> list=new ArrayList<Map<String,Object>>(); Map<String,Object> map=new HashMap<String,Object>(); map.put("title", "真的爱你"); map.put("info", "无法可修饰的一对手,带出温暖永远在背后"); map.put("img", R.drawable.huangjiaju); list.add(map); map=new HashMap<String,Object>(); map.put("title", "一生有你"); map.put("info", "多少人曾爱慕你年轻时的容颜"); map.put("img", R.drawable.shuimunianhua); list.add(map); map=new HashMap<String,Object>(); map.put("title", "Moves Like Jagger"); map.put("info", "Just you shoot for the stars,If it feels right"); map.put("img", R.drawable.maroon5); list.add(map); return list; } //创建一个ViewHolder类,每个类对象包含ListView的Item的所有控件元素 private final class ViewHolder{ public ImageView img; public TextView title; public TextView info; public CheckBox cb; } //自定义adapter继承自BaseAdapter,实现两个方法 /* * */ class MyAdapter extends BaseAdapter{ private LayoutInflater inflater; private List<Map<String,Object>> list; /* * 三种方式获取XML布局文件 * 1.LayoutInflater inflater=LayoutInflater.from(context); * 2.LayoutInflater inflater=getLayoutInflater(); * 3.LayoutInflater inflater=(LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE); */ public MyAdapter(Context context,List<Map<String,Object>> list){ inflater=LayoutInflater.from(context); this.list=list; } @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } /* * (non-Javadoc) * holder里面放置每个item的所有控件 * 当convertview为空时,说明之前没有创建过这个Item,实例化一个新的view,通过setTag方法把holder放在convertView中 * 当convertview不为空时,此时可以直接从convertView取出,使用getTag * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup) */ @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder=null; if(convertView==null){ holder=new ViewHolder(); convertView=inflater.inflate(R.layout.item, null); holder.img=(ImageView) convertView.findViewById(R.id.img); holder.title=(TextView) convertView.findViewById(R.id.title); holder.info=(TextView) convertView.findViewById(R.id.info); holder.cb=(CheckBox) convertView.findViewById(R.id.cb); convertView.setTag(holder); }else{ holder=(ViewHolder) convertView.getTag(); } holder.img.setBackgroundResource((Integer) list.get(position).get("img")); holder.title.setText((CharSequence) list.get(position).get("title")); holder.info.setText((CharSequence) list.get(position).get("info")); holder.cb.setOnCheckedChangeListener(new checkedChangeListener(position)); holder.cb.setChecked(false);//特别说明:把它全部设为false,是因为每次删除完之后会出现下一个界面上显示为选中但是不能删除,只有先取消再点击才有效,这应该是界面的绘制问题(猜测) return convertView; } /* * MyAdapter中的内部类实现了OnCheckedChangeListener接口, * 提供一个构造函数,此处的构造函数的作用是传递了一个position参数, * 可以与getView中的position关联起来,也可以在类内部的onCheckedChanged方法中使用。 * onCheckedChanged方法是在checkBox的状态改变时被调用的,为了删除按钮的点击事件中 * 能够获取到当前选中的所有项,所以每当选中一项,就把当前项放在一个list列表中,这样 * 在删除按钮处理点击事件时,就可以轻松完成。 * 一个小小的效果:有选中项时删除按钮显示,否则按钮消失。 * 实现:按钮初始状态为不可见,每当选中一项则设为可见,每当取消一项,判断是否还有选中, * 若没有选中项,设为不可见 */ class checkedChangeListener implements OnCheckedChangeListener{ int position; public checkedChangeListener(int position){ this.position=position; } @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { /* * 当某一个checkbox被选中时,先显示点击了当前item,然后把当前元素作为对象加入positions列表当中 * 设置删除按钮为可见 */ if(isChecked){ imgbtn.setVisibility(View.VISIBLE); Toast.makeText(getApplicationContext(), "点击了"+(String)list.get(position).get("title"),Toast.LENGTH_SHORT).show(); positions.add(list.get(position)); }else{ /* * 当该项被取消时,先显示取消了此项,然后把当前项从列表中删除, * 每次删除完之后,判断是否还有选中项,如果没有选中项,设置删除按钮不可见 */ Toast.makeText(getApplicationContext(), "取消了"+(String)list.get(position).get("title"),Toast.LENGTH_SHORT).show(); positions.remove(list.get(position)); //判断当前是否有选中项,若没有,隐藏删除按钮 if(positions.size()==0){ imgbtn.setVisibility(View.INVISIBLE); } } } } /* * 此处没有用到下面两个方法,故不作说明 * (non-Javadoc) * @see android.widget.Adapter#getItem(int) */ @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } } }
代码均已测试,无明显bug。因本人水平有限,出错之处在所难免,欢迎指正。
相关文章推荐
- android 学习笔记:自定义通用ListView/GridView,实现ListAdapter 类
- 2014-10-27Android学习------布局处理(八)------自定义ListView的监听事件和Adapter的实现-----城市列表应用程序
- android自定义BaseAdapter,实现从网络加载包含图片的listview
- Android 自定义Adapter以实现自定义填充ListView的Item
- Android之Listview(item为单选题)自定义adapter,像考试时前面的10几道单选题的实现
- Android 自定义Adapter实现多视图Item的ListView
- Android开发学习之路-自定义ListView(继承BaseAdapter)
- Android学习第五天————ExpandableListView组件通过适配器BaseExpandableListAdapter实现两层列表项
- Android中自定义Adapter实现ListView动态刷新进度条
- Android中自定义Adapter实现ListView动态刷新进度条
- Android中自定义Adapter实现ListView动态刷新进度条
- ANDROID中自定义ADAPTER实现LISTVIEW动态刷新进度条
- Android中ListView同过自定义布局并使用SimpleAdapter的方式实现数据的绑定
- Android中ListView的自定义Adapter监听Item中Button,实现跳转到一个新的Activity
- Android ListView自定义Adapter实现仿QQ界面
- android 自定义ListView实现下拉刷新、分页加载、点击事件——自定义控件学习(七)
- android 基础-自定义listView的实现 adapter 方法解析
- Android中listview布局,自定义adapter,长按,点击,退出的demo
- Android中Spinner下拉列表(使用ArrayAdapter和自定义Adapter实现)
- Android客户端之“微服私访”App的系统学习(五)使用Picasso实现轮播图以及使用自定义View实现个人中心页面