ListView优化

来源:互联网 发布:天九幸福集团 知乎 编辑:程序博客网 时间:2024/06/05 05:03

开题

拖延症是指自我调节失败,在能够预料后果有害的情况下,仍然把计划要做的事情往后推迟的一种行为。拖延是一种普遍存在的现象,一项调查显示大约75%的大学生认为自己有时拖延,50%认为自己一直拖延。严重的拖延症会对个体的身心健康带来消极影响,如出现强烈的自责情绪、负罪感,不断的自我否定、贬低,并伴有焦虑症、抑郁症等心理疾病,一旦出现这种状态,需要引起重视。——来自百科
拖延症是会传染的,就算自己这边没有拖延,但对方也会拖延,进而导致自己这边也开始拖延起来!现在这个项目我这边已经是完工了,但是对方迟迟没有搞定,导致整个项目无法提交。
这就是拖延症的可怕,我们不仅是与自己的拖延症作战,而是与所有有关人士的拖延症作战,决定项目是否能够提交,在于那个最慢的人。
既然决定权已经不在我的手上,那么我也可以做做其他事情,像是现在这样写写博客。
这次就介绍一下ListView中比较简单但又非常重要的优化。

ListView

MVC架构

  • M:模型层 —- javaBean —- personList
  • V:视图层 —- jsp —- ListView
  • C:控制层 —- servlet —- Adapter

Adapter

  • ListView的每个条目都是一个View对象
  • 首先我们定义一个类MyAdapter,继承自BaseAdapter,BaseAdapter是抽象类,所以我们需要实现四个方法:getCount();getView();getItem();getItemId();
  • class MyAdapter extends BaseAdapter{//系统调用,用来获知集合中有多少条元素@Overridepublic int getCount() {    return personList.size();}//由系统调用,获取一个View对象,作为ListView的条目//position:本次getView方法调用所返回的View对象,在listView中是处于第几个条目,那么position的值就是多少@Overridepublic View getView(int position, View convertView, ViewGroup parent) {    Person p = personList.get(position);    System.out.println("getView调用:" + position + ";" + convertView);    View v = null;//方法1:把布局文件填充成一个View对象    v = View.inflate(ListViewActivity.this, R.layout.item_listview, null);//方法2:获取布局填充器对象//          LayoutInflater inflater = LayoutInflater.from(MainActivity.this);//          使用布局填充器填充布局文件//          View v2 = inflater.inflate(R.layout.item_listview, null);//方法3://          LayoutInflater inflater2 = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);//          View v3 = inflater2.inflate(R.layout.item_listview, null);    //通过资源id查找组件,注意调用的是View对象的findViewById    TextView tv_name = (TextView) v.findViewById(R.id.tv_name);    tv_name.setText(p.getName());    TextView tv_phone = (TextView) v.findViewById(R.id.tv_phone);    tv_phone.setText(p.getPhone());    TextView tv_salary = (TextView) v.findViewById(R.id.tv_salary);    tv_salary.setText(p.getSalary());    return v;}@Overridepublic Object getItem(int position) {    return null;}@Overridepublic long getItemId(int position) {    return 0;}}`

1
2

  • 注意,这里重新加载的2,1,0,11,之前并没有被销毁,而是在缓存中,如果缓存满了,才会被销毁。这里条目2,1,0,11,并没有必要被重新加载,我们可以直接从缓存中取出。
    ListView为什么要做这么一个缓存的机制,主要是因为填充操作是比较耗费资源的操作:
    v = View.inflate(ListViewActivity.this, R.layout.item_listview, null);
    尤其是你的布局文件R.layout.item_listview,如果非常的华丽,填充过程会更加耗费资源。如果我们不断的滑动,就会不断的加载,看程序就会崩溃!
    崩溃图示
    报错是OutOfMemoryError,扛不住了。
  • 所以每次我们调用getView()方法都v = View.inflate()是不对的。应该是,没缓存加载,有缓存则直接调。
  • public View getView(int position, View convertView, ViewGroup parent)。加粗部分就是系统缓存的View
  • 所以我们要做一个这样的改动
    //判断条目是否有缓存
    if(convertView == null){
    //方法1:把布局文件填充成一个View对象
    v = View.inflate(ListViewActivity.this, R.layout.item_listview, null);
    }
    else{
    v = convertView;
    }
    如果有缓存不加载,没有缓存则加载。就这么一个小小的改动,你可以试试程序还会不会崩。
    不会溢出
  • 号外 也许你特别爱探究,想到,这里如果放到if(convertView == null){
    TextView tv_name = (TextView) v.findViewById(R.id.tv_name);
    tv_name.setText(p.getName());
    TextView tv_phone = (TextView) v.findViewById(R.id.tv_phone);
    tv_phone.setText(p.getPhone());
    TextView tv_salary = (TextView) v.findViewById(R.id.tv_salary);
    tv_salary.setText(p.getSalary());}
    会不会更好,textView都不用每次赋值。你可以试一试。
  • 其实这样是不可以的。因为ListView如果往上翻,0会首先缓存,有缓存之后12加载的就是0。
  • 补充,程序onCreate方法,我的personList是从数据库加载的,数据库是用请看我的文章《android数据存储》:
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    personList = new ArrayList<Person>();//把数据库的数据查询出来MyOpenHelper oh = new MyOpenHelper(this);SQLiteDatabase db =  oh.getWritableDatabase();Cursor cursor = db.query("person", null, null, null, null, null, null, null);while(cursor.moveToNext()){    String _id = cursor.getString(0);    String name = cursor.getString(1);    String salary = cursor.getString(2);    String phone = cursor.getString(3);    Person p = new Person(_id, name, phone, salary);    personList.add(p);}ListView lv = (ListView) findViewById(R.id.oplist);lv.setAdapter(new MyAdapter());
1 0
原创粉丝点击