Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 自己實現的android樹控件,android TreeView

自己實現的android樹控件,android TreeView

編輯:關於Android編程

1.開發原因   在項目中經常需要一個需要一個樹狀框架,這是非常常見的控件。不過可能是谷歌考慮到android是手機系統,界面寬度有限,   所以只提供了只有二級的ExpandableListView。雖然這個控件可以滿足很多需求,但是無數級的樹在某些情況下還是需要的,所以我花了一天時間   (大部分時間都在調試動畫去了,不過現在動畫還有點問題,具體原因不明。。如果某位大神能找到原因灰常感謝)。     2.原理   網上很多都是擴展listview實現的,不過listview貌似不支持復雜控件的事件?而且做動畫也不方便,所有我決定擴展linearlayout,在裡面增加子節點的方式實現。     3.代碼 TreeView.java:     復制代碼   1 package net.memornote.android.ui.view;   2    3 import java.util.ArrayList;   4 import java.util.List;   5 import java.util.Timer;   6 import java.util.TimerTask;   7    8 import android.content.Context;   9 import android.graphics.Rect;  10 import android.util.AttributeSet;  11 import android.view.View;  12 import android.view.animation.Animation;  13 import android.view.animation.Animation.AnimationListener;  14 import android.view.animation.ScaleAnimation;  15 import android.view.animation.TranslateAnimation;  16 import android.widget.LinearLayout;  17   18 public class TreeView extends LinearLayout{  19       20 //    private List<TreeItem> items;  21     private List<TreeItem> sortedItems;  22     private int animTime;  23   24     public TreeView(Context context, AttributeSet attrs) {  25         super(context, attrs);  26         setOrientation(LinearLayout.VERTICAL);  27     }  28     /**  29      * initialize data,you must make sure that each item has parent except the top ones.  30      * @param items the data to show   31      * @param index the index of the tree to insert to  32      * @param viewHeight each view's height  33      * @param animTime if you want expand animation,   34      * you can set the time(ms) of animation,otherwise you can set 0.  35      *   36      */  37     public void initData(List<TreeItem> items,int index){  38           39         if(items==null||items.size()==0){  40             return ;  41         }  42   43         sortItemList(items);  44           45         int size=sortedItems.size();  46           47         initAddIndex=index<0?-Integer.MAX_VALUE:index;  48           49         for (int i=0;i<size;i++) {  50             TreeItem item=sortedItems.get(i);  51             recuseShow(item);  52         }  53           54     }  55       56     private boolean isAnim=false;  57     /**  58      * 這個方法還有很 嚴重的bug,無法使用。。  59      * 設置為0則關閉動畫  60      * @param animTime  61      */  62     public void enabledAnim(int animTime) {  63         if(animTime<0){  64             isAnim=false;  65             return ;  66         }  67         this.animTime=animTime;  68         isAnim=true;  69     }  70       71     private int initAddIndex;   72       73     private void recuseShow(TreeItem item){  74         View view=item.getView();  75         addView(view,initAddIndex);  76         if(item.getParent()!=null){  77             view.setVisibility(View.GONE);  78             item.isShow=false;  79         }else {  80             view.setVisibility(View.VISIBLE);  81             item.isShow=true;  82         }  83         initAddIndex++;  84         List<TreeItem> childrens=item.getChildrens();  85         if(childrens.size()>0){  86             for (TreeItem it : childrens) {  87                 recuseShow(it);  88             }  89         }  90     }  91       92     @Override  93     public void onWindowFocusChanged(boolean hasWindowFocus) {  94         super.onWindowFocusChanged(hasWindowFocus);  95         if(hasWindowFocus){  96               97         }  98     }  99      100     private void sortItemList(List<TreeItem> items) { 101         //把items按照層級關系存放,sortedItems只存放頂層的item 102         sortedItems=new ArrayList<TreeItem>(5); 103         for (TreeItem item : items) { 104             if(item.getParent()==null){ 105                 sortedItems.add(item); 106             }else { 107                 item.getParent().getChildrens().add(item); 108             } 109         } 110          111     } 112      113      114     private int viewIndex=0; 115     private int animHeight=0; 116     private void addChild(TreeItem item,boolean isRecurse){ 117         if(item.getChildrens().size()>0){ 118             List<TreeItem> list=item.getChildrens(); 119             for (TreeItem it :    list) { 120                 View view=it.getView(); 121                 if(it.isShow){ 122                     continue; 123                 } 124                 viewIndex++; 125                 view.setVisibility(View.VISIBLE); 126                 it.isShow=true; 127                 if(isAnim){ 128                     animHeight-=it.getViewHeight(); 129                 } 130                 it.nextIsExpand=true; 131                 if(isRecurse){ 132                     addChild(it,true); 133                 } 134             } 135         } 136     } 137     private int removeCount=0; 138     private synchronized void removeChild(TreeItem item,boolean isRecurse){ 139         if(item.getChildrens().size()>0){ 140             List<TreeItem> list=item.getChildrens(); 141             for (TreeItem it :    list) { 142                 View view=it.getView(); 143                 if(!it.isShow){ 144                     continue; 145                 } 146 //                removeViewAt(viewIndex); 147                  148                 TranslateAnimation ta=new TranslateAnimation(0, 0, 0, 0); 149                 ta.setFillAfter(true); 150                 ta.setDuration(1000); 151                 view.startAnimation(ta); 152 //                viewIndex++; 153                 removeCount++; 154                 it.isShow=false; 155                 view.setVisibility(View.GONE); 156                 if(isAnim){ 157                     animHeight+=it.getViewHeight(); 158                 } 159                 if(isRecurse){ 160                     removeChild(it,true); 161                 } 162             } 163         } 164     } 165  166     private void animAdd(){ 167         TranslateAnimation ta=new TranslateAnimation( 168                 Animation.ABSOLUTE, 0,  169                 Animation.ABSOLUTE, 0,  170                 Animation.ABSOLUTE, animHeight,  171                 Animation.ABSOLUTE, 0); 172         ta.setFillBefore(true); 173 //        ta.setFillAfter(false); 174         ta.setDuration(animTime); 175          176         for (int i = viewIndex+1; i < getChildCount(); i++) { 177             View view=getChildAt(i); 178             view.startAnimation(ta); 179         } 180         animHeight=0; 181     } 182     private void animRemove(){ 183         TranslateAnimation ta=new TranslateAnimation( 184                 Animation.ABSOLUTE, 0,  185                 Animation.ABSOLUTE, 0,  186                 Animation.ABSOLUTE, animHeight,  187                 Animation.ABSOLUTE, 0); 188         ta.setFillAfter(false); 189         ta.setFillBefore(true); 190         ta.setDuration(animTime); 191          192         int startAnimIndex; 193         startAnimIndex=viewIndex+1; 194         for (int i = startAnimIndex; i < getChildCount(); i++) { 195             View view=getChildAt(i); 196              197             view.startAnimation(ta); 198         } 199         animHeight=0; 200     } 201     public void expand(TreeItem item){ 202         viewIndex=indexOfChild(item.getView()); 203         addChild(item,false); 204         if(isAnim){ 205             animAdd(); 206         } 207     } 208      209  210     public void expandAllChildren(TreeItem item) { 211         viewIndex=indexOfChild(item.getView()); 212         addChild(item,true); 213         if(isAnim){ 214             animAdd(); 215         } 216     } 217      218     public void expandAll(){ 219         if(sortedItems==null){ 220             return ; 221         } 222         for (TreeItem item : sortedItems) { 223             expandAllChildren(item); 224         } 225     } 226      227     public void contractAllChildren(TreeItem item) { 228         viewIndex=indexOfChild(item.getView())+1; 229         removeChild(item,true); 230         if(isAnim){ 231             animRemove(); 232         } 233     } 234      235     public void contractAll(){ 236         if(sortedItems==null){ 237             return ; 238         } 239         for (TreeItem item : sortedItems) { 240             contractAllChildren(item); 241         } 242     } 243      244     public void bind(TreeItem item) { 245         if(item.nextIsExpand){ 246             expand(item); 247         }else { 248             contractAllChildren(item); 249         } 250         item.nextIsExpand=!item.nextIsExpand; 251     } 252      253      254 } 復制代碼 TreeItem.java     復制代碼  1 package net.memornote.android.ui.view;  2   3 import java.util.ArrayList;  4 import java.util.List;  5   6 import android.view.View;  7   8 public class TreeItem {  9     private View view; 10     private TreeItem parent; 11     private List<TreeItem> childrens=new ArrayList<TreeItem>(0); 12     public boolean nextIsExpand=true; 13     public boolean isShow=false; 14     private int viewHeight;   15      16      17     public TreeItem(){} 18     public TreeItem(int id,View view, TreeItem parent) { 19         super(); 20         this.view = view; 21         this.parent = parent; 22     } 23  24     public View getView() { 25         if(view!=null){ 26             view.setPadding(getLevel()*20,0,0,0); 27         } 28         return view; 29     } 30  31     public void setView(View view) { 32         this.view = view; 33     } 34  35     public TreeItem getParent() { 36         return parent; 37     } 38  39     public void setParent(TreeItem parent) { 40         this.parent = parent; 41     } 42  43     /** 44      * 動態獲取該節點的級數 45      * @return 46      */ 47     public int getLevel() { 48         int level=0; 49         TreeItem localParent=parent; 50          51         while (localParent!=null) { 52             level++; 53             localParent=localParent.getParent(); 54         } 55          56         return level; 57     } 58     public List<TreeItem> getChildrens() { 59         return childrens; 60     } 61     public int getViewHeight() { 62         if(view==null||view.getHeight()==0){ 63             return viewHeight; 64         } 65         return view.getHeight(); 66     } 67     public void setViewHeight(int viewHeight) { 68         this.viewHeight = viewHeight; 69     } 70      71  72 } 復制代碼 測試代碼:     復制代碼  1 package net.memornote.android.ui;  2   3 import net.memornote.android.R;  4 import net.memornote.android.ui.fragment.MainFragment;  5 import net.memornote.android.ui.fragment.MenuFragment;  6   7 import com.actionbarsherlock.view.Menu;  8 import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;  9 import com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity; 10  11 import android.os.Bundle; 12 import android.view.KeyEvent; 13  14 public class MainActivity extends SlidingFragmentActivity { 15  16      17     @Override 18     public void onCreate(Bundle savedInstanceState) { 19         super.onCreate(savedInstanceState); 20          21         setContentView(R.layout.slid_content_frame); 22  23                 tv_notebook=(TreeView)   findViewById(R.id.tv_notebook); 24          25         List<TreeItem> items=new ArrayList<TreeItem>(); 26          27         initData(items); 28         tv_notebook.initData(items, 0); 29         tv_notebook.enabledAnim(500); 30          31     } 32     //初始化一些測試數據 33     public void initData(List<TreeItem> items) { 34         for (int i=0;i<10;i++) { 35 //            TextView tv=new TextView(getActivity()); 36             Button button=new Button(getActivity()); 37             button.setText("item"+i); 38             final TreeItem item=new TreeItem(0, button, null); 39              40             button.setOnClickListener(new OnClickListener() { 41                 @Override 42                 public void onClick(View v) { 43                     tv_notebook.bind(item); 44                 } 45             }); 46              47             items.add(item); 48              49             if(i%2==0){ 50                 Button bt1=new Button(getActivity()); 51                 bt1.setText("item"+i); 52                 bt1.setClickable(true); 53                 final TreeItem item_1=new TreeItem(0, bt1, null); 54                  55                 bt1.setOnClickListener(new OnClickListener() { 56                     @Override 57                     public void onClick(View v) { 58  59                         tv_notebook.bind(item_1); 60                     } 61                 }); 62                 item_1.setParent(item); 63                 items.add(item_1); 64                  65                 if(i%4==0){ 66                     Button bt_2=new Button(getActivity()); 67                     bt_2.setText("item"+i); 68                     bt_2.setClickable(true); 69                     final TreeItem item_2=new TreeItem(0, bt_2, null); 70                      71                     bt_2.setOnClickListener(new OnClickListener() { 72                         @Override 73                         public void onClick(View v) { 74                             tv_notebook.bind(item_2); 75                         } 76                     }); 77                     item_2.setParent(item_1); 78                     items.add(item_2); 79                 } 80                  81             } 82              83              84         } 85     } 86  87     @Override 88     public boolean onCreateOptionsMenu(Menu menu) { 89         return true; 90     } 91  92 } 93          復制代碼
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved