我有一个listview(使用自定义列表适配器),我需要在每一行显示倒计时.
例如,如果我的列表包含4个项目,我将有4行.
在这一点上,我需要处理4个不同的倒计时(每行一个),因为时间不同.
到目前为止,我使用以下方式处理它:在自定义列表适配器中,在getView()方法内部,我创建一个新的CountDownTimer,并在TextView中显示剩余时间.
但是问题是它减慢了很多活动,甚至在最坏的情况下甚至无法正确滚动(因为每次显示一行,都会创建一个新的CountDownTimer).
有没有更清洁和更平滑的解决方案来处理listView中的多个倒计时计时器?
谢谢
解决方法
而不是试图显示所有的剩余时间,这个想法是更新可见项目的剩余时间.
请按照以下示例代码,让我知道:
主要活动 :
public class MainActivity extends Activity { private ListView lvItems; private List<Product> lstProducts; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvItems = (ListView) findViewById(R.id.lvItems); lstProducts = new ArrayList<>(); lstProducts.add(new Product("A",System.currentTimeMillis() + 10000)); lstProducts.add(new Product("B",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("C",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("D",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("E",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("F",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("G",System.currentTimeMillis() + 30000)); lstProducts.add(new Product("H",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("I",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("J",System.currentTimeMillis() + 40000)); lstProducts.add(new Product("K",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("L",System.currentTimeMillis() + 50000)); lstProducts.add(new Product("M",System.currentTimeMillis() + 60000)); lstProducts.add(new Product("N",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("O",System.currentTimeMillis() + 10000)); lvItems.setAdapter(new CountdownAdapter(MainActivity.this,lstProducts)); } private class Product { String name; long expirationTime; public Product(String name,long expirationTime) { this.name = name; this.expirationTime = expirationTime; } } public class CountdownAdapter extends ArrayAdapter<Product> { private LayoutInflater lf; private List<ViewHolder> lstHolders; private Handler mHandler = new Handler(); private Runnable updateRemainingTimeRunnable = new Runnable() { @Override public void run() { synchronized (lstHolders) { long currentTime = System.currentTimeMillis(); for (ViewHolder holder : lstHolders) { holder.updateTimeRemaining(currentTime); } } } }; public CountdownAdapter(Context context,List<Product> objects) { super(context,objects); lf = LayoutInflater.from(context); lstHolders = new ArrayList<>(); startUpdateTimer(); } private void startUpdateTimer() { Timer tmr = new Timer(); tmr.schedule(new TimerTask() { @Override public void run() { mHandler.post(updateRemainingTimeRunnable); } },1000,1000); } @Override public View getView(int position,View convertView,ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = lf.inflate(R.layout.list_item,parent,false); holder.tvProduct = (TextView) convertView.findViewById(R.id.tvProduct); holder.tvTimeRemaining = (TextView) convertView.findViewById(R.id.tvTimeRemaining); convertView.setTag(holder); synchronized (lstHolders) { lstHolders.add(holder); } } else { holder = (ViewHolder) convertView.getTag(); } holder.setData(getItem(position)); return convertView; } } private class ViewHolder { TextView tvProduct; TextView tvTimeRemaining; Product mProduct; public void setData(Product item) { mProduct = item; tvProduct.setText(item.name); updateTimeRemaining(System.currentTimeMillis()); } public void updateTimeRemaining(long currentTime) { long timeDiff = mProduct.expirationTime - currentTime; if (timeDiff > 0) { int seconds = (int) (timeDiff / 1000) % 60; int minutes = (int) ((timeDiff / (1000 * 60)) % 60); int hours = (int) ((timeDiff / (1000 * 60 * 60)) % 24); tvTimeRemaining.setText(hours + " hrs " + minutes + " mins " + seconds + " sec"); } else { tvTimeRemaining.setText("Expired!!"); } } } }
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/lvItems" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/tvProduct" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="Product Name" android:textSize="16dp" android:textStyle="bold" /> <TextView android:id="@+id/tvTimeRemaining" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="Time Remaining : " /> </LinearLayout>