Here is a simple example implementing ListView with timer in each row.
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.