列表视图中的倒数计时器

时间:2017-05-12 06:29:39

标签: android listview

我在listview中实现了倒数计时器。但问题是,当我关闭我的应用程序并重新打开时,计时器从开始重置。我希望计时器运行即使应用程序关闭。例如 - 如果时间是10分钟我关闭应用程序并在6分钟后打开计时器必须显示剩余时间为4分钟。

MainActivity.java

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() + 250000));
        lstProducts.add(new Product("C", System.currentTimeMillis() + 200000));
        lstProducts.add(new Product("D", System.currentTimeMillis() + 300000));


        lvItems.setAdapter(new CountdownAdapter(MainActivity.this, lstProducts));
    }

}

Product.java

public class Product {
    String name;
    long expirationTime;

    public Product(String name, long expirationTime) {
        this.name = name;
        this.expirationTime = expirationTime;
    }
}

CountdownAdapter.java

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, 0, 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;
    }


    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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.ram.asynctimer.MainActivity">

    <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:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <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>

MyService.java

public class MyService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        //throw new UnsupportedOperationException("Not yet implemented");
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // do your jobs here
        return super.onStartCommand(intent, flags, startId);
    }
}

2 个答案:

答案 0 :(得分:0)

原因“计时器重置”是指您在关闭时没有保存每个项目计时器,当您启动应用程序时,您将再次设置新的计时器。

只需将每个项目计时器存储在onStop方法中,然后再次在onCreate中加载这些项目,并设置是否

if(item1_timer - System.currentTimeMillis()>0){
   {
      //set timer to item1 and so on
   }else{
           item1.timer = "Expired"
      }

答案 1 :(得分:0)

如果您修改了Product.java以保留到期时间和剩余时间,那么您可以使用捆绑包保存和恢复该信息。

<强> Product.java

public class Product {
String name;
long expirationTime;
long remainingTime

    public Product(String name, long expirationTime, long remainingTime) {
        this.name = name;
        this.expirationTime = expirationTime;
        if(remainingTime <= 0)
            this.remainingTime = this.expirationTime;
        else 
            this.remainingTime = remainingTime;
    }
}

从这里,您可以使用共享首选项来保存所有产品的状态。

<强> MainActivity.java

public class MainActivity extends Activity {
    public static final String PREFS_NAME = "TimerValsFile";
    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<>();

        // Access the shared preferences
        SharedPreferences timerVals = getSharedPreferences(PREFS_NAME, 0);

        // Restore remaining time from shared preferences
        long remA = timerVals.getLong("A", -1);
        long remB = timerVals.getLong("A", -1);
        long remC = timerVals.getLong("A", -1);
        long remD = timerVals.getLong("A", -1);

        lstProducts.add(new Product("A", System.currentTimeMillis() + 10000), remA);
        lstProducts.add(new Product("B", System.currentTimeMillis() + 250000), remB);
        lstProducts.add(new Product("C", System.currentTimeMillis() + 200000), remC);
        lstProducts.add(new Product("D", System.currentTimeMillis() + 300000), remD);


        lvItems.setAdapter(new CountdownAdapter(MainActivity.this, lstProducts));
    }

    @Override
    protected void onStop(){
        super.onStop();

        // We need an Editor object to make preference changes.
        // All objects are from android.context.Context
        SharedPreferences timerVals = getSharedPreferences(PREFS_NAME, 0);
        SharedPreferences.Editor editor = timerVals.edit();
        editor.putLong("A", lstProducts.get(0).remainingTime);
        editor.putLong("B", lstProducts.get(1).remainingTime);
        editor.putLong("C", lstProducts.get(2).remainingTime);
        editor.putLong("D", lstProducts.get(3).remainingTime);

        // Commit the edits!
        editor.apply();
    }

}

现在您要从实例状态加载,您需要修改ViewHolder类

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) {
        mProduct.remainingTime -= currentTime;
        if (mProduct.remainingTime > 0) {
            int seconds = (int) (mProduct.remainingTime / 1000) % 60;
            int minutes = (int) ((mProduct.remainingTime / (1000 * 60)) % 60);
            int hours = (int) ((mProduct.remainingTime / (1000 * 60 * 60)) % 24);
            tvTimeRemaining.setText(hours + " hrs " + minutes + " mins " + seconds + " sec");
        } else {
            tvTimeRemaining.setText("Expired!!");
        }
    }
}

我还没有真正对此进行测试,但很快就能解决这个问题,但我希望这能为您提供一般的想法。这基本上是使用服务的替代方案。

来源:

SO: Android Shared preferences example

Android开发者指南: https://developer.android.com/guide/topics/data/data-storage.html#pref

https://developer.android.com/reference/android/content/SharedPreferences.Editor.html