Implementing Tree View in PSLab Android App

When a task expands over sub tasks, it can be easily represented by a stem and leaf diagram. In the context of android it can be implemented using an expandable list view. But in a scenario where the subtasks has mini tasks appended to it, it is hard to implement it using the general two level expandable list views. PSLab android application supports many experiments to perform using the PSLab device. These experiments are divided into major sections and each experiments are listed under them. The best way to implement this functionality in the android application is using a multi layer treeview implementation. In this context three layers are enough as follows; This was implemented with the help from a library called AndroidTreeView. This blog will outline how to modify and implement it in PSLab android application. Basic Idea Tree view implementation simply follows the data structure “Tree” used in algorithms. Every tree has a root where it starts and from the root there will be branches which are connected using edges. Every edge will have a parent and child. To reach a child, one has to traverse through only one route. Setting Up Dependencies Implementing tree view begins with setting up dependencies in the gradle file in the project. compile 'com.github.bmelnychuk:atv:1.2.+' Creating UI for tree view The speciality about this implementation is that it can be loaded into any kind of a layout such as a linearlayout, relativelayout, framelayout etc. final TreeNode Root = TreeNode.root(); Root.addChildren( // Add child nodes here ); // Set up the tree view AndroidTreeView experimentsListTree = new AndroidTreeView(getActivity(), Root); experimentsListTree.setDefaultAnimation(true); [LinearLayout/RelativeLayout].addView(experimentsListTree.getView()); Creating a node holder Trees are made of a collection of tree nodes. A holder for a tree node can be created using an object which extends the BaseNodeViewHolder class provided by the library. BaseNodeViewHolder requires a holder class which is generally static so that it can be accessed without creating an instance which nests textviews, imageviews and buttons. Once the holder extends the BaseNodeViewHolder, it should override two methods as follows; @Override public View createNodeView(final TreeNode node, ClassContainingNodeData header) { } @Override public void toggle(boolean active) { } createNodeView() which inflate the view and toggle() method which can be used to toggle clicks on the tree node in the UI. The following code snippet shows how to create an object which extends the above mentioned class with the overridden methods. public class ExperimentHeaderHolder extends TreeNode.BaseNodeViewHolder<ExperimentHeaderHolder.ExperimentHeader> { private ImageView arrow; public ExperimentHeaderHolder(Context context) { super(context); } @Override public View createNodeView(final TreeNode node, ExperimentHeader header) { final LayoutInflater inflater = LayoutInflater.from(context); final View view = inflater.inflate(R.layout.header_holder, null, false); TextView title = (TextView) view.findViewById(R.id.title); title.setText(header.title); arrow = (ImageView) view.findViewById(R.id.experiment_arrow); return view; } @Override public void toggle(boolean active) { arrow.setImageResource(active ? arrow_drop_up : arrow_drop_down); } public static class ExperimentHeader { public String title; public ExperimentHeader(String title) { this.title = title; } } } Creating a TreeNode Once the holder is complete, we can move on to creating an actual tree node. TreeNode class requires an object…

Continue ReadingImplementing Tree View in PSLab Android App

Expandable ListView In PSLab Android App

In the PSLab Android App, we show a list of experiments for the user to perform or refer to while performing an experiment, using PSLab hardware device. A long list of experiments need to be subdivided into topics like Electronics, Electrical, School Level, Physics, etc. In turn, each category like Electronics, Electrical, etc can have a sub-list of experiments like: Electronics Diode I-V characteristics Zener I-V characteristics Transistor related experiments Electrical Transients RLC Bode Plots Ohm's Law This list can continue in similar fashion for other categories as well. We had to  display  this experiment list to the users with a good UX, and ExpandableListView seemed the most appropriate option. ExpandableListView is a two-level listView. In the Group view an individual item can be expanded to show it's children. The Items associated with ExpandableListView come from ExpandableListAdapter.                 Implementation of Experiments List Using ExpandableListView First, the ExpandableListView was declared in the xml layout file inside some container like LinearLayout/RelativeLayout. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:layout_width="match_parent"   android:layout_height="match_parent"   android:orientation="vertical">   <ExpandableListView       android:id="@+id/saved_experiments_elv"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:divider="@color/colorPrimaryDark"       android:dividerHeight="2dp" /> </LinearLayout> Then we populated the data onto the ExpandableListView, by making an adapter for ExpandableListView by extending BaseExpandableListAdapter and implementing its methods. We then passed a Context, List<String> and Map<String,List<String>> to the Adapter constructor. Context: for inflating the layout List<String>: contains titles of unexpanded list Map<String,List<String>>: contains sub-list mapped with title string public SavedExperimentAdapter(Context context,                                 List<String> experimentGroupHeader,                                 HashMap<String, List<String>> experimentList) {       this.context = context;       this.experimentHeader = experimentGroupHeader;       this.experimentList = experimentList;   } In getGroupView() method, we inflate, set title and return group view i.e the main list that we see on clicking and the  sub-list is expanded. You can define your own layout in xml and inflate it. For PSLab Android, we used the default one provided by Android android.R.layout.simple_expandable_list_item_2 @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {   String headerTitle = (String) getGroup(groupPosition);   if (convertView == null) {       LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);       convertView = inflater.inflate(android.R.layout.simple_expandable_list_item_2, null);   }   TextView tvExperimentListHeader = (TextView) convertView.findViewById(android.R.id.text1);   tvExperimentListHeader.setTypeface(null, Typeface.BOLD);   tvExperimentListHeader.setText(headerTitle);   TextView tvTemp = (TextView) convertView.findViewById(android.R.id.text2);   tvTemp.setText(experimentDescription.get(groupPosition));   return convertView; } Similarly, in getChildView() method, we inflate, set data and return child view. We wanted simple TextView as sub-list item thus inflated the layout containing only TextView and setText by taking reference of textView from the inflated view. @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {   String experimentName = (String) getChild(groupPosition, childPosition);   if (convertView == null) {       LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);       convertView = inflater.inflate(R.layout.experiment_list_item, null);   }   TextView tvExperimentTitle = (TextView) convertView.findViewById(R.id.exp_list_item);   tvExperimentTitle.setText(experimentName);   return convertView; } The complete code for the Adapter can be seen here. After creating the adapter we proceeded similarly to the normal ListView. Take the reference for ExpandableListView by findViewById() or BindView if you are using ButterKnife and set the adapter as an instance of adapter created above. @BindView(R.id.saved_experiments_elv) ExpandableListView experimentExpandableList; experimentAdapter = new SavedExperimentAdapter(context, headerList, map); experimentExpandableList.setAdapter(experimentAdapter); Roadmap We are planning to divide the experiment sub-list into categories like Electronics Diode Diode I-V Zener…

Continue ReadingExpandable ListView In PSLab Android App