To day I will present a way to highlighting respectively items in a gridview.
For solution, we immediately find out the TimeTask. It represents a task to run at a specified time. The task may be run once or repeatedly.
Therefore, we must use three variables to detect gridview item position and start or stop this work:
- position: initializing with values -1 and ascending 1 after the asynctask run 1 time.
- max position: it is number of gridview items.
- current position: use for pausing work and restart.
For highlight item, each gridview item layout must define in an xml file, we are changing it's background to highlighting it.
Okey, more details, I will show in code...Sorry for confusing presentation! And now, launch Eclipse and we start a new android project.
First, defining a gridview item properties in a class. Source code for GridViewItem.java:
package com.blogspot.hongthaiit.gridviewhighlightitem;
/**
*
* @author hongthaiit
*
*/
public class GridViewItem {
private int image;
private boolean isHighLight;
public GridViewItem() {
// empty constructor
}
public GridViewItem(int image, boolean is) {
this.image = image;
this.isHighLight = is;
}
public boolean isHighLight() {
return isHighLight;
}
/**
* set if item is highlight or not
*/
public void setHighLight(boolean isHighLight) {
this.isHighLight = isHighLight;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
}
In our activity, we must:- Defining highlight method.
- Create an asynctask for highlight gridview items.
- Combining the asynctask and a TimeTask.
/**
* Highlight gridview items method
*/
private void highLight() {
if (position == 0 ) {
//set item at position 0 highlight
//update adapter after that
adapter.getItem(position).setHighLight(true);
adapter.notifyDataSetChanged();
} else if (position < maxPosition) {
// highlight current item and not highlight previous item
//and update adapter after that
adapter.getItem(position - 1).setHighLight(false);
adapter.getItem(position).setHighLight(true);
adapter.notifyDataSetChanged();
} else {
//canceling time task and reset position
cancelTimerTask();
position = -1;
currentPosition = -1;
start.setText(getResources().getString(R.string.start));
}
}
And the asynctask we need:
private class HiglightTask extends AsyncTask {
@Override
protected Void doInBackground(Void... params) {
if (position < maxPosition) {
publishProgress(Integer.valueOf(position));
}
Log.i(TAG, "do in background");
return null;
}
@Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
if (position < maxPosition) {
highLight();
}
}
@Override
protected void onProgressUpdate(Integer... values) {
if (position < maxPosition) {
position = position + 1;
} else {
}
Log.d(TAG, "pos " + position);
Log.i(TAG, "onProgressUpdate");
}
}
The method to start highlighting work like this:
private void launchHighlightWork() {
Log.v(TAG, "callAsynchronousTask");
final Handler handler = new Handler();
Timer timer = new Timer();
timeTask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
HiglightTask higlightBackgroundTask = new HiglightTask();
higlightBackgroundTask.execute();
} catch (Exception e) {
}
}
});
}
};
timer.schedule(timeTask, 0, 1000);
}
Moreover, we need some advanced methods like cancelTimesTask() (use for pausing work and when activity is onPause or onStop).
Full MainActivity.java file:
public class MainActivity extends Activity {
private int position = -1;
private int currentPosition = -1;
private int maxPosition;
private int studyStyle;
private TimerTask timeTask;
private static String TAG = "MainActivity";
private GridView gridNumber;
private ViewGroup buttonView;
private Button start;
private GridViewAdapter adapter;
private ArrayList<Gridviewitem> items;
private static int resourceArray[] = { R.drawable.number_0,
R.drawable.number_1, R.drawable.number_2, R.drawable.number_3,
R.drawable.number_4, R.drawable.number_5, R.drawable.number_6,
R.drawable.number_7, R.drawable.number_8, R.drawable.number_9 };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locateView(); //define all elements in content views
setAdapter(studyStyle); // set gridview adapter
}
/**
* Canceling highlight work when app is not visible
*/
@Override
protected void onPause() {
super.onPause();
cancelTimerTask();
}
private void locateView() {
gridNumber = (GridView) findViewById(R.id.grid);
buttonView = (LinearLayout) findViewById(R.id.fragment);
replaceButtonLayout();
}
/**
* set Button Start view from other xml
*/
private void replaceButtonLayout() {
LayoutInflater inflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.fragment_button, buttonView, false);
start = (Button) view.findViewById(R.id.btn_start);
start.setOnClickListener(startCountingOnClick()); //set onclick event for start button
buttonView.addView(view);
}
/**
* Set gridview adapter
* @param studyCase
*/
private void setAdapter(int studyCase) {
items = new ArrayList<Gridviewitem>();
if (studyCase == 0) {
maxPosition = 10;
createListImageItems(resourceArray);
}
adapter = new GridViewAdapter(this, R.layout.item_grid_view, items);
gridNumber.setAdapter(adapter);
}
/**
* create an arraylist of highlight item use for gridview adapter
* @param array
*/
private void createListImageItems(int[] array) {
for (int i = 0; i < array.length; i++) {
GridViewItem item = new GridViewItem();
item.setHighLight(false);
item.setImage(array[i]);
items.add(item);
}
}
/**
* Highlight gridview items method
*/
private void highLight() {
if (position == 0 ) {
//set item at position 0 highlight
//update adapter after that
adapter.getItem(position).setHighLight(true);
adapter.notifyDataSetChanged();
} else if (position < maxPosition) {
// highlight current item and not highlight previous item
//and update adapter after that
adapter.getItem(position - 1).setHighLight(false);
adapter.getItem(position).setHighLight(true);
adapter.notifyDataSetChanged();
} else {
//canceling time task and reset position
cancelTimerTask();
position = -1;
currentPosition = -1;
start.setText(getResources().getString(R.string.start));
}
}
/**
* Run this task for highlight items
*/
private void launchHighlightWork() {
Log.v(TAG, "callAsynchronousTask");
final Handler handler = new Handler();
Timer timer = new Timer();
timeTask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
HiglightTask higlightBackgroundTask = new HiglightTask();
higlightBackgroundTask.execute();
} catch (Exception e) {
}
}
});
}
};
timer.schedule(timeTask, 0, 1000);
}
/**
* This asynctask use for highlight
*
*/
private class HiglightTask extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
if (position < maxPosition) {
publishProgress(Integer.valueOf(position));
}
Log.i(TAG, "do in background");
return null;
}
@Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
if (position < maxPosition) {
highLight();
}
}
@Override
protected void onProgressUpdate(Integer... values) {
if (position < maxPosition) {
position = position + 1;
} else {
}
Log.d(TAG, "pos " + position);
Log.i(TAG, "onProgressUpdate");
}
}
/**
* Start button event
* @return
*/
private OnClickListener startCountingOnClick() {
return new OnClickListener() {
@Override
public void onClick(View v) {
if (start.getText().toString()
.equals(getResources().getString(R.string.start))) {
position = currentPosition;
setAdapter(studyStyle);
launchHighlightWork();
start.setText(getResources().getString(R.string.stop));
} else {
Log.i(TAG, "current position" + position);
currentPosition = position;
cancelTimerTask();
setAdapter(studyStyle);
highLight();
start.setText(getResources().getString(R.string.start));
}
}
};
}
/**
* Canceling the time task, so stopping highlight.
*/
private void cancelTimerTask() {
if (timeTask != null) {
timeTask.cancel();
}
}
}
Layout (activity_main.xml) for MainActivity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<GridView
android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:columnWidth="80dp"
android:gravity="center"
android:numColumns="3"
android:stretchMode="columnWidth" >
</GridView>
<LinearLayout
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
With Gridview adapter, making own adapter extends ArrayAdapter. File GridViewAdapter.java:
public class GridViewAdapter extends ArrayAdapter<Gridviewitem> {
// private LinkedList<highlightitem> items;
private Activity activity;
private int resourceLayoutId;
private List items;
private static final String TAG = GridViewAdapter.class.getSimpleName();
public GridViewAdapter(Activity activity, int resourceLayout,
List<gridviewitem> items) {
super(activity, 0, items);
this.activity = activity;
this.items = items;
this.resourceLayoutId = resourceLayout;
Log.i(TAG, "initial adapter");
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = activity.getLayoutInflater();
convertView = inflater.inflate(resourceLayoutId, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
GridViewItem item = items.get(position);
if (item.isHighLight()) {
holder.background.setBackgroundColor(Color.BLUE);
} else {
holder.background.setBackgroundColor(Color.TRANSPARENT);
}
holder.image.setImageResource(item.getImage());
return convertView;
}
private static class ViewHolder {
private ImageView image;
private ViewGroup background;
public ViewHolder(View v) {
image = (ImageView) v.findViewById(R.id.item_image);
background = (ViewGroup) v.findViewById(R.id.row_layout);
}
}
}
Define xml for each gridview element (item_grid.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/row_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:orientation="vertical"
android:padding="5dp" >
<LinearLayout
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="5dp"
android:background="@null"
android:orientation="vertical" >
<ImageView
android:id="@+id/item_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_launcher"
android:contentDescription="@string/app_name"/>
<TextView
android:id="@+id/item_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:focusable="false"
android:textSize="15sp" >
</TextView>
</LinearLayout>
</LinearLayout>
In this example, I make a "button layout"(file fragment_button.xml - replaced it to LinearLayout in activity_main.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="horizontal" >
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/start" />
</LinearLayout>
Finally, run program and we have result like this:
Enjoy! For any question, please comment! :)
(sorry for having ads)