Here is a simple example implementing ListView with timer in each row.

Timer in ListView

Model Class for row

We have a simple model class for each row in the ListView.

Item.java


package com.coderzheaven.listviewtimer;

import java.util.Timer;

public class Item {

    public String title;
    public int timeInSeconds;
    public Timer timer;

    public Timer getTimer() {
        return timer;
    }

    public void setTimer(Timer timer) {
        this.timer = timer;
    }

    public int getTimeInSeconds() {
        return timeInSeconds;
    }

    public void setTimeInSeconds(int timeInSeconds) {
        this.timeInSeconds = timeInSeconds;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Item(String title, int timeInSeconds) {
        this.title = title;
        this.timeInSeconds = timeInSeconds;
    }
}

Layout for the Listview row

Now we have the cell.xml which is the layout for each row.

<?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"
    android:layout_margin="3dp"
    android:background="@color/colorPrimary_lit"
    android:orientation="vertical">


    <Button
        android:id="@+id/btnStartTimer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_margin="2dp"
        android:padding="10dp"
        android:text="START"
        android:textColor="@android:color/black"
        android:textStyle="bold" />


    <TextView
        android:id="@+id/tvTimer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_margin="2dp"
        android:gravity="center"
        android:layout_toRightOf="@+id/btnStartTimer"
        android:layout_toLeftOf="@+id/btnStopTimer"
        android:padding="10dp"
        android:text="14:50:70"
        android:textColor="@android:color/white"
        android:textSize="30sp"
        android:textStyle="bold" />


    <Button
        android:id="@+id/btnStopTimer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_margin="2dp"
        android:padding="10dp"
        android:text="STOP"
        android:textColor="@android:color/black"
        android:textStyle="bold" />


</RelativeLayout>

Layout for the Activity

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: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.coderzheaven.listviewtimer.MainActivity">


    <GridView
        android:id="@+id/grid_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="3dp"
        android:horizontalSpacing="3dp"
        android:verticalSpacing="3dp"></GridView>
</RelativeLayout>

GridAdapter

Here goes our adapter for the List/Grid.


package com.coderzheaven.listviewtimer;

import android.content.Context;
import android.graphics.Typeface;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class GridAdapter extends BaseAdapter implements View.OnClickListener {

    private final static String TAG = GridAdapter.class.getSimpleName();

    private Context mContext;

    List<Item> allTables;
    LayoutInflater inflater;

    private final int TIMER_INTERVAL = 1000;    // 1 Second

    private Handler handler = null;

    Typeface custom_font;

    public GridAdapter(Context c, List<Item> allTables) {
        mContext = c;
        this.allTables = allTables;
        inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        custom_font = Typeface.createFromAsset(mContext.getAssets(), "fonts/RobotoCondensed-Regular.ttf");
    }

    public int getCount() {
        return allTables.size();
    }

    public Object getItem(int position) {
        return null;
    }

    public long getItemId(int position) {
        return 0;
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder = null;

        if (convertView == null) {

            convertView = inflater.inflate(R.layout.cell, null);

            holder = new ViewHolder();

            holder.tvTimer = (TextView) convertView.findViewById(R.id.tvTimer);
            holder.btnStart = (Button) convertView.findViewById(R.id.btnStartTimer);
            holder.btnStop = (Button) convertView.findViewById(R.id.btnStopTimer);

            holder.tvTimer.setTypeface(custom_font);
            holder.btnStart.setTypeface(custom_font);
            holder.btnStop.setTypeface(custom_font);

            convertView.setTag(holder);

        } else {

            holder = (ViewHolder) convertView.getTag();

        }

        holder.btnStart.setOnClickListener(this);
        holder.btnStop.setOnClickListener(this);

        holder.btnStart.setTag(position);
        holder.btnStop.setTag(position);

        Item item = allTables.get(position);

        if (null != item) {

            if (null == item.getTimer()) {
                holder.tvTimer.setText(convertToTimerString(0));
                holder.btnStart.setVisibility(View.VISIBLE);
                holder.btnStop.setVisibility(View.GONE);
            } else {
                holder.tvTimer.setText(convertToTimerString(item.getTimeInSeconds()));
                holder.btnStop.setVisibility(View.VISIBLE);
                holder.btnStart.setVisibility(View.GONE);
            }

        }

        return convertView;
    }

    String convertToTimerString(int seconds) {
        String timeString = null;

        int rem = seconds % 60;  // 150%60 = 30
        int minutes = seconds / 60;
        int hour = minutes / 60;

        String tempRem = String.valueOf(rem);
        String tempMin = String.valueOf(minutes);
        String tempHr = String.valueOf(hour);

        if (rem < 10)
            tempRem = "0" + rem;

        if (minutes < 10)
            tempMin = "0" + minutes;

        if (hour < 10)
            tempHr = "0" + hour;


        timeString = tempHr + ":" + tempMin + ":" + tempRem;

        return timeString;
    }

    @Override
    public void onClick(View v) {

        Item item = allTables.get((int) v.getTag());

        int position = (int) v.getTag();

        if (v.getId() == R.id.btnStartTimer) {

            Timer timer = new Timer();
            TimerTask updateTime = new CustomTimerTask(mContext, item, position);
            timer.scheduleAtFixedRate(updateTime, 1000, TIMER_INTERVAL);

            item.setTimeInSeconds(0);
            item.setTimer(timer);

            allTables.remove(position);
            allTables.add(position, item);

            notifyDataSetChanged();


        } else if (v.getId() == R.id.btnStopTimer) {

            Timer timer = item.getTimer();
            if (null != timer) {
                timer.cancel();
                timer = null;
            }

            item.setTimer(timer);

            allTables.remove(position);
            allTables.add(position, item);
            notifyDataSetChanged();


        }


    }

    private static class ViewHolder {

        TextView tvTimer;
        Button btnStart, btnStop;

    }


    // Our Custom Timer Class...

    class CustomTimerTask extends TimerTask {

        private Context context;
        private Handler mHandler = new Handler();
        Item item;
        int position;

        public CustomTimerTask(Context context, Item snookerTable, int position) {
            this.context = context;
            this.position = position;
            this.item = snookerTable;
        }

        @Override
        public void run() {

            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    int curTime = item.timeInSeconds;
                    item.setTimeInSeconds(curTime + 1);
                    allTables.remove(position);
                    allTables.add(position, item);
                    notifyDataSetChanged();
                }
            });

        }

    }


}

MainActivity


package com.coderzheaven.listviewtimer;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.GridView;

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

public class MainActivity extends AppCompatActivity {

    private static int NUM_ROWS = 20;

    private GridAdapter gridAdapter;

    private List<Item> allTables = new ArrayList<Item>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        GridView gridview = (GridView) findViewById(R.id.grid_view);
        gridAdapter = new GridAdapter(this, allTables);
        gridview.setAdapter(gridAdapter);

        for (int i = 0; i < NUM_ROWS; i++) {
            Item item = new Item("Row " + i, 0);
            allTables.add(item);
        }
    }
}

You can download the complete source code from here.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

 

 

 

Theme by HermesThemes

Copyright © 2018 CoderzHeaven. All Rights Reserved

Please wait...

Subscribe to our newsletter

Want to be notified when our article is published? Enter your email address and name below to be the first to know.