android实现ListView或GridView中item的倒数功能

有时在开发中可能会遇到当未到某个时间时需要让ListView或GridView中的相应item进行倒数的需求,此时,如果还是按照常见的ListView或GridView的Adapter的写法+计时功能来实现的话,则当滚动ListView或GridView的时候,item就可能会出现复用问题(即不需要进行倒数或当前item的倒数已经结束了,却还会出现倒数的现象),因此,为了解决这种问题,需要进行倒数时,重新遍历当前对象的集合,然后让每个对象的相应时间值减1,最后再通过Adapter的notifyDataSetChanged方法静态的刷新界面。

效果如下所示:

MainActivity的代码如下所示:

package com.abner.countdownforlistview;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ListView lv_goods;
    private GoodsAdapter adapter;

    private int result = -1;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                result = adapter.countDownTime();
                if (result == 0) {
                    handler.removeMessages(1);
                    return;
                } else {
                    adapter.notifyDataSetChanged();
                    handler.sendEmptyMessageDelayed(1, 1000);
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv_goods = (ListView) findViewById(R.id.lv_goods);
        initData();
    }

    private void initData() {
        List<Goods> goodsList = new ArrayList<>();
        for (int i = 0; i < 15; i++) {
            Goods goods = new Goods();
            goods.setGoodsName("这是商品名称:" + i);
            goods.setPrice(i * 26);
            goods.setTime(i % 3 == 0 ? i * 8 + 62 : 0);
            goodsList.add(goods);
        }
        adapter = new GoodsAdapter(this, goodsList);
        lv_goods.setAdapter(adapter);
        handler.sendEmptyMessageDelayed(1, 1000);
    }
}

在这个MainActivity中,可以看到通过Handler实现了倒数功能,在为ListView设置完Adapter后即通过handler的sendEmptyMessageDelayed方法发送了一条消息,然后在handler的handleMessage方法中通过调用在adapter中声明的countDownTime方法对相应的对象集合进行遍历再设置相应的值,最后通过返回的result进行判断倒数是否已经结束,如果已经结束则移除消息,否则继续发送消息进行倒数操作。

ListView的GoodsAdapter的代码如下所示:

package com.abner.countdownforlistview;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.List;

import static com.abner.countdownforlistview.R.id.tv_price;

/**
 * Created by abner on 2016/5/6.
 */
public class GoodsAdapter extends BaseAdapter {
    private Context context;
    private List<Goods> goodsList;

    public GoodsAdapter(Context context, List<Goods> goodsList) {
        this.context = context;
        this.goodsList = goodsList;
    }

    @Override
    public int getCount() {
        return goodsList == null ? 0 : goodsList.size();
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.lv_goods_item, null);
            holder.tv_goodsName = (TextView) convertView.findViewById(R.id.tv_goodsName);
            holder.tv_price = (TextView) convertView.findViewById(tv_price);
            holder.tv_time = (TextView) convertView.findViewById(R.id.tv_time);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        final Goods goods = goodsList.get(position);
        holder.tv_goodsName.setText(goods.getGoodsName());
        holder.tv_price.setText("¥" + goods.getPrice());

        final int time = goods.getTime();
        if (time > 0) {
            holder.tv_time.setText(getTimeStr(time) + "后开始");
        } else {
            holder.tv_time.setText("正在进行中...");
        }

        return convertView;
    }

    class ViewHolder {
        TextView tv_goodsName;
        TextView tv_price;
        TextView tv_time;
    }

    private int result = -1;

    /**
     * 倒数,实时更新每个item的显示时间
     *
     * @return
     */
    public int countDownTime() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    if (goodsList == null || result == goodsList.size() + 1) {
                        result = 0;
                        return;
                    }
                    result = 1;
                    for (Goods goods : goodsList) {
                        if (goods.getTime() == 0) {
                            goods.setTime(0);
                            result++;
                        } else {
                            goods.setTime(goods.getTime() - 1);
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        Log.i("test", "result==>" + result);
        return result;
    }

    /**
     * 格式化时间显示,格式为:XX分XX秒
     *
     * @param timeDiff
     * @return
     */
    public static String getTimeStr(int timeDiff) {
        int min = timeDiff / 60;
        int sec = timeDiff - min * 60;

        String result = "";
        if (min == 0) {
            result = sec + "秒";
        } else {
            result = min + "分" + sec + "秒";
        }

        return result;
    }
}

此时,在android中实现ListView或GridView中item的倒数功能就已经完成了。

 源码下载

时间: 2024-07-31 12:52:08

android实现ListView或GridView中item的倒数功能的相关文章

Android实现ListView或GridView首行/尾行距离屏幕边缘距离

Android上ListView&GridView默认行都是置顶的,这样会很丑. 一般为了解决这个问题都会在首行或尾行加上一个隐藏的View,那样实在是太麻烦了.在网上看博客的时候突然看到这个属性真的很有用! 直接上关键属性: 设置ListView或GridView的android:clipToPadding = true, 然后通过paddingTop和paddingBottom设置距离就好了. 博客原文: http://www.cnblogs.com/xitang/p/3606578.htm

在ListView或GridView 中使用到跑马灯滚动效果实现的问题。

一般情况下TextView实现跑马灯效果只要设置一些几个属性即可实现了. android:singleLine="true"//只显示单行 android:ellipsize="marquee"       //实现滚动效果 android:focusable="true"    //获取焦点,获取不到焦点是无法实现跑马灯滚动的 android:marqueeRepeatLimit="marquee_forever"  //

android 打造ListView和Gridview万能adapter适配器(附源码)

android开发中,我们离不开adapter,每个项目都有很多地方需要adapter,那么我们如何让自己少写adapter代码呢?那就是封装adapter,让我们的adapter成为万能的adapter.下面我列出我实现的思路,供给大家学习与参考,当然有更好的方式也可以提供建议哦. 一.针对Listview或GridView的万能适配器(源码) 1.第一步实现公用的viewholder/** * 优化adapter用的ViewHolder * Created by admin on 17/8/

利用selector方法使listview,gridview的item背景变色

转载请注明出处:http://blog.csdn.net/harryweasley/article/details/44955845,谢谢 当我点击了一个item后,这个item的背景会一直变色下去, 刚开始使用state_selected,想着点击item后,选中后,他的背景就会改变,但发现并没有起作用, 之后经过谷歌,找到了实现该效果的方法, 我们应该用state_activated而不是state_selected这个方法,并且在xml给listview或者gridview设置他的属性an

Android 通用ListView、GridView适配器

1.简述 在Android开发肯定避免不了与adapter打交道,一般都是继承于BaseAdapter重写里面几个方法,然后一个ListView对应一个Adapter,那自然项目中就出现一大堆Adapter,鉴于此Adapter出现大量的重复代码是否有办法可以简化呢?答案是肯定的. 2.常规写法 只贴adapter部分,layout就不贴了,因为不是重点. public class SimpleAdapter extends BaseAdapter { public static class V

实现CheckBox的三种选中状态(全选、半选、不选)在GridView中模拟树形的功能

度娘了很多帖子,只说三种状态要用图片替换来做,但没找到有用的例子,被逼自己写了一个 三方控件肯定是很多的,如jstree,可以直接用 由于公司的UDS限制,不能上传图片,只能文字说明了. 就是要在gridview中实现如下效果:一级.二级因为三级没有全部选中而显示半选状态 ?一级    ?二级       三级1        三级2 js↓ $(function(){ BindCheckNode(); $("span[name^='lblCheck']").click(checkBo

关于ListView嵌套GridView中的onItemClickListener失效问题

一开始在ListView中设置了onItemClickListener,在里面Log输出Item列表的位置,完全没有反应, 网上大部分说的什么把子组件屏蔽掉(而且好多都是转载的一样的), 可是我希望的就是要用到子组件,所以这个方法治标不治本 能否同时即监听到子组件,又监听到ListView本身呢?(未找到解决办法) 所以只能找其他解决办法了... 开始以为是与onTouch这个方法有冲突, 参考了:http://blog.csdn.net/jiangwei0910410003/article/d

GridView中item高度自适应

public class MyAdapter extends BaseAdapter {         GridView mGv;        public static int ROW_NUMBER = 5;     public MyAdapter (GridView gv, Context mContext, ArrayList<String> list) {         this.context = mContext;         this.mGv = gv;       

Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件

前言 下拉刷新组件在开发中使用率是非常高的,基本上联网的APP都会采用这种方式.对于开发效率而言,使用获得大家认可的开源库必然是效率最高的,但是不重复发明轮子的前提是你得自己知道轮子是怎么发明出来的,并且自己能够实现这些功能.否则只是知道其原理,并没有去实践那也就是纸上谈兵了.做程序猿,动手做才会遇到真正的问题,否则就只是自以为是的认为自己懂了.今天这篇文章就是以自己重复发明轮子这个出发点而来的,通过实现经典.使用率较高的组件来提高自己的认识.下面我们就一起来学习吧. 整体布局结构