溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

android中怎么自定義樹(shù)形

發(fā)布時(shí)間:2021-06-26 14:48:40 來(lái)源:億速云 閱讀:154 作者:Leah 欄目:云計(jì)算

android中怎么自定義樹(shù)形,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

TreeView.java代碼:

package com.tbx.android.widget;

import java.util.ArrayList;


public class TreeView extends ListView implements OnItemClickListener {
	
    private static String TAG = "TreeView";
    
    List<TreeElement> treeElements = null;// 所有節(jié)點(diǎn)集合
    List<TreeElement> currentElements = null;// 當(dāng)前顯示的節(jié)點(diǎn)集合
    List<TreeElement> tempElements = null;// 用于臨時(shí)存儲(chǔ)
    
    HashMap<String, List<TreeElement>> deleteMap = new HashMap<String, List<TreeElement>>();
    //用于存儲(chǔ)要?jiǎng)h除的子節(jié)點(diǎn),以及間接子節(jié)點(diǎn)。
    TreeViewAdapter adapter = null;// 用于數(shù)據(jù)填充
    LastLevelItemClickListener itemClickCallBack;// 用戶點(diǎn)擊事件回調(diào)
 
    public TreeView(final Context context, AttributeSet attrs) {
       super(context, attrs);
       Log.d(TAG, "create with TreeView(Context context, AttributeSet attrs)");
       treeElements = new ArrayList<TreeElement>();
       currentElements = new ArrayList<TreeElement>();
 
       adapter = new TreeViewAdapter(context, currentElements);
       this.setAdapter(adapter);
       itemClickCallBack = new LastLevelItemClickListener() {
           @Override
           public void onLastLevelItemClick(int position,TreeViewAdapter adapter) {
              Log.d(TAG, "last level element "
                     + currentElements.get(position).getTitle()
                     + " is clicked");
           }
       };
       this.setOnItemClickListener(this);
    }
 
    public void initData(Context context, List<TreeElement> treeElements) {
       this.treeElements = treeElements;
       getFirstLevelElements(context);
       adapter.notifyDataSetChanged();
    }
 
    /**
     * 設(shè)置點(diǎn)擊事件回調(diào)接口
     *
     * @param itemClickCallBack
     */
 
    public void setLastLevelItemClickCallBack(LastLevelItemClickListener itemClickCallBack) {
       this.itemClickCallBack = itemClickCallBack;
    }
 
    /**
     * 初始化樹(shù)形結(jié)構(gòu)列表數(shù)據(jù),把第一層級(jí)的數(shù)據(jù)添加到currentElements中
     */
    public void getFirstLevelElements(Context context) {
       Log.d(TAG, "initCurrentElements");
       int size = treeElements.size();
       Log.d(TAG, "tree elements num is: " + size);
       if (currentElements == null) {
           currentElements = new ArrayList<TreeElement>();
       }
       currentElements.clear();
       for (int i = 0; i < size; i++) {
           if (treeElements.get(i).getLevel() == 1) {
              currentElements.add(treeElements.get(i));
              Log.d(TAG, "find a first level element: " + treeElements.get(i));
 
           }
       }
    }
 
    /**
     * 從所有節(jié)點(diǎn)集合中獲取某父節(jié)點(diǎn)的子節(jié)點(diǎn)集合
     *
     * @param parentId
     * @return
     */
    private List<TreeElement> getChildElementsFromAllById(String parentId) {
       tempElements = new ArrayList<TreeElement>();
       int size = treeElements.size();
 
       for (int i = 0; i < size; i++) {
    	   String temptParentId = treeElements.get(i).getParentId() ;
    	   if(temptParentId != null){
    		   if (temptParentId.equalsIgnoreCase(parentId)) {
    	              tempElements.add(treeElements.get(i));
    	              Log.d(TAG, "find a child element: " + treeElements.get(i));
    	       }
    	   }
       }
       return tempElements;
    }
 
    /**
     * 從當(dāng)前顯示的節(jié)點(diǎn)集合中    , 獲取某父節(jié)點(diǎn)的子節(jié)點(diǎn)集合
     * @param parentId
     * @return
     */
    private List<TreeElement> getChildElementsFromCurrentById(String parentId) {
       Log.d(TAG, "getChildElementsFromCurrentById    parentId: " + parentId);
       if (tempElements == null) {
           tempElements = new ArrayList<TreeElement>();
       } else {
           tempElements.clear();
       }
 
       int size = currentElements.size();
       if(size > 0){
    	   for(TreeElement treeElement : currentElements){
    		   String temp = treeElement.getParentId();
    		   if(temp != null){
                   if (temp.equalsIgnoreCase(parentId)) {
                       tempElements.add(treeElement);
                       Log.d(TAG, "find a child element to delete: " +treeElement);
                    }

        	   }
    	   }
       }
       return tempElements;
    }
 
    /**
     * 刪除某父節(jié)點(diǎn)的所有子節(jié)點(diǎn)集合(包括直接節(jié)點(diǎn)和間接節(jié)點(diǎn))
     * @param parentId
     * @return
     */
    private synchronized boolean delAllChildElementsByParentId(String parentId) {
       Log.e(TAG, "delAllChildElementsByParentId: " + parentId);
       
       List<TreeElement> childElments = getChildElementsFromCurrentById(parentId);
       List<TreeElement> treeElementsToDel = deleteMap.get(parentId);
       if (treeElementsToDel == null) {
           treeElementsToDel = new ArrayList<TreeElement>();
           deleteMap.put(parentId, treeElementsToDel);
       } else {
           treeElementsToDel.clear();
       }
       int size = childElments.size();
       Log.e(TAG, "childElments size : " + size);
       TreeElement childElement = null;
       for (int i = 0; i < size; i++) {
           childElement = childElments.get(i);
           //尋找間接節(jié)點(diǎn)
           if (childElement.hasChild && childElement.fold) {
              treeElementsToDel.add(childElement);
           }
       }
       size = treeElementsToDel.size();
       Log.e(TAG, "treeElementsToDel size : " + size);
 
       if(size > 0){
    	   //刪除間接節(jié)點(diǎn)
    	   List<TreeElement> deleteTreeElement = treeElementsToDel;
    	   for(TreeElement element : deleteTreeElement){
    		   delAllChildElementsByParentId(element.getId());
    	   }
       }
       //刪除直接節(jié)點(diǎn)
       delDirectChildElementsByParentId(parentId);
       return true;
    }
 
    /**
     * 刪除某父節(jié)點(diǎn)的直接子節(jié)點(diǎn)集合
     *
     * @param parentId
     * @return
     */
    private synchronized boolean delDirectChildElementsByParentId(
           String parentId) {
       Log.d(TAG, "delDirectChildElementsByParentId(): " + parentId);
       boolean success = false;
       if (currentElements == null || currentElements.size() == 0) {
           Log.d(TAG, "delChildElementsById() failed,currentElements is null or it's size is 0");
           return success;
       }
       synchronized (currentElements) {
           int size = currentElements.size();
           Log.d(TAG, "begin delete");
           for (int i = size - 1; i >= 0; i--) {
        	  String temp = currentElements.get(i).getParentId(); 
        	  if(temp != null && temp.equalsIgnoreCase(parentId)){
        		  currentElements.get(i).fold = false;// 記得隱藏子節(jié)點(diǎn)時(shí)把展開(kāi)狀態(tài)設(shè)為false
                  currentElements.remove(i);
        	  }
           }
        }
       success = true;
       return success;
    }
 
    /**
     * 根據(jù)id查下標(biāo)
     *
     * @param id
     * @return
     */
    @SuppressWarnings("unused")
	private int getElementIndexById(String id) {
       int num = currentElements.size();
       for (int i = 0; i < num; i++) {
           if (currentElements.get(i).getId().equalsIgnoreCase(id)) {
              return i;
           }
       }
       return -1;
    }
    
    @SuppressWarnings("unused")
	private TreeElement getElementById(String id){
    	 int num = currentElements.size();
    	 if( num > 0){
    		 for (int i = 0; i < num; i++) {
                 if (currentElements.get(i).getId().equalsIgnoreCase(id)) {
                    return currentElements.get(i);
                 }
             }
    	 }
         return null;
    }
 
    @Override
    public void onItemClick(AdapterView<?> arg0, View convertView,
           int position, long id) {
       TreeElement element = currentElements.get(position);
       if (element.isHasChild()) {// 當(dāng)前節(jié)點(diǎn)有子節(jié)點(diǎn)時(shí)只進(jìn)行數(shù)據(jù)顯示或隱藏等操作
           if (!element.isFold()) {// 當(dāng)前父節(jié)點(diǎn)為未展開(kāi)狀態(tài)
              currentElements.addAll(position + 1,this.getChildElementsFromAllById(element.getId()));
           } else if (element.fold) {// 當(dāng)前父節(jié)點(diǎn)為展開(kāi)狀態(tài)
              boolean success = this.delAllChildElementsByParentId(element.getId());
              Log.d(TAG, "delete child state: " + success);
              if (!success) {
                  return;
              }
           }
           element.setFold(!element.isFold());// 設(shè)置反狀態(tài)
           adapter.notifyDataSetChanged();// 刷新數(shù)據(jù)顯示
       } else {// 當(dāng)前節(jié)點(diǎn)有子節(jié)點(diǎn)時(shí)只進(jìn)行用戶自定義操作
           itemClickCallBack.onLastLevelItemClick(position,adapter);
       }
 
    }
 
    /**
     * 自定義內(nèi)部接口,用于用戶點(diǎn)擊最終節(jié)點(diǎn)時(shí)的事件回調(diào)
     */
    public interface LastLevelItemClickListener {
       public void onLastLevelItemClick(int position,TreeViewAdapter adapter);
    }
}

TreeElement.java代碼:

/**
 * 類(lèi)名:TreeElement.java
* 類(lèi)描述:樹(shù)形結(jié)構(gòu)節(jié)點(diǎn)類(lèi)
 * 創(chuàng)建時(shí)間:2012-11-23 16:32
 */
public class TreeElement {
    String id = null;// 當(dāng)前節(jié)點(diǎn)id
    String title = null;// 當(dāng)前節(jié)點(diǎn)文字
    boolean hasParent = false;// 當(dāng)前節(jié)點(diǎn)是否有父節(jié)點(diǎn)
    boolean hasChild = false;// 當(dāng)前節(jié)點(diǎn)是否有子節(jié)點(diǎn)
    boolean childShow = false;// 如果子節(jié)點(diǎn),字節(jié)當(dāng)當(dāng)前是否已顯示
    String parentId = null;// 父節(jié)點(diǎn)id
    int level = -1;// 當(dāng)前界面層級(jí)
    boolean fold = false;// 是否處于展開(kāi)狀態(tài)
...
}

TreeViewAdapter.java

package com.tbx.android.adapter;

import java.util.List;

/**
 * 類(lèi)名:TreeViewAdapter.java
 * 類(lèi)描述:用于填充數(shù)據(jù)的類(lèi)
* 創(chuàng)建時(shí)間:2012-11-23 16:32
*/
public class TreeViewAdapter extends BaseAdapter {
 
    class ViewHolder {
       ImageView icon;
       TextView title;
    }
 
    Context context;
    ViewHolder holder;
    LayoutInflater inflater;
 
    List<TreeElement> elements;
 
    public TreeViewAdapter(Context context, List<TreeElement> elements) {
       this.context = context;
       this.elements = elements;
    }
 
    @Override
    public int getCount() {
       return elements.size();
    }
 
    @Override
    public Object getItem(int position) {
       return elements.get(position);
    }
 
    @Override
    public long getItemId(int position) {
       return position;
    }
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
       /**
        * ---------------------- get holder------------------------
        */
       if (convertView == null) {
           if (inflater == null) {
              inflater = LayoutInflater.from(context);
           }
           holder = new ViewHolder();
           convertView = inflater
                  .inflate(R.layout.tree_view_item, null);
           holder.icon = (ImageView) convertView
                  .findViewById(R.id.tree_view_item_icon);
           holder.title = (TextView) convertView
                  .findViewById(R.id.tree_view_item_title);
           convertView.setTag(holder);
       } else {
           holder = (ViewHolder) convertView.getTag();
       }
       /**
        * ---------------------- set holder--------------------------
        */
       if (elements.get(position).isHasChild()) {// 有子節(jié)點(diǎn),要顯示圖標(biāo)
           if (elements.get(position).isFold()) {
              holder.icon.setImageResource(R.drawable.tree_view_icon_open);
           } else if (!elements.get(position).isFold()) {
              holder.icon.setImageResource(R.drawable.tree_view_icon_close);
           }
           holder.icon.setVisibility(View.VISIBLE);
       } else {// 沒(méi)有子節(jié)點(diǎn),要隱藏圖標(biāo)
           holder.icon.setImageResource(R.drawable.tree_view_icon_close);
           holder.icon.setVisibility(View.INVISIBLE);
       }
       holder.icon.setPadding(25 * (elements.get(position).getLevel()), 0, 0, 0);// 根據(jù)層級(jí)設(shè)置縮進(jìn)
       holder.title.setText(elements.get(position).getTitle());
       holder.title.setTextSize(35 - elements.get(position).getLevel() * 5); // 根據(jù)層級(jí)設(shè)置字體大小
 
       return convertView;
    }
}

MainActivity.java

public class MainActivity extends Activity {

	private TreeView lvAddress; //通訊錄列表
	private List<TreeElement> lvAddressData = new ArrayList<TreeElement>();
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lvAddress = (TreeView) findViewById(R.id.frame_listview_address);
    	
		LastLevelItemClickListener itemClickCallBack = new LastLevelItemClickListener() {
			// 創(chuàng)建節(jié)點(diǎn)點(diǎn)擊事件監(jiān)聽(tīng)
			@Override
			public void onLastLevelItemClick(int position,
					TreeViewAdapter adapter) {
				TreeElement element = (TreeElement) adapter.getItem(position);
				//然后自己處理
			}
		};
		
		//初始化數(shù)據(jù)
		initData();
		lvAddress.initData(this, lvAddressData);// 初始化數(shù)據(jù)
		lvAddress.setLastLevelItemClickCallBack(itemClickCallBack);// 設(shè)置節(jié)點(diǎn)點(diǎn)擊事件監(jiān)聽(tīng)
        
        
    }

    private void initData() {//測(cè)試數(shù)據(jù)
		 TreeElement root = new TreeElement();
		 root.setId("01");
		 root.setLevel(1);
		 root.setTitle("好友");
		 root.setFold(false);
		 root.setHasChild(true);
		 root.setHasParent(false);
		 root.setParentId(null);
		 lvAddressData.add(root);
		 
		 TreeElement twoLevel = new TreeElement();
		 twoLevel.setId("0101");
		 twoLevel.setLevel(2);
		 twoLevel.setTitle("初中同學(xué)");
		 twoLevel.setFold(false);
		 twoLevel.setHasChild(true);
		 twoLevel.setHasParent(true);
		 twoLevel.setParentId("01");
		 lvAddressData.add(twoLevel);
		 
		 
		 TreeElement threeLevel = new TreeElement();
		 threeLevel.setId("010101");
		 threeLevel.setLevel(3);
		 threeLevel.setTitle("發(fā)財(cái)");
		 threeLevel.setFold(false);
		 threeLevel.setHasChild(false);
		 threeLevel.setHasParent(true);
		 threeLevel.setParentId("0101");
		 lvAddressData.add(threeLevel);
	}

	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

tree_view_item.xml布局內(nèi)容

<?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:gravity="center_vertical"
    android:orientation="horizontal" >
 
    <ImageView
        android:id="@+id/tree_view_item_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
 
    <TextView
        android:id="@+id/tree_view_item_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="15dip"
         />
 
</LinearLayout>


關(guān)于android中怎么自定義樹(shù)形問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI