• Android UI组件----自定义ListView实现动态刷新


    【声明】

    欢迎转载,但请保留文章原始出处→_→

    生命壹号:http://www.cnblogs.com/smyhvae/

    文章来源:http://www.cnblogs.com/smyhvae/p/3910541.html

     

    【正文】

    一、具体步骤:

    (1)在activiy_main.xml中加一个ListView控件;再添加一个item的模板activity_main_item.xml,加一个底部加载的视图activity_main_load.xml;

    (2)初始化item中的数据;

    (3)自定义适配器BaseAdapter;

    (4)ListiView绑定监听器OnScrollListener,并实现该监听器的两个方法:

      • public void onScrollStateChanged(AbsListView view, int scrollState)
      • public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount)

          注:如果屏幕滑到最下面了,并且scrollState的状态为:滚动完毕之后ListView处于停止状态(手离开屏幕),此时可以加载新数据了

    (5)通过额外的线程,来模拟加载新数据;

    (6)新数据加载完成后,通过handle通知主线程,将这个新数据显示在UI界面上(因为涉及到线程安全问题),此时要调用notifyDataSetChanged()方法来刷新。

           注:handler为线程之间通信的桥梁

    二、代码实现: 

    完整版代码如下:

    activiy_main.xml代码如下:

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     tools:context=".MainActivity" >
     6     <ListView
     7         android:id="@+id/listView1"
     8         android:layout_width="match_parent"
     9         android:layout_height="match_parent" >
    10     </ListView>
    11 </LinearLayout>

    注:为优化起见,第9行的代码一定要写成"match_parent",而不是“wrap_content”(解释略)

    activity_main_item.xml代码如下:(作为一个item的模板)

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:orientation="vertical" >
     6     <TextView
     7     android:id="@+id/textView1_title"
     8     android:layout_width="match_parent"
     9     android:layout_height="wrap_content"
    10     android:text="Large Text"
    11     android:textAppearance="?android:attr/textAppearanceLarge" />
    12     <TextView
    13         android:id="@+id/textView2_content"
    14         android:layout_width="match_parent"
    15         android:layout_height="wrap_content"
    16         android:text="TextView" />
    17 </LinearLayout>

    activity_main_load.xml代码如下:(作为加载时底部的显示)

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="wrap_content"
     5     android:orientation="horizontal"
     6     android:gravity="center" >
     7 
     8     <ProgressBar
     9         android:id="@+id/progressBar1"
    10         android:layout_width="25dp"
    11         android:layout_height="25dp" />
    12 
    13     <TextView
    14         android:id="@+id/textView1"
    15         android:layout_width="wrap_content"
    16         android:layout_height="wrap_content"
    17         android:text="正在加载···" />
    18 
    19 </LinearLayout>

    MainActivity.java代码如下:

      1 package com.smyhvae.smyh005listview5;
      2 
      3 import java.util.Vector;
      4 
      5 import android.app.Activity;
      6 import android.os.Bundle;
      7 import android.os.Handler;
      8 import android.os.Message;
      9 import android.view.Menu;
     10 import android.view.View;
     11 import android.view.ViewGroup;
     12 import android.widget.AbsListView;
     13 import android.widget.AbsListView.OnScrollListener;
     14 import android.widget.BaseAdapter;
     15 import android.widget.ListView;
     16 import android.widget.TextView;
     17 
     18 public class MainActivity extends Activity {
     19 
     20     private ListView listView;
     21     Vector<News> news = new Vector<News>();
     22     //private ArrayList<News> news = new ArrayList<News>();上面一行与这一行,二选一
     23     MyAdapter myAdapter;
     24     
     25     @Override
     26     protected void onCreate(Bundle savedInstanceState) {
     27         super.onCreate(savedInstanceState);
     28         setContentView(R.layout.activity_main);
     29         listView = (ListView)findViewById(R.id.listView1);
     30         
     31         listView.setOnScrollListener(new ListViewListener());  //绑定监听器
     32         
     33         //设置底部视图
     34         View footer = getLayoutInflater().inflate(R.layout.activity_main_load, null);
     35         listView.addFooterView(footer);        
     36         
     37 //        initData();
     38         new LoadDataThread().start();//加载数据的工作线程
     39             
     40         myAdapter = new MyAdapter();
     41         listView.setAdapter(myAdapter);
     42     }
     43 
     44    //定义一个数据的类
     45     class News {
     46         String title;
     47         String content;
     48     }
     49     
     50     int index = 1;//数据的记数器(索引)
     51     //初始化数据
     52     void initData(){        
     53         System.out.println("initData");
     54         for (int i = 0; i < 15; i++) {
     55             News n = new News();  //这句话一定要放在循环的里面,否则每个item显示的内容都是一样的
     56             n.title = "title-"+index;
     57             n.content = "content"+index;
     58             index++;
     59             news.add(n);  //这一步很关键,我就是少了这一步,导致运行时,界面为空
     60         }
     61     }
     62     
     63     
     64     
     65     //自定义适配器
     66     class MyAdapter extends BaseAdapter{
     67 
     68         @Override
     69         public int getCount() {
     70             // TODO Auto-generated method stub
     71             return news.size();
     72         }
     73         public Object getItem(int position) {
     74             return news.get(position);
     75         }
     76 
     77         @Override
     78         public long getItemId(int position) {
     79             return position;
     80         }
     81 
     82         @Override
     83         public View getView(int position, View convertView, ViewGroup parent) {
     84             ViewHolder viewHolder = new ViewHolder();
     85             //通过下面的条件判断语句,来循环利用。如果convertView = null ,表示屏幕上没有可以被重复利用的对象。
     86             if(convertView==null){
     87                 //创建View
     88                 convertView = getLayoutInflater().inflate(R.layout.activity_main_item, null);
     89                 viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.textView1_title);
     90                 viewHolder.tvContent = (TextView) convertView.findViewById(R.id.textView2_content);
     91                 convertView.setTag(viewHolder);
     92             }else{
     93                 viewHolder = (ViewHolder)convertView.getTag();
     94             }
     95             //从Vector中取出数据填充到ListView列表项中
     96             News n = news.get(position);
     97             viewHolder.tvTitle.setText(n.title);
     98             viewHolder.tvContent.setText(n.content);
     99             return convertView;
    100         }
    101         
    102     }
    103 
    104     static class ViewHolder{
    105         TextView tvTitle;
    106         TextView tvContent;
    107     }    
    108 
    109     
    110 
    111     
    112     //实现ListView的监听器的接口
    113     int visibleLastIndex = 0; //最后一个显示的索引    
    114     public class ListViewListener implements OnScrollListener{        
    115         @Override
    116         public void onScrollStateChanged(AbsListView view, int scrollState) {
    117             //如果屏幕滑到最下面了,并且scrollState的状态为:滚动完毕之后ListView处于停止状态(手离开屏幕),
    118             if(visibleLastIndex==myAdapter.getCount() && scrollState==OnScrollListener.SCROLL_STATE_IDLE){
    119                 new LoadDataThread().start();//如果满足上面的条件,此时,可以加载新数据了
    120             }
    121         }
    122 
    123         @Override
    124         public void onScroll(AbsListView view, int firstVisibleItem,
    125             int visibleItemCount, int totalItemCount) {
    126             visibleLastIndex = firstVisibleItem+visibleItemCount-1;
    127             
    128         }
    129         
    130     }
    131     
    132     //额外开启一个线程,模拟加载数据
    133     class LoadDataThread extends Thread{
    134         @Override
    135         public void run() {
    136             initData();
    137             try {
    138                 Thread.sleep(2000);//休眠两秒
    139             } catch (InterruptedException e) {
    140                 // TODO Auto-generated catch block
    141                 e.printStackTrace();
    142             }
    143             
    144             //新数据加载完成后,通过handle通知主线程,将这个新数据显示在UI界面上(因为涉及到线程安全问题)
    145             handler.sendEmptyMessage(1);
    146         }
    147     }      
    148     
    149     //handler为线程之间通信的桥梁    
    150     private Handler handler = new Handler(){
    151         public void handleMessage(Message msg) {
    152             switch(msg.what){
    153             case 1:  //根据上面的提示,当Message为1,表示数据处理完了,可以通知主线程了
    154                  myAdapter.notifyDataSetChanged();        //这个方法一旦调用,UI界面就刷新了
    155                 break;
    156                 
    157             default :
    158                 break;
    159             }
    160         }
    161         
    162     };
    163     
    164     
    165     @Override
    166     public boolean onCreateOptionsMenu(Menu menu) {
    167         // Inflate the menu; this adds items to the action bar if it is present.
    168         getMenuInflater().inflate(R.menu.main, menu);
    169         return true;
    170     }
    171 
    172 
    173     
    174 }

    运行后,显示结果如下:

    下图依次为:刚运行时、滑动到底部时、刷新之后的效果

    三、总结:

    • 监听事件处理的接口:OnScrollListener
    • Adapter的刷新方法:notifyDataSetChanged()

    【工程文件】

    密码:bqsy
     

    我的公众号

    想学习代码之外的软技能?不妨关注我的微信公众号:生命团队(id:vitateam)。

    扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外:

  • 相关阅读:
    maven报错【Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.6 or one of】
    Srping框架中使用@query注解实现复杂查询
    FreeMarker自定义TemplateDirectiveModel
    SpringMVC和Freemarker整合,带自定义标签的使用方法
    关于FreeMarker自定义TemplateDirectiveModel
    滑块验证码【插件待研究】
    注册页面 注册码【欠缺较多 待完善】
    IO流-文件的写入和读取
    Date、String、Calendar相互转化
    Runtime类
  • 原文地址:https://www.cnblogs.com/qianguyihao/p/3910541.html
Copyright © 2020-2023  润新知