浅谈ListView

    xiaoxiao2021-04-13  39

    虽然已经有了RecyclerView,但是ListView还是有他的好处的,比较简单 如果学RecyclerView之前先学ListView会有很大的其实的,比如说ViewHolder

    首先我们应该在XML的layout处写出ListView布局

    <!-- android:divider="#000" 给间隔线加颜色 android:dividerHeight="10sp" 给间隔线设置高度 android:scrollbars="none" 设置右边的滚动条 none为没有 android:fadeScrollbars="false" 设置右边的滚动条(自动显示的) --> <!--要对ListView里面的item项做Select选择器(按下去变色) 要对整体进行设置,不能对行布局进行设置(要改变系统) listView原来有一个系统定义好的切换的一套算法 所以把他替换要改整个listView(整体) android:listSelector="@drawable/item_selector"用这个属性 由整个ListView做全局的处理 --> <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/listView" android:listSelector="@drawable/item_selector" />

    现在ListView有三种适配器

    1、数组适配器ArrayAdapter,只能显示简单是String

    实现他很简单,主要是分四部

    //1、获得ListView对象 ListView listView = (ListView) findViewById(R.id.listView); //2、准备数据源 String[] data = {" * 1、获得ListView对象" , " * 2、准备数据源" , " * 3、准备适配器Adapter" , " * 4、将适配器关联到ListView"}; //3、准备适配器 ArrayAdapter<String> adapter = new ArrayAdapter<>(this , android.R.layout.simple_list_item_1 , data); //4、适配器关联ListView listView.setAdapter(adapter);

    第二种:简单适配器SimpleAdapter,其实也是比较简单的

    实现他也是分四步:

    private List<Map<String,Object>> mMapList; //1、声明出ListView mListView = (ListView) findViewById(R.id.listView); //2、准备数据源 mMapList = new ArrayList<>(); Map<String , Object> map = new HashMap<>(); map.put("logo" , R.drawable.music); map.put("title" , "千千静音"); map.put("version" , "版本:2.4.1"); map.put("size" , "大小:32.1M"); mMapList.add(map); map = new HashMap<>(); map.put("logo" , R.drawable.calendar); map.put("title" , "计算器"); map.put("version" , "版本:1.4.1"); map.put("size" , "大小:12.1M"); mMapList.add(map); map = new HashMap<>(); //把这个R.drawable.Maps转换成图片是SimpleAdapter自己的事情,内部有实现 map.put("logo" , R.drawable.maps); map.put("title" , "地图"); map.put("version" , "版本:3.5.1"); map.put("size" , "大小:35.6M"); mMapList.add(map); map = new HashMap<>(); map.put("logo" , R.drawable.camera); map.put("title" , "照相机"); map.put("version" , "版本:1.0.0"); map.put("size" , "大小:22.12M"); mMapList.add(map); //3、设置适配器 SimpleAdapter simpleAdapter = new SimpleAdapter(this //上下文 ,mMapList //数据源 ,R.layout.item_simple_adapter //行布局 /** * Key与id要保证一一对应 必须对应相应的 * 意思为:用logo key对应的value填入R.id.logo所对应的布局中 */ ,new String[]{"logo", "title" , "version" , "size"} //键值对的key 要与键值对的key完全一样 ,new int[]{R.id.logo , R.id.title , R.id.version , R.id.size}); //行布局中的id //4、关联Adapter mListView.setAdapter(simpleAdapter);

    最后一种的BaseAdapter(个人觉得是最重要的),一般用来重写的

    里面已经包含了优化ListView了,要仔细阅读哦

    首先从写BaseAdapter,继承BaseAdapter /** *ListView的优化(控制次数)---》先一级后二级 * 每次调用getView()方法都要执行两个耗时操作 * 1、inflate方法(获得布局对象)----》》一级优化 * 通过用convertView解决 * 2、findViewById方法(获得控件对象)----》》二级优化 * 通过自定义的ViewHolder解决 * * * 看到这个优化很容易就想起了RecyclerView的ViewHolder,现在终于知道了Viewholder的来源了吧 */ public class MyAdapter extends BaseAdapter{ private List<Map<String , Object>> list; //传入的数据 private LayoutInflater inflater; //反射器 public MyAdapter(Context context) { inflater = LayoutInflater.from(context); } public void setList(List<Map<String , Object>> list){ this.list = list; } /** * 返回数据源的数量 决定了界面一共多少行 * @return */ @Override public int getCount() { return list.size(); } @Override public Object getItem(int i) { return list.get(i); } @Override public long getItemId(int i) { return i; } /** * 自定义适配器的核心方法 * 通过LayoutInflater反射出行布局对象,并且填充上数据内容 * 返回一个视图 填充好布局 等着调用 每显示一行调用一次 * * ConvertView的工作原理 * 无论总量为多少,Android只渲染当前屏的item项 * 被渲染过的Item项,它的视图对象会被保存到Recycler中 * 新滑入屏幕的item项将从Recycler中直接获取缓存的视图,而不是再通过 * inflate方法反射获取 * 结论: * 无论总量是多少,Recycler中只需要缓存N+1个视图对象,即可保证整个ListView * 的显示(N为一屏幕可显示的Item数) * 无论总量为多少,inflate方法最多调用N+1次 * * @param i * @param convertView 代表从缓冲区里面拿到的缓冲视图对象 一开始缓冲区里面什么都没有为null 后来有了就直接取出就可 * @param viewGroup * @return */ @Override public View getView(int i, View convertView, ViewGroup viewGroup) { ViewHolder holder = null; /** * 反射器:把XML的布局反射为一个view对象 */ if(convertView == null) { convertView = inflater.inflate(R.layout.item_simple_adapter, null); holder = new ViewHolder(); holder.logo= (ImageView)convertView.findViewById(R.id.logo); holder.title =(TextView)convertView.findViewById(R.id.title); holder.version=(TextView)convertView.findViewById(R.id.version); holder.size = (TextView)convertView.findViewById(R.id.size); //viewHolder与convertView关联起来 convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } Map<String , Object> map = list.get(i); holder.logo.setImageResource((Integer) map.get("logo")); holder.title.setText( (String)map.get("title")); holder.version.setText((String) map.get("version")); holder.size.setText((String) map.get("size")); return convertView; } private class ViewHolder { ImageView logo; TextView title; TextView version; TextView size; } }

    然后使用我们从写的BaseAdapter private List<Map<String, Object>> mMapList; //1、声明出ListView mListView = (ListView) findViewById(R.id.listView); //2、准备数据源 mMapList = new ArrayList<>(); Map<String, Object> map = new HashMap<>(); map.put("logo", R.drawable.music); map.put("title", "千千静音"); map.put("version", "版本:2.4.1"); map.put("size", "大小:32.1M"); mMapList.add(map); map = new HashMap<>(); map.put("logo", R.drawable.calendar); map.put("title", "计算器"); map.put("version", "版本:1.4.1"); map.put("size", "大小:12.1M"); mMapList.add(map); map = new HashMap<>(); //把这个R.drawable.Maps转换成图片是SimpleAdapter自己的事情,内部有实现 map.put("logo", R.drawable.maps); map.put("title", "地图"); map.put("version", "版本:3.5.1"); map.put("size", "大小:35.6M"); mMapList.add(map); map = new HashMap<>(); map.put("logo", R.drawable.camera); map.put("title", "照相机"); map.put("version", "版本:1.0.0"); map.put("size", "大小:22.12M"); mMapList.add(map); //3、设置适配器 MyAdapter adapter = new MyAdapter(this); adapter.setList(mMapList); //4、关联Adapter mListView.setAdapter(adapter); //5、对每一项做监听事件 不是对listView而是对里面的每一项 //短瞬间的点击 mListView.setOnItemClickListener(this); //长按 mListView.setOnItemLongClickListener(this); } @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { Toast.makeText(this , "点击item"+ i , Toast.LENGTH_SHORT).show(); } /** * 返回值 * true 表示消化掉事件,事件不会继续传递 * false 表示不消化事件,事件将继续传递下去 * 结论:如果希望长按事件后,不再触发点击事件,则应将返回值设置为true * @param adapterView * @param view * @param i * @param l * @return */ @Override public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) { Toast.makeText(this , "长按item"+ i , Toast.LENGTH_SHORT).show(); return true; }
    转载请注明原文地址: https://ju.6miu.com/read-668579.html

    最新回复(0)