Android - Highlighting respectively gridview items

Good day everyone,
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.


And then, use TimeTask to launch an AsyncTask after a time. When the asynctak running, we will highlight the gridview item.
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.
Highlighting method can be like this:

/**
     * 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:
pic name pic name pic name
Enjoy! For any question, please comment! :)
(sorry for having ads)

Share


Previous post
« Prev Post
Next post
Next Post »