时间:2021-05-19
对于ListVie来说,数据项的设置有很多种方式,而自定义实现BaseAdapter是最经常用的了,那么这里我们来讲解一下自定义实现BaseAdapter的普通实现。
MainActivity.java
public class MainActivity extends AppCompatActivity { //数据源 private List<String> data; //ListView控件 private ListView mList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获取控件ID mList = (ListView)findViewById(R.id.mList); data = new ArrayList<>(); //数据赋初值 for(int i = 0; i < 20; i ++){ data.add("数据项"+ i); } //创建适配器 MyAdapter adapter = new MyAdapter(data); //设置适配器 mList.setAdapter(adapter); }}MyAdapter.java
public class MyAdapter extends BaseAdapter { //数据项 private List<String> data; public MyAdapter(List<String> data) { this.data = data; } @Override /** * 返回数据源的长度,表示ListView的item项显示多少个 */ public int getCount() { return data == null ? 0 : data.size(); } /** * 返回指定位置的 item 数据源的对象,这个方法为手动调用,非设置适配器时候调用 * @param position 指定位置 * @return */ @Override public Object getItem(int position) { return data.get(position); } /** * 返回指定位置的 item的标记 id,很少使用到 * @param position 指定位置 * @return */ @Override public long getItemId(int position) { return position; } /** * 工厂方法,设置好模板,返回视图,每个视图是怎么显示出来的, 核心点,怎么产生一个View, View 里面怎么 * 放置对应的内容 * @param position 当前加载的位置 * @param convertView 复用的view * @param parent listview * @return */ @Override public View getView(int position, View convertView, ViewGroup parent) { //获取布局 View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,null); //获取布局中的TextView控件1 TextView tv1 = (TextView) view.findViewById(R.id.mTv1); //设置控件1的数据 tv1.setText(data.get(position)); //获取布局中的TextView控件2 TextView tv2 = (TextView) view.findViewById(R.id.mTv2); //设置控件2数据 tv2.setText(data.get(position)); return view; }}以上是普通的使用,但是这样的效率会非常低,因为每次加载一个item都会调用getView方法,而每次都会去解析一个view布局,这样一直解析会对内存的消耗特别大,所以效率会大大降低,那么我们在此基础上先稍微优化下,让view解析次数变少一点,最基本的操作就是采用convertView复用控件来进行操作。
这里只需要修改getView方法中的处理:
@Override public View getView(int position, View convertView, ViewGroup parent) { Log.i("TAG", "getView: " + position); if (convertView == null) { convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null); } TextView tv1 = (TextView) convertView.findViewById(R.id.mTv1); tv1.setText(data.get(position)); TextView tv2 = (TextView) convertView.findViewById(R.id.mTv2); tv2.setText(data.get(position)); return convertView; }}以上的处理方式相比上面的处理方式相对于上面的解析要少很多次,因为第一种实现方式是任何一个需要显示的控件都需要去解析一次布局,而这里我们使用了系统给的converView复用控件,他的基本原理是,系统会自动创建好界面显示n个item的数据项(比如一个界面可见的item为5个,默认创建好了5个view布局对象),保存到converView中(这里可以把他当成一个循环数组吧,他的总容量相当于是n + 1),当显示第n + 1个的时候,他会解析一次,之后的显示的view布局会复用自己的converView中已经存在的布局项,而不再去重新解析。简单的画个图吧:
如上图所示,相当于只解析了6次,其他的view都是复用的,所以相对于上面的实现,这样的效率会相对高一点,不过,虽然解析的次数是少了,但是每个控件需要findViewById还是会重复调用,而且其实每个不同对象view中的控件id对象肯定是相同的,所以,重复的去调用又会显得效率不高,那么如何解决不重复findViewById呢,那就要使用到我们的优化布局了,关于优化,将在下一篇博客中介绍。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
上一篇中我们介绍了自定义实现BaseAdapter的普通实现布局,然而上一章也说了普通实现的方式效率会很低,而且对系统开销也很大,所以,那样的实现是为了让初学者
前言在Android开发中,我们有时需要实现类似IOS的对话框。今天我就来总结下,如何通过自定义的开发来实现类似的功能。自定义Dialog我们知道Android
本文实例讲述了Android编程实现自定义进度条颜色的方法。分享给大家供大家参考,具体如下:android自定义进度条颜色先看图基于产品经理各种自定义需求,经过
Android自定义布局竖向的ViewPager的实现效果图:这个自定义控件涉及到的知识点:自定义ViewGroup中onMeasure和onLayout的写法
在Android开发中,往往要用到自定义的控件来实现我们的需求或效果。在使用自定义控件时,难免要用到自定义属性,那怎么使用自定义属性呢?在文件res/value