編輯:關於android開發
一、知識點
1、ExpandableListView常用XML屬性
2.ExpandableListView繼承BaseExpandableListAdapter後重寫的各個函數詳解
3.ExpandableListView自定義下拉圖標
二、解析
2.1、ExpandableListView常用XML屬性
2.1.1 設置點擊item項後該item項的背景色
//當你選中某一個item項時,該item項的背景會變色,下面的值是將該背景色設置為透明 android:listSelector="#00000000"
2.1.2 設置item項的高度
//這個是用在item的布局文件裡 android:minHeight="50dp"
2.1.3 拖動時背景圖片問題
//在拖動的時候背景圖片消失變成黑色背景,等到拖動完畢我們自己的背景圖片才顯示出來 android:scrollingCache=”false” 或 android:cacheColorHint=”#00000000″
2.1.4 分割線高度
android:dividerHeight="1dp"
2.2ExpandableListView繼承BaseExpandableListAdapter後重寫的各個函數詳解
下面的代碼幾乎每條都給了注釋,就不再贅述了。
2.2.1 child.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal" >
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textSize="18dp"
android:text="this"
/>
</LinearLayout>
2.2.2 group.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="50dp"
android:orientation="horizontal" >
<ImageView
android:layout_marginLeft="10dp"
android:layout_gravity="center_vertical"
android:id="@+id/arrow"
android:layout_width="25dp"
android:layout_height="25dp"
/>
<TextView
android:layout_marginLeft="10dp"
android:id="@+id/logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
2.2.3 colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="gray">#BEBEBE</color>
<color name="SeaGreen1">#54FF9F</color>
</resources>
2.2.4 activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ExpandableListView
android:id="@+id/expandlist"
android:divider="@color/gray"
android:childDivider="@color/SeaGreen1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:groupIndicator="@null"
android:listSelector="#00000000"
android:dividerHeight="1dp"
>
</ExpandableListView>
</LinearLayout>
2.2.5 MyExpandableListAdapter.java
package com.yds.example;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MyExpandableListAdapter extends BaseExpandableListAdapter {
//上下文
Context context;
//聲明一個布局管理器對象
LayoutInflater inflater;
//聲明一個組集合
List<Map<String, Object>>group;
//聲明一個子元素集合
List<List<Map<String, Object>>>child;
//聲明一個map對象
Map<String, Object>map;
/**
* 自定義適配器的構造函數
* @param context 上下文
* @param group 組集合
* @param child 子元素集合
*/
public MyExpandableListAdapter(Context context,List<Map<String, Object>>group,List<List<Map<String, Object>>>child){
//初始化上下文
this.context = context;
//初始化布局管理器對象
inflater = LayoutInflater.from(context);
//初始化組集合
this.group = group;
//初始化子元素集合
this.child = child;
}
/**
* ExpandableListAdapter裡面的所有條目
* 都可用嗎?如果是yes,就意味著所有條目可以選擇和點擊了。
* 返回值:返回True表示所有條目均可用。
*/
@Override
public boolean areAllItemsEnabled() {
// TODO Auto-generated method stub
return true;
}
/**
* 獲取指定組中的指定子元素數據。
*/
@Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
/*child.get(groupPosition)是得到groupPosition處的list對象,然後
* child.get(groupPosition).get(childPosition)得到child的map對象,然後
* child.get(groupPosition).get(childPosition).get("Child")是得到key值
* 為Child的值
* */
return child.get(groupPosition).get(childPosition).get("Child");
}
/**
* 獲取指定組中的指定子元素ID,這個ID在組裡一定是唯一的。聯合ID(getCombinedChildId(long, long))在所有條目(所有組和所有元素)中也是唯一的。
*/
@Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
/******子元素的位置********/
return childPosition;
}
/**獲取一個視圖對象,顯示指定組中的指定子元素數據。
* @param groupPosition 組位置(該組內部含有子元素)
* @param childPosition 子元素位置(決定返回哪個視圖)
* @param isLastChild 子元素是否處於組中的最後一個
* @param convertView 重用已經有的視圖對象,它是RecycleBin緩存機制調用getScrapView方法獲取廢棄已緩存的view.
* @param parent 返回的視圖(View)對象始終依附於的視圖組。通俗的說是它的父視圖。
*/
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolderChild viewHolderChild;
/*當convertView為空,也就是沒有廢棄已緩存 view時,將執行下面方法,調用layoutinflate的
* inflate()方法來加載一個view。
* 如有不懂,請點擊:http://blog.csdn.net/libmill/article/details/49644743
*/
if(convertView==null){
//重新加載布局
convertView = inflater.inflate(R.layout.child, null);
//初始化控件管理器(自己命名的)
viewHolderChild = new ViewHolderChild();
//綁定控件id
viewHolderChild.tv = (TextView) convertView.findViewById(R.id.tv);
/*convertView的setTag將viewHolderChild設置到Tag中,以便系統第二次繪制
ExpandableListView時從Tag中取出
*/
convertView.setTag(viewHolderChild);
}else{
//當convertView不為空時,從Tag中取出viewHolderChild
viewHolderChild = (ViewHolderChild) convertView.getTag();
}
//給子元素的TextView設置值
viewHolderChild.tv.setText(getChild(groupPosition, childPosition).toString());
//返回視圖對象,這裡是childPostion處的視圖
return convertView;
}
/**
* 獲取指定組中子元素的個數
*/
@Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return child.get(groupPosition).size();
}
/**
* 從列表所有項(組或子項)中獲得一個唯一的子ID號。可折疊列表要求每個元素(組或子項)在所有的子元素和組中
* 有一個唯一的ID。本方法負責根據所給的子ID號和組ID號返回唯一的ID。此外,若hasStableIds()
* 是true,那麼必須要返回穩定的ID。
* @param groupId 包含該子元素的組ID
* @param childId 子元素的ID
* @return:列表所有項(組或子項)中唯一的(和可能穩定)的子元素ID號。(譯者注:ID理論上是穩定的,
* 不會發生沖突的情況。也就是說,這個列表會有組、子元素,它們的ID都是唯一的。)
*/
@Override
public long getCombinedChildId(long groupId , long childId ) {
// TODO Auto-generated method stub
return 0;
}
/**
* 獲取組ID
* @param groupId 組ID
* @return :組ID
*/
@Override
public long getCombinedGroupId(long groupId) {
// TODO Auto-generated method stub
return 0;
}
/**
* 得到指定組的組數據
* @param groupPosition:指定的組的位置
* @return 返回指定組的組數據
*/
@Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
/**group.get(groupPosition)獲取map對象
* group.get(groupPosition).get("Group")獲取key值為Group的數據
* **/
return group.get(groupPosition).get("Group");
}
/**
* 獲取組長
*/
@Override
public int getGroupCount() {
// TODO Auto-generated method stub
return group.size();
}
/**
* 獲取指定組的Id
*/
@Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
/**
* 獲取指定組的視圖對象
* @param groupPosition:組位置(決定返回哪個視圖)
* @param isExpanded:改組是展開狀態還是伸縮狀態
* @param convertView:重用已有的視圖對象
* @return 返回指定組的視圖對象
*/
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolderGroup viewHolder;
//判斷convertView是否為空,convertView是RecycleBean調用getScrapView函數得到廢棄已緩存的view
if(convertView==null){
//初始化控件管理器對象
viewHolder = new ViewHolderGroup();
//重新加載布局
convertView = inflater.inflate(R.layout.group, null);
//給組元素綁定ID
viewHolder.logo_tv = (TextView) convertView.findViewById(R.id.logo);
//給組元素箭頭綁定ID
viewHolder.arrow = (ImageView) convertView.findViewById(R.id.arrow);
//convertView將viewHolder設置到Tag中,以便再次繪制ExpandableListView時從Tag中取出viewHolder;
convertView.setTag(viewHolder);
}else {//如果convertView不為空,即getScrapView得到廢棄已緩存的view
//從Tag中取出之前存入的viewHolder
viewHolder = (ViewHolderGroup) convertView.getTag();
}
//設置組值
viewHolder.logo_tv.setText(getGroup(groupPosition).toString());
//如果組是展開狀態
if (isExpanded) {
//箭頭向下
viewHolder.arrow.setImageResource(R.drawable.arrow_down);
}else{//如果組是伸縮狀態
//箭頭向右
viewHolder.arrow.setImageResource(R.drawable.arrow);
}
//返回得到的指定組的視圖對象
return convertView;
}
/**
* 組和子元素是否持有穩定的ID,也就是底層數據的改變不會影響到它們。
* @return 返回一個Boolean類型的值,如果為TRUE,意味著相同的ID永遠引用相同的對象
*/
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
/**
* 是否選中指定位置上的子元素。
*/
@Override
public boolean isChildSelectable(int arg0, int arg1) {
// TODO Auto-generated method stub
return true;
}
/**
* 如果當前適配器不包含任何數據則返回True。經常用來決定一個空視圖是否應該被顯示。
* 一個典型的實現將返回表達式getCount() == 0的結果,但是由於getCount()包含了頭部和尾部,適配器可能需要不同的行為。
*/
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
/**
* 當組收縮狀態的時候此方法被調用。
*/
@Override
public void onGroupCollapsed(int groupPosition) {
// TODO Auto-generated method stub
}
/**
* 當組展開狀態的時候此方法被調用。
*/
@Override
public void onGroupExpanded(int groupPosition) {
// TODO Auto-generated method stub
}
/**
* 注冊一個觀察者(observer),當此適配器數據修改時即調用此觀察者。
* @param observer:當數據修改時通知調用的對象
*/
@Override
public void registerDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
/**
* 取消先前通過registerDataSetObserver(DataSetObserver)方式注冊進該適配器中的觀察者對象。
* @param observer 取消這個觀察者的注冊
*/
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
/**
* 組控件管理器
* @author Administrator
*
*/
class ViewHolderGroup{
TextView logo_tv;
ImageView arrow;
}
/**
* 子控件管理器
* @author Administrator
*
*/
class ViewHolderChild{
TextView tv;
}
}
2.2.6 MainActivity.java
package com.yds.example;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ExpandableListView;
public class MainActivity extends Activity {
//聲明一個可伸展的列表視圖對象
private ExpandableListView expandlist;
//聲明並初始化一個組集合對象,該集合時一個一維數組
private List<Map<String, Object>>groupList = new ArrayList<Map<String,Object>>();
//聲明一個子元素集合對象,該集合是一個數組鏈表
private List<List<Map<String, Object>>>childList = new ArrayList<List<Map<String,Object>>>();
//聲明一個子元素集合對象
private List<Map<String, Object>>child;
//聲明一個map對象
private Map<String, Object>map;
//組元素值
private String[] armTypes = new String[]{
"WORD", "EXCEL", "EMAIL", "PPT"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//加載布局
setContentView(R.layout.activity_main);
//給組賦值
for (int i = 0; i < armTypes.length; i++) {
//每次都要初始化map對象
map = new HashMap<String, Object>();
//將組值放入key為Group的map中
map.put("Group", armTypes[i]);
//將map添加到組集合中
groupList.add(map);
}
//給每組的子元素賦值
for (int j = 0; j < 4; j++) {
//每次初始化子集合對象。該對象是一個一維數組
child = new ArrayList<Map<String,Object>>();
//每個組下面有25個子元素
for (int i = 0; i < 25; i++) {
//初始化map對象
map = new HashMap<String, Object>();
//將子元素的值放入key值為Child的map中
map.put("Child", "this is "+i+" example");
//將map添加到一維數組中
child.add(map);
}
//將一維數組添加到集合中
childList.add(child);
}
//可伸展的列表視圖綁定ID
expandlist = (ExpandableListView) findViewById(R.id.expandlist);
//聲明並初始化一個adapter
MyExpandableListAdapter adapter = new MyExpandableListAdapter(MainActivity.this,groupList,childList);
//可伸展的列表視圖加載adapter
expandlist.setAdapter(adapter);
}
}
三、結果截圖:

第三方開源框架的下拉刷新列表(QQ比較常用的)。,開源框架
第三方開源框架的下拉刷新列表(QQ比較常用的)。,開源框架PullToRefreshListView是第三方開源框架下拉刷新列表,比較流行的QQ 微信等上面都在用。 下載
(轉)[原] Android 自定義View 密碼框 例子,androidview
(轉)[原] Android 自定義View 密碼框 例子,androidview遵從准則 暴露您view中所有影響可見外觀的屬性或者行為。 通過XML添加和設置樣式
使用Vitamio打造自己的Android萬能播放器—— 手勢控制亮度、音量、縮放
使用Vitamio打造自己的Android萬能播放器—— 手勢控制亮度、音量、縮放 使用Vitamio打造自己的Android萬能播放器(1)——
Android中Service的一個Demo例子
Android中Service的一個Demo例子 Android中Service的一個Demo例子 Service組件是Android系統重要的一部分,網上看了代碼,很簡