Suggestions for building a treeview control in Android
I built a treeview
of my own which supports n levels. It's easy to use in touch screens, especially on devices with larger screen.
I Used a class which extends ListviewAdapter
and created my own listitem
. the items know on which level they are and they inherit the expandstate
of their parents (by remembering their own state). This Tree is quite fast up to thousand items.
Edit: added the code, but the way I wrote in the comment, It won't be very helpful, because it's very close to my own needs.
package de.supinfo.FISDroid;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.PaintDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Bitmap mIcon1;
private int active_view;
private int last_path;
public String[][] values = new String[0][];
public EfficientAdapter(Context context, String[][] str_arr_values, int int_active_view) {
// Cache the LayoutInflate to avoid asking for a new one each time.
mInflater = LayoutInflater.from(context);
values = str_arr_values;
active_view = int_active_view;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
int padding = 0;
// int selfstate = Integer.parseInt(values[position][4].trim());
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.xml.list_item_icon_text, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text_view);
holder.icon = (ImageView) convertView.findViewById(R.id.img_view);
holder.expanded = (ImageView) convertView.findViewById(R.id.ImageView01);
holder.llout = (LinearLayout) convertView.findViewById(R.id.list_item_icon_text);
holder.docs = (TextView) convertView.findViewById(R.id.doc_count);
holder.prun = (ImageView) convertView.findViewById(R.id.prun);
holder.coord = (ImageView) convertView.findViewById(R.id.coord);
holder.button = (Button) convertView.findViewById(R.id.button);
holder.button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
main.tabHost.setCurrentTab(2);
}
});
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Bind the data efficiently with the holder.
String text = values[position][0];
String docs = values[position][11];
if (!docs.equals("0")) {
// TODO
// Anzeige das Dokumente vorhanden sind, eventuell Anzahl
holder.docs.setText(docs);
holder.docs.setVisibility(View.VISIBLE);
} else {
holder.docs.setVisibility(View.INVISIBLE);
}
holder.coord.setVisibility(values[position][12].equals("") || values[position][12].equals("0") || values[position][12].equals("0.0") ? View.INVISIBLE : View.VISIBLE);
holder.prun.setVisibility(values[position][14].equals("") ? View.INVISIBLE : View.VISIBLE);
holder.text.setText(text);
holder.text.setTextSize(GlobalVars.Style.TextSize);
if (position == active_view) {
holder.text.setTextColor(R.color.headline_font);
PaintDrawable pd = new PaintDrawable(Color.RED);
holder.llout.setBackgroundDrawable(pd);
holder.text.setSingleLine(false);
holder.button.setVisibility(values[position][1].equals("-1") ? View.GONE : View.VISIBLE);
} else {
holder.text.setTextColor(R.color.headline_font);
PaintDrawable pd = new PaintDrawable(Color.TRANSPARENT);
holder.llout.setBackgroundDrawable(pd);
holder.text.setSingleLine(true);
holder.button.setVisibility(View.GONE);
}
int i = Integer.parseInt(values[position][5].trim());
mIcon1 = GlobalHelper.GetIcon(i);
holder.icon.setImageBitmap(mIcon1);
if (values[position][8].equals("-1")) {
holder.expanded.setVisibility(View.VISIBLE);
holder.expanded.setImageResource(android.R.drawable.ic_input_add);
} else if (values[position][8].equals("0")) {
holder.expanded.setVisibility(View.INVISIBLE);
} else if (values[position][8].equals("1")) {
holder.expanded.setVisibility(View.VISIBLE);
if (values[position][9].equals("1")) {
holder.expanded.setImageResource(android.R.drawable.ic_menu_revert);
} else {
holder.expanded.setImageResource(android.R.drawable.ic_input_add);
}
}
padding = Integer.parseInt(values[position][7].trim()) * 24;
convertView.setPadding(padding, 5, 5, 5);
return convertView;
}
static class ViewHolder {
LinearLayout llout;
TextView text;
ImageView icon;
ImageView expanded;
ImageView coord;
ImageView prun;
TextView docs;
Button button;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return values.length;
}
public String[] getValues(int position) {
return values[position];
}
public String getValue(int position) {
return values[position][0];
}
public String getDatid(int position) {
return values[position][1];
}
public String getPath(int position) {
return values[position][2];
}
public String getParent(int position) {
return values[position][3];
}
public void set_active_view() {
active_view = GlobalVars.cn.index;
}
public int get_active_view() {
return active_view;
}
public void set_last_path(int position) {
last_path = position;
}
public int get_last_path() {
return last_path;
}
}
Edit: added the xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/list_item_icon_text"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="@color/tree_normal_back"
android:padding="1dip"
android:orientation="horizontal"
android:layout_width="fill_parent">
<LinearLayout
android:id="@+id/plusminus"
android:layout_height="48dip"
android:layout_width="24dip"
android:gravity="right|center_vertical">
<ImageView
android:id="@+id/ImageView01"
android:layout_height="24dip"
android:layout_width="24dip"/>
</LinearLayout>
<LinearLayout
android:id="@+id/LinearLayout01"
android:layout_height="48dip"
android:layout_width="48dip"
android:orientation="horizontal"
android:paddingLeft="4dip">
<LinearLayout
android:id="@+id/LinearLayout02"
android:layout_height="48dip" android:orientation="vertical" android:layout_width="16dip">
<TextView
android:text="0"
android:id="@+id/doc_count"
android:textColorHighlight="@color/headline_font"
android:layout_gravity="center_vertical"
android:textColor="@color/black"
android:textSize="12dip"
android:layout_margin="0dip"
android:padding="0dip"
android:paddingTop="0dip"
android:gravity="center_vertical|center_horizontal"
android:background="@drawable/ico_24_paperclip"
android:textStyle="normal" android:layout_height="16dip" android:layout_width="16dip">
</TextView>
<ImageView
android:id="@+id/prun"
android:layout_gravity="center_vertical"
android:layout_height="16dip"
android:layout_width="16dip" android:background="@drawable/ico_24_prun"/>
<ImageView
android:id="@+id/coord"
android:layout_gravity="center_vertical"
android:layout_height="16dip"
android:layout_width="16dip" android:background="@drawable/ico_24_coord"/>
</LinearLayout>
<ImageView
android:id="@+id/img_view"
android:layout_gravity="center_vertical"
android:layout_height="24dip"
android:layout_width="24dip" />
</LinearLayout>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/tabs_edit"
android:focusable="false"
android:visibility="gone">
</Button>
<TextView
android:layout_gravity="center_vertical"
android:padding="2dip"
android:marqueeRepeatLimit="2"
android:layout_width="wrap_content"
android:textSize="22dip"
android:textColor="@color/tree_normal_font"
android:id="@+id/text_view"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
Here is a solution that our company open-sourced as a library (so very easy to re-use):
http://code.google.com/p/tree-view-list-android/
The ExpandableListView is probably the closest existing thing. Keep in mind though that it might be hard for a user to fat finger a tree view.
You can use this library: https://github.com/bmelnychuk/AndroidTreeView to get your required tree-view. It's a N-level tree where you can control every single node in tree.
Usage
1) install: compile 'com.github.bmelnychuk:atv:1.2.+'
2) build tree-view:
TreeNode root = TreeNode.root();
TreeNode parent = new TreeNode("node-name");
TreeNode child0 = new TreeNode("child-node-name-1");
TreeNode child1 = new TreeNode("child_node-name-2");
parent.addChildren(child0, child1);
root.addChild(parent);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With