編輯:關於Android編程
ListView實現二級節點想必大家都知道可以用ExpandableListView 就可以輕松實現,但是要實現3級甚至多級菜單怎麼實現呢? 再利用ExpandableListView 就會十分繁瑣,今天我們來探究另一種實現方式來實現。
思路:每次點擊展開子菜單 ,可以理解為 listView的一次重繪(數據更新<增加子節點數據>),而收起子菜單就是移除當前節點下的子數據,這是數據更新。對於界面每一個itemView的實現可以在adapter裡面實現,根據沒個子元素的級別,是否含有子節點,是否已經展開來配置不同的界面顯示效果。首先來看實現的效果:



1:首先看子元素bean
package com.example.androidexpandablelistview;
import java.util.ArrayList;
import java.util.List;
/**
* 元素 可根據需要添加新的屬性
* @author jrh
*
*/
public class TreeElement {
/**
* 各個元素的層級標識
*/
private int parentLevel;
/**
* 節點顯示標題
*/
private String noteName;
/**
* 子節點元素集合
*/
private ArrayList dataList = new ArrayList();
/**
* 是否已擴展
*/
private boolean isExpandAble;
/**
* 是否有子節點元素
*/
private boolean isHasChild;
/**
* 當前節點位置
*/
private int position;
/**
*
* @param parentLevel 各個元素的層級標識
* @param noteName 節點顯示標題
* @param dataList 子節點元素集合
* @param isExpandAble 是否已擴展
* @param isHasChild 是否有子節點元素
* @param position 當前節點位置
*/
public TreeElement(int parentLevel, String noteName,
ArrayList dataList, boolean isExpandAble,
boolean isHasChild, int position) {
super();
this.parentLevel = parentLevel;
this.noteName = noteName;
this.dataList = dataList;
this.isExpandAble = isExpandAble;
this.isHasChild = isHasChild;
this.position = position;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public boolean isHasChild() {
return isHasChild;
}
public void setHasChild(boolean isHasChild) {
this.isHasChild = isHasChild;
}
public int getParentLevel() {
return parentLevel;
}
public void setParentLevel(int parentLevel) {
this.parentLevel = parentLevel;
}
public String getNoteName() {
return noteName;
}
public void setNoteName(String noteName) {
this.noteName = noteName;
}
public ArrayList getDataList() {
return dataList;
}
public void setDataList(ArrayList dataList) {
this.dataList = dataList;
}
public boolean isExpandAble() {
return isExpandAble;
}
public void setExpandAble(boolean isExpandAble) {
this.isExpandAble = isExpandAble;
}
}
package com.example.androidexpandablelistview;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
/**
* 處理點擊 數據更新 通用
* @author jrh
*
*/
public class TreeAdapter extends BaseAdapter {
private List mParentList;
private Context context;
public TreeAdapter(List parentList, Context context) {
super();
this.mParentList = parentList;
this.context = context;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mParentList == null ? 0 : mParentList.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return mParentList == null ? null : mParentList.get(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
// TODO Auto-generated method stub
return null;
}
public void onExpandClick(int position) {
// 父節點沒有子元素直接返回
if (!mParentList.get(position).isHasChild()) {
return;
}
// 父節點已經擴展
if (mParentList.get(position).isExpandAble()) {
mParentList.get(position).setExpandAble(false);
TreeElement element = mParentList.get(position);
// 遍歷已擴展的元素,刪除
ArrayList temp = new ArrayList();
// 從當前點的下一個元素開始隱藏
for (int i = position + 1; i < mParentList.size(); i++) {
if (element.getParentLevel() >= mParentList.get(i)
.getParentLevel()) {
break;
}
temp.add(mParentList.get(i));
}
mParentList.removeAll(temp);
for (int i = position + 1; i < mParentList.size(); i++) {
mParentList.get(i).setPosition(i);
}
notifyDataSetChanged();
} else {
// 父節點為點開
TreeElement objElement = mParentList.get(position);
objElement.setExpandAble(true);
int level = objElement.getParentLevel();
int nextLevel = level + 1;
ArrayList tempList = objElement.getDataList();
//擴充父類集合
for (int i = 0; i < tempList.size(); i++) {
TreeElement element = tempList.get(i);
element.setParentLevel(nextLevel);
element.setExpandAble(false);
mParentList.add(position+1,element);
}
for (int i = position+1; i
3:具體適配adapter
package com.example.androidexpandablelistview;
import java.util.List;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.LayerDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* 具體子adapter 可根據不同的要求自定義
* @author jrh
*
*/
public class DetaiTreeAdapter extends TreeAdapter {
private LayoutInflater inflater;
private List mParentList;
public DetaiTreeAdapter(List parentList, Context context) {
super(parentList, context);
inflater = LayoutInflater.from(context);
mParentList = parentList;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return super.getCount();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return super.getItem(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return super.getItemId(arg0);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
// hodler 需為局部變量
ViewHodler hodler = new ViewHodler();
TreeElement treeElement = mParentList.get(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.itemview, null);
hodler.icon = (ImageView) convertView.findViewById(R.id.ic_img);
hodler.title = (TextView) convertView.findViewById(R.id.title_tv);
hodler.connection = (RelativeLayout) convertView
.findViewById(R.id.layout_treeview_connection);
convertView.setTag(hodler);
} else {
hodler = (ViewHodler) convertView.getTag();
}
// -; +;圖標處理
if (treeElement.isHasChild()) {
if (treeElement.isExpandAble()) {
if (treeElement.getParentLevel() == 0) {
hodler.icon
.setImageResource(R.drawable.knowledgetree_rootexpanded);
} else {
hodler.icon
.setImageResource(R.drawable.knowledgetree_expanded);
}
} else {
if (treeElement.getParentLevel() == 0) {
hodler.icon
.setImageResource(R.drawable.knowledgetree_rootunexpanded);
} else {
hodler.icon
.setImageResource(R.drawable.knowledgetree_unexpanded);
}
}
} else {
hodler.icon.setImageResource(R.drawable.knowledgetree_leaf);
}
// 設置 展開 時,“-”、“+”間的連線
if (treeElement.getParentLevel() == 0) {
if (position + 1 < getCount()
&& mParentList.get(position + 1).getParentLevel() == 0) {
hodler.connection.setBackgroundResource(0);
} else if (position + 1 == getCount()) {
hodler.connection.setBackgroundResource(0);
} else {
hodler.connection
.setBackgroundResource(R.drawable.knowledgetree_halfconnection_root);
}
} else {
if (position + 1 < getCount()
&& mParentList.get(position + 1).getParentLevel() == 0) {
hodler.connection
.setBackgroundResource(R.drawable.knowledgetree_halfconnection_leaf);
} else if (position == getCount() - 1)
hodler.connection
.setBackgroundResource(R.drawable.knowledgetree_halfconnection_leaf);
else
hodler.connection
.setBackgroundResource(R.drawable.knowledgetree_connection);
}
// 標題背景設置
if (treeElement.getParentLevel() == 0) {
hodler.title.setBackgroundColor(Color.BLUE);
hodler.title.setPadding(8, 8, 8, 8);
} else if (treeElement.getParentLevel() == 1) {
hodler.title.setBackgroundColor(Color.RED);
hodler.title.setPadding(38, 8, 8, 8);
} else if (treeElement.getParentLevel() == 2) {
hodler.title.setPadding(78, 8, 8, 8);
hodler.title.setBackgroundColor(Color.GRAY);
}
hodler.title.setTextColor(Color.WHITE);
hodler.title.setText(treeElement.getNoteName());
return convertView;
}
@Override
public void onExpandClick(int position) {
super.onExpandClick(position);
}
class ViewHodler {
ImageView icon;
TextView title;
RelativeLayout connection;
}
}
4:主界面
package com.example.androidexpandablelistview;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
public class MainActivity extends Activity {
private ListView mLv;
private DetaiTreeAdapter adapter;
private ArrayList dataList;
private ArrayList seconddataList;
private ArrayList thirddataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
initData();
initEvent();
}
/**
* 事件處理
*/
private void initEvent() {
mLv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView arg0, View arg1, int arg2,
long arg3) {
adapter.onExpandClick(arg2);
}
});
}
/**
* 數據加載
*/
private void initData() {
dataList = new ArrayList();
seconddataList = new ArrayList();
thirddataList = new ArrayList();
adapter = new DetaiTreeAdapter(dataList, MainActivity.this);
mLv.setAdapter(adapter);
//模擬三級節點數據
for (int i = Data.thridTitle.length-1; i >=0; i--) {
TreeElement element = new TreeElement(2, Data.thridTitle[i], new ArrayList(),
false, false, i);
thirddataList.add(element);
}
//模擬二級節點數據
for (int i = Data.secondTitle.length-1; i >=0; i--) {
TreeElement element = new TreeElement(1, Data.secondTitle[i],
i == 0 ? thirddataList : null, false,
i == 0 ? true : false, i);
seconddataList.add(element);
}
//模擬一級節點數據
for (int i = 0; i < Data.title.length; i++) {
TreeElement element = new TreeElement(0, Data.title[i],
i == 0 ? seconddataList : null, false, i == 0 ? true
: false, i);
dataList.add(element);
}
adapter.notifyDataSetChanged();
}
private void initView() {
mLv = (ListView) findViewById(R.id.lv);
}
}
5:模擬數據
package com.example.androidexpandablelistview;
/**
* 模擬數據
* @author jrh
*
*/
public class Data {
public static String title[] = {常識判斷,言語理解,數量關系,判斷推理,資料分析};
public static String secondTitle[]={政治,經濟,法律,歷史,人文};
public static String thridTitle[] ={時政,馬克思主義哲學,中共黨史,中國特色社會主義體系};
}
6:界面布局
7:itemView
Android中實現可滑動的Tab的3種方式
1. 第一種,使用 TabHost + ViewPager 實現該方法會有一個Bug,當設置tabHost.setCurrentTab()為0時,ViewPager不顯示
Android 使用handler實現線程間發送消息 (主線程 與 子線程之間)、(子線程 與 子線程之間)
關鍵字:Android 使用handler實現線程間發送消息 (主線程 與 子線程之間)、(子線程 與 子線程之間) 相信大家平時都有使用到異步線程往主線程(U
Android開發筆記(一百二十五)自定義視頻播放器
視頻播放方式在Android中播放視頻的方式有兩種:1、使用MediaPlayer結合SurfaceView進行播放。其中通過SurfaceView顯示視頻的畫面,通過M
Android http文件上傳-本地+服務器一條龍分析
本地: 先看下項目結構 MainActivity.java oldProcess) { Message msg = handler.obtainMessage()