【Android】利用ListView实现图文列表,并实现页面刷新加载

整体思路

1.当前Activity implements AbsListView.OnScrollListener
2.实现接囗的方法
3.listView注册滚动监听
4.Adapter中添加增加数据的函数
5.获得2页以后的数据后,adapter增加数据,并刷新notifyDataSetChanged();

实现步骤

/第一步:新建News类(也可从网络或数据库获取),初始化数据。/

// 创建News 类,单独文件
public class News {
    String title;
    String content;
}

// 初始化数据,该demo为静态,大项目数据来自数据库等其他地方。Activity 中的代码
private int index = 1;
private void initData(){
    /**
    * @Description: 这是一个方法,声明初始化数据方法
    */
    for (int i = 0;i < 10;i++){
        News n = new News();
        n.title = "title--"+index;
        n.content = "content--"+index;
        index++;

        // 添加到Vector<News> news 中。
        news.add(n);
    }
}

/第二步:自定义适配器填充数据,convertView减少对象的创建,ViewHolder减少组件的查找/

static class MyAdapter extends BaseAdapter{
    /**
    * @Description: 这是一个静态内部类,自定义适配器
    */
    private Context context;
    public MyAdapter(Context context){
        this.context = context;
    }

    @Override
    public int getCount() {
        return news.size();
    }

    @Override
    public Object getItem(int position) {
        return news.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {
    	// viewHolder 减少组件的查询,尽量减少到只查询一屏数量的次数
        ViewHolder viewHolder;
        // convertView 减少对象的创建,只创建一屏的空间再反复利用
        if(convertView==null){
            LayoutInflater layoutInflater = LayoutInflater.from(context);
            convertView = layoutInflater.inflate(R.layout.list_item_12,null);

            viewHolder = new ViewHolder();
            viewHolder.textView_title = convertView.findViewById(R.id.textView_title);
            viewHolder.textView_content = convertView.findViewById(R.id.textView_content);

			// 将viewHolder 存在converView
            convertView.setTag(viewHolder);
        }else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        // 获取数据,取静态成员属性 news (第一步中的)的一个数据存入局部变量 n 中,再映射到页面去。
        News n = news.get(position);
        viewHolder.textView_title.setText(n.title);
        viewHolder.textView_content.setText(n.content);

        return convertView;
    }

    static class ViewHolder{
        /**
        * @Description: 这是一个静态内部类,减少组件的查询。
        */
        TextView textView_title;
        TextView textView_content;
    }
}

/第三步:创建模拟加载数据的线程,再次加载数据,利用handler 多线程交互/

class LoadDataThread extends Thread{
    /**
    * @Description: 这是一个子线程,用于动态显示加载数据。
			     * 子线程不能直接与主线程通信。
			     * 线程之间的通信的机制:Handler
    */
    @Override
    public void run(){
        initData();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 不能让子线程通知主线程数据改变数据集,让主线程自己更新数据集。
        // myAdapter.notifyDataSetInvalidated();
        // 通过handler 给主线程发消息
        handler.sendEmptyMessage(DATA_UPDATE);

    }
}

// Handler来源: android.os.Handler;
// Handler:用于线程之间的通信
private Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        /**
        * @Description: 用于处理消息
        */
        switch (msg.what){
            case DATA_UPDATE:
                myAdapter.notifyDataSetInvalidated();
                break;
        }
    }
};

/第四步:滚动监听事件,滚动状态改变和滚动之后的改变/

//用来存储显示在尾部的最后一条数据的索引值
private int visibleLastIndex;

// 首先当前的Activity 实现AbsListView.OnScrollListener 类。因此就需要重写 onScrollStateChanged 和 onScroll 两个方法
@Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
    /**
    * @Description: 状态改变发生变化触动该方法
    * @Params:  * @param absListView
               * @param scrollState: 滚动的状态:SCROLL STATE IDLE(停止滑动) /SCROLL STATE FLING(手指离开的滑动状态) /SCROLL STATE TOUCH SCROLL(手指停留的滑动状态)
    */
    if (myAdapter.getCount() == visibleLastIndex && scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE){
        // 当活动停止且页面底部为最后一条数据
        // 启动线程,加载新数据
        new LoadDataThread().start();
    }

}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    /**
    * @Description: 滚动时触发该方法
    * @Params:  * @param absListView
               * @param firstVisibleItem: 第一个可见元素的序号
               * @param visibleItemCount:屏幕可显示的元素数量
               * @param totalItemCount: 元素总数
    */
    visibleLastIndex = firstVisibleItem + visibleItemCount-1; // 减去“正在加载中...”的那一条

}

展示一下 Activity 中的

private ListView listView;
// 数据,将其设置为static ,则内部类可直接使用
private static Vector<News> news = new Vector<>();
private MyAdapter myAdapter;
private static final int DATA_UPDATE = 0x1;//数据更新完成后的标记,1,十六进制

@Override
protected void onCreate(Bundle savedInstanceState) {
    /**
    * @Description: activity主要逻辑代码,例如setAdapter /set
    */
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main_12);
    listView = findViewById(R.id.listView);

    // 注册滑动事件
    listView.setOnScrollListener(this);

    // 设置底部loading布局页面
    View footerView = getLayoutInflater().inflate(R.layout.loading_12,null);
    listView.addFooterView(footerView);

    // 初始化数据
    initData();

    myAdapter = new MyAdapter(MainActivity12.this);
    listView.setAdapter(myAdapter);
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值