A timeline is a display of a list of events in chronological order. Timelines can use any suitable scale representing time, suiting the subject and data; many use a linear scale, in which a unit of distance is equal to a set amount of time.
In this tutorial, we will see how to implement timeline view in Android. Below is the mock-up how we are expected to build,
Refer the below link for complete sample code:-
Download Sample Code
Have a look on few code snippets,
//ctimeline_row.xml
//activity_main.xml
//TimelineRow.java
//TimelineViewAdapter.java
//MainActivity.java
In this tutorial, we will see how to implement timeline view in Android. Below is the mock-up how we are expected to build,
Refer the below link for complete sample code:-
Download Sample Code
Have a look on few code snippets,
//ctimeline_row.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | <?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="wrap_content" android:orientation="horizontal"> <RelativeLayout android:layout_width="72dp" android:layout_height="match_parent"> <View android:id="@+id/crowUpperLine" android:layout_width="25dp" android:layout_height="match_parent" android:layout_above="@+id/crowImg" android:layout_centerInParent="true" android:layout_centerVertical="true" android:background="@android:color/darker_gray" /> <View android:id="@+id/crowLowerLine" android:layout_width="25dp" android:layout_height="match_parent" android:layout_below="@+id/crowImg" android:layout_centerInParent="true" android:layout_centerVertical="true" android:background="@android:color/darker_gray" /> <View android:id="@+id/crowBackground" android:layout_width="25dp" android:layout_height="25dp" android:layout_centerInParent="true" android:layout_centerVertical="true" /> <ImageView android:id="@+id/crowImg" android:layout_width="25dp" android:layout_height="25dp" android:layout_centerInParent="true" android:layout_centerVertical="true" android:layout_marginTop="-12.5dp" android:layout_marginBottom="-12.5dp" /> </RelativeLayout> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="16dp" android:paddingBottom="10dp" android:paddingRight="16dp"> <TextView android:id="@+id/crowDate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Date" android:paddingTop="10dp" android:textAppearance="?android:attr/textAppearanceSmall" /> <TextView android:id="@+id/crowTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/crowDate" android:layout_centerVertical="true" android:text="Title" android:textAppearance="?android:attr/textAppearanceListItem" android:textStyle="bold" /> <TextView android:id="@+id/crowDesc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/crowTitle" android:layout_centerVertical="true" android:text="Description" android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle" /> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#d7f2eb" /> </RelativeLayout> </LinearLayout> |
//activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ListView android:id="@+id/timeline_listView" android:layout_width="match_parent" android:layout_height="match_parent" android:divider="@null" android:dividerHeight="0dp" /> </LinearLayout> |
//TimelineRow.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | package com.elitetechnologies.timelineview.TimelineView; import android.graphics.Bitmap; import java.util.Date; public class TimelineRow { private int id; private Date date = null; private String title = null; private String description = null; private Bitmap image = null; private int bellowLineColor = 0; private int bellowLineSize = 6; private int imageSize = 50; private int backgroundColor = 0; private int backgroundSize = 50; private int dateColor = 0; private int titleColor = 0; private int descriptionColor = 0; public TimelineRow(int id) { this.id = id; } public TimelineRow(int id, Date date) { this.id = id; this.date = date; } public TimelineRow(int id, Date date, String title, String description) { this.id = id; this.date = date; this.title = title; this.description = description; } public TimelineRow(int id, Date date, String title, String description, Bitmap image, int bellowLineColor, int bellowLineSize, int imageSize) { this.id = id; this.date = date; this.title = title; this.description = description; this.image = image; this.bellowLineColor = bellowLineColor; this.bellowLineSize = bellowLineSize; this.imageSize = imageSize; } public TimelineRow(int id, Date date, String title, String description, Bitmap image, int bellowLineColor, int bellowLineSize, int imageSize, int backgroundColor, int backgroundSize) { this.id = id; this.date = date; this.title = title; this.description = description; this.image = image; this.bellowLineColor = bellowLineColor; this.bellowLineSize = bellowLineSize; this.imageSize = imageSize; this.backgroundColor = backgroundColor; this.backgroundSize = backgroundSize; } public TimelineRow(int id, Date date, String title, String description, Bitmap image, int bellowLineColor, int bellowLineSize, int imageSize, int backgroundColor, int backgroundSize, int dateColor, int titleColor, int descriptionColor) { this.id = id; this.date = date; this.title = title; this.description = description; this.image = image; this.bellowLineColor = bellowLineColor; this.bellowLineSize = bellowLineSize; this.imageSize = imageSize; this.backgroundColor = backgroundColor; this.backgroundSize = backgroundSize; this.dateColor = dateColor; this.titleColor = titleColor; this.descriptionColor = descriptionColor; } public int getBackgroundSize() { return backgroundSize; } public void setBackgroundSize(int backgroundSize) { this.backgroundSize = backgroundSize; } public int getBackgroundColor() { return backgroundColor; } public void setBackgroundColor(int backgroundColor) { this.backgroundColor = backgroundColor; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public int getImageSize() { return imageSize; } public void setImageSize(int imageSize) { this.imageSize = imageSize; } public int getBellowLineSize() { return bellowLineSize; } public int getId() { return id; } public void setId(int id) { this.id = id; } public void setBellowLineSize(int bellowLineSize) { this.bellowLineSize = bellowLineSize; } public int getBellowLineColor() { return bellowLineColor; } public void setBellowLineColor(int bellowLineColor) { this.bellowLineColor = bellowLineColor; } public Bitmap getImage() { return image; } public void setImage(Bitmap image) { this.image = image; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public int getDateColor() { return dateColor; } public void setDateColor(int dateColor) { this.dateColor = dateColor; } public int getTitleColor() { return titleColor; } public void setTitleColor(int titleColor) { this.titleColor = titleColor; } public int getDescriptionColor() { return descriptionColor; } public void setDescriptionColor(int descriptionColor) { this.descriptionColor = descriptionColor; } } |
//TimelineViewAdapter.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | package com.elitetechnologies.timelineview.TimelineView; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.GradientDrawable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import com.elitetechnologies.timelineview.R; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; public class TimelineViewAdapter extends ArrayAdapter<TimelineRow> { private Context context; private Resources res; private List<TimelineRow> RowDataList; private String AND; public TimelineViewAdapter(Context context, int resource, ArrayList<TimelineRow> objects, boolean orderTheList) { super(context, resource, objects); this.context = context; res = context.getResources(); AND ="and"; if (orderTheList) this.RowDataList = rearrangeByDate(objects); else this.RowDataList = objects; } @Override public View getView(int position, View convertView, ViewGroup parent) { TimelineRow row = RowDataList.get(position); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.ctimeline_row, null); TextView rowDate = (TextView) view.findViewById(R.id.crowDate); TextView rowTitle = (TextView) view.findViewById(R.id.crowTitle); TextView rowDescription = (TextView) view.findViewById(R.id.crowDesc); ImageView rowImage = (ImageView) view.findViewById(R.id.crowImg); View rowUpperLine = (View) view.findViewById(R.id.crowUpperLine); View rowLowerLine = (View) view.findViewById(R.id.crowLowerLine); final float scale = getContext().getResources().getDisplayMetrics().density; if (position == 0 && position == RowDataList.size() - 1) { rowUpperLine.setVisibility(View.INVISIBLE); rowLowerLine.setVisibility(View.INVISIBLE); } else if (position == 0) { int pixels = (int) (row.getBellowLineSize() * scale + 0.5f); rowUpperLine.setVisibility(View.INVISIBLE); rowLowerLine.setBackgroundColor(row.getBellowLineColor()); rowLowerLine.getLayoutParams().width = pixels; } else if (position == RowDataList.size() - 1) { int pixels = (int) (RowDataList.get(position - 1).getBellowLineSize() * scale + 0.5f); rowLowerLine.setVisibility(View.INVISIBLE); rowUpperLine.setBackgroundColor(RowDataList.get(position - 1).getBellowLineColor()); rowUpperLine.getLayoutParams().width = pixels; } else { int pixels = (int) (row.getBellowLineSize() * scale + 0.5f); int pixels2 = (int) (RowDataList.get(position - 1).getBellowLineSize() * scale + 0.5f); rowLowerLine.setBackgroundColor(row.getBellowLineColor()); rowUpperLine.setBackgroundColor(RowDataList.get(position - 1).getBellowLineColor()); rowLowerLine.getLayoutParams().width = pixels; rowUpperLine.getLayoutParams().width = pixels2; } if (position == 0 || position == RowDataList.size() - 1) { Bitmap tintBitmap = tintImage(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_srcdstpoint), Color.parseColor("#c44227")); row.setImage(tintBitmap); }else{ Bitmap tintBitmap = tintImage(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_nodes), Color.parseColor("#f29d9d")); row.setImage(tintBitmap); } if(position<=2) { row.setBellowLineSize(12); row.setBellowLineColor(Color.parseColor("#9df2b1")); } rowDate.setText(getPastTime(row.getDate())); if (row.getDateColor() != 0) rowDate.setTextColor(row.getDateColor()); if (row.getTitle() == null) rowTitle.setVisibility(View.GONE); else { rowTitle.setText(row.getTitle()); if (row.getTitleColor() != 0) rowTitle.setTextColor(row.getTitleColor()); } if (row.getDescription() == null) rowDescription.setVisibility(View.GONE); else { rowDescription.setText(row.getDescription()); if (row.getDescriptionColor() != 0) rowDescription.setTextColor(row.getDescriptionColor()); } if (row.getImage() != null) { rowImage.setImageBitmap(row.getImage()); } int pixels = (int) (row.getImageSize() * scale + 0.5f); rowImage.getLayoutParams().width = pixels; rowImage.getLayoutParams().height = pixels; View backgroundView = view.findViewById(R.id.crowBackground); if (row.getBackgroundColor() == 0) backgroundView.setBackground(null); else { if (row.getBackgroundSize() == -1) { backgroundView.getLayoutParams().width = pixels; backgroundView.getLayoutParams().height = pixels; } else { int BackgroundPixels = (int) (row.getBackgroundSize() * scale + 0.5f); backgroundView.getLayoutParams().width = BackgroundPixels; backgroundView.getLayoutParams().height = BackgroundPixels; } GradientDrawable background = (GradientDrawable) backgroundView.getBackground(); if (background != null) { background.setColor(row.getBackgroundColor()); } } ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) rowImage.getLayoutParams(); marginParams.setMargins(0, (int) (pixels / 2) * -1, 0, (pixels / 2) * -1); return view; } private String getPastTime(Date date) { if (date == null) return ""; StringBuilder dateText = new StringBuilder(); Date today = new Date(); long diff = (today.getTime() - date.getTime()) / 1000; long years = diff / (60 * 60 * 24 * 30 * 12); long months = (diff / (60 * 60 * 24 * 30)) % 12; long days = (diff / (60 * 60 * 24)) % 30; long hours = (diff / (60 * 60)) % 24; long minutes = (diff / 60) % 60; long seconds = diff % 60; if (years > 0) { appendPastTime(dateText, years, R.plurals.years, months, R.plurals.months); } else if (months > 0) { appendPastTime(dateText, months, R.plurals.months, days, R.plurals.days); } else if (days > 0) { appendPastTime(dateText, days, R.plurals.days, hours, R.plurals.hours); } else if (hours > 0) { appendPastTime(dateText, hours, R.plurals.hours, minutes, R.plurals.minutes); } else if (minutes > 0) { appendPastTime(dateText, minutes, R.plurals.minutes, seconds, R.plurals.seconds); } else if (seconds >= 0) { dateText.append(res.getQuantityString(R.plurals.seconds, (int) seconds, (int) seconds)); } return dateText.toString(); } private void appendPastTime(StringBuilder s, long timespan, int nameId, long timespanNext, int nameNextId) { s.append(res.getQuantityString(nameId, (int) timespan, timespan)); if (timespanNext > 0) { s.append(' ').append(AND).append(' '); s.append(res.getQuantityString(nameNextId, (int) timespanNext, timespanNext)); } } private ArrayList<TimelineRow> rearrangeByDate(ArrayList<TimelineRow> objects) { if (objects.get(0) == null) return objects; int size = objects.size(); for (int i = 0; i < size - 1; i++) { for (int j = i + 1; j < size; j++) { if(objects.get(i).getDate()!= null && objects.get(j).getDate() != null) if (objects.get(i).getDate().compareTo(objects.get(j).getDate()) <= 0) Collections.swap(objects, i, j); } } return objects; } private static Bitmap tintImage(Bitmap bitmap, int color) { Paint paint = new Paint(); paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)); Bitmap bitmapResult = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmapResult); canvas.drawBitmap(bitmap, 0, 0, paint); return bitmapResult; } } |
//MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | package com.elitetechnologies.timelineview; import android.annotation.SuppressLint; import android.graphics.BitmapFactory; import android.graphics.Color; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.Toast; import com.elitetechnologies.timelineview.TimelineView.TimelineRow; import com.elitetechnologies.timelineview.TimelineView.TimelineViewAdapter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; public class MainActivity extends AppCompatActivity { //Create Timeline Rows List private ArrayList<TimelineRow> timelineRowsList = new ArrayList<>(); ArrayAdapter<TimelineRow> myAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);// Create Timeline rows List // Add Random Rows to the List for (int i = 0; i < 15; i++) { //add the new row to the list timelineRowsList.add(createRandomTimelineRow(i)); } //Create the Timeline Adapter myAdapter = new TimelineViewAdapter(this, 0, timelineRowsList, //if true, list will be sorted by date true); //Get the ListView and Bind it with the Timeline Adapter ListView timeline_listView = (ListView) findViewById(R.id.timeline_listView); timeline_listView.setAdapter(myAdapter); myAdapter.notifyDataSetChanged(); //if you wish to handle the clicks on the rows AdapterView.OnItemClickListener adapterListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { TimelineRow row = timelineRowsList.get(position); Toast.makeText(MainActivity.this, row.getTitle()+"at position"+position, Toast.LENGTH_SHORT).show(); } }; timeline_listView.setOnItemClickListener(adapterListener); } //Method to create new Timeline Row private TimelineRow createRandomTimelineRow(int id) { // Create new timeline row (pass your Id) TimelineRow myRow = new TimelineRow(id); //to set the row Date (optional) myRow.setDate(getRandomDate()); //to set the row Title (optional) myRow.setTitle("Title " + id); myRow.setTitleColor(Color.parseColor("#3295a8")); //to set the row Description (optional) myRow.setDescription("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); myRow.setDescriptionColor(Color.parseColor("#32a8a4")); //to set row Below Line Color (optional) myRow.setBellowLineColor(Color.LTGRAY); return myRow; } @SuppressLint("NewApi") public Date getRandomDate() { SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); Date startDate = null; Date endDate = new Date(); try { startDate = sdf.parse("14/02/2020"); long random = ThreadLocalRandom.current().nextLong(startDate.getTime(), endDate.getTime()); endDate = new Date(random); } catch (ParseException e) { e.printStackTrace(); } return endDate; } } |
No comments:
Post a Comment